SWT Step 4. Layout basics

Objective

Implement the basics of the layout management. The testcase example shoud be able to create a top shell containing a simple button.

Task notes

Default Shell size and position

In SWT, it's assumed that the o.e.swt.widgets.Shell is created with the default size and position assigned by the system.

Since OS/2 handles the FS_SHELLPOSITION flag in a very strange manner (the size/position of the frame after creation remains zero until the frame is shown for the first time, and there's no way neither to get the size/position the system is going to assign nor to change them before the frame is shown) the workaround is made using WinQueryTaskSizePos() (it seems to return the same values the system uses when FS_SHELLPOSITION is specified). This means, that the Shell.getBounds() method will return system assigned values (but not zero as it would be in the case of FS_SHELLPOSITION) after Shell creation and before opening (showing) it and it's also possible to change them -- the same behavior is shown in Windows.

Notification messages

In OS/2 control notification messages (WM_CONTROL, WM_COMMAND) do not necessarily contain the control window handle in their parameters, only the identity is guaranteed to present in most cases. Therefore, in order to send the message back to the widget (this is an SWT logic and it is quite handy) the only way to determine its handle, which we need to obtain a reference to the widget, is to use its window ID. This, in turn, requires an algorithm to generate IDs during window creation, that are unique within the owner window context. The window handle could be such unique identifier, but the problem is that the window ID is a 16-bit value. However, at the present, we still use it for that purpose taking its low 16 bits, which is based on the assumption that handles in OS/2 always have a form of 0x8000nnnn. But this assumtion is possibly erroneous, so in the future this algorithm should be replaced with another one.

Widget height

As mentioned in task notes of the SWT002 step about screen coordinates, we need an easy way to obtain the height of a widget as well as the height of its parent to do necessary calculations related to the coordinate space flipping. The package method Control.getHeight() can still be used to get the height of the widget itself (respecting the situation when the widget is the Decorations instance and it is minimized). The height of the widget's parent can be obtained by the Control.getParentHeight() call (which, for the Shell class, returns the value of the Shell.display.getHeight() method, rather then parent.getHeight(), if the parent is null). The situation for non-Shell windows when the parent is null is inapplicable, so the exception is thrown in this case. The Control.getBounds(SWP) package method returns the height of the parent just as it returned by the getParentHeight() method.

Step checklist

Operation Status Remarks
Make the size and position methods of widgets to work correcty (add OS.SWP structre, OS.WinQueryTaskSizePos(), WinQueryWindowPos()); implement Display.getBounds() Done [dmik] Size and position relative methods are completely rewritten: now they use the package helper method getBounds(SWP) which uses WinQueryWindowPos() instead of WinQueryWindowRect().
Implement Decorations.{get|set}{Minimized|Maximized}() methods Done [dmik]
Add OS.objcpy (int, SWP), objcpy(SWP, int); WM_WINDOWPOSCHANGED, WM_ADJUSTWINDOWPOS message handling and AWP_* constants; implement SWT.Resize, SWT.Move, SWT.Iconify, SWT.Deiconify events... Activate? Done [dmik]
Add OS.WinGetSysBitmap() and SBMP_* constants, GpiQueryBitmapInfoHeader() and BITMAPINFOHEADER2 class, GpiDeleteBitmap() Done [dmik] Currently used to detect dimensions of the check box
Add OS.WinSetPresParam() and PP_* constants, implement two helper methods (Control.setPres{Foreground|Background}()) Done [dmik] Used to set the background and foreground colors of standard controls drawn by the system
add BS_*, BM_*, BN_*, BDS_* constants Done [dmik]
Add malloc(), free(), memcpy(), memset(); add 3 static helper methods to Control: beginDeferWindowPos(), endDeferWindowPos() and deferWindowPos(); add OS.WinSetMultWindowPos(), WinIsWindow() Done [dmik] We use standard C memory management functions because there's no advantage to organize a heap on the Java level. Without the heap, direct calls to DosAllocMem() to allocate small amounts waste memory since they always allocate it by blocks of 4KB.

OS.WinSetMultWindowPos() is used to improve the performance of sizing/moving operations.
Add handlers for WM_CONTROL, WM_COMMAND messages, CMDSRC_* constants; Add and partially implement the Button class (basic OS/2 buttons, setSelection(), getSelection(), SWT.Selection event) Done [dmik] Only OS/2 basic button styles are now implemented (excluding imaged ones)
Add OS.WinCalcFrameRect(), Implement Composite.setLayout(), getLayout(), layout(), Control.computeSize(), Scrollable.computeTrim() Done [dmik] Currently scrollbars are not taken into account when calculating the widget's preferred size
Replace the SWT004 testcase with SWT004_01 and SWT004_02 ones Done [dmik]
Make Control.getBorderWidth() to return values applicable for individual widgets Will be done on next steps Now it always returns the value of SV_CXBORDER, which is not the case for many widgets