| 1 | <?xml version='1.0' encoding='UTF-8'?> | 
|---|
| 2 | <?xml-stylesheet type="text/css" | 
|---|
| 3 | href="eclipseos2-xxe.css" | 
|---|
| 4 | ?> | 
|---|
| 5 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | 
|---|
| 6 | "xhtml1-strict.dtd"> | 
|---|
| 7 | <html> | 
|---|
| 8 | <head> | 
|---|
| 9 | <link type="text/css" | 
|---|
| 10 | href="eclipseos2.css" | 
|---|
| 11 | rel="stylesheet" /> | 
|---|
| 12 |  | 
|---|
| 13 | <title>Eclipse for OS/2 Transitional Project Notes</title> | 
|---|
| 14 | </head> | 
|---|
| 15 |  | 
|---|
| 16 | <body> | 
|---|
| 17 | <h1>SWT Step 4. Layout basics</h1> | 
|---|
| 18 |  | 
|---|
| 19 | <h2>Objective</h2> | 
|---|
| 20 |  | 
|---|
| 21 | <p>Implement the basics of the layout management. The testcase example | 
|---|
| 22 | shoud be able to create a top shell containing a simple button.</p> | 
|---|
| 23 |  | 
|---|
| 24 | <h2>Task notes</h2> | 
|---|
| 25 |  | 
|---|
| 26 | <h3>Default Shell size and position</h3> | 
|---|
| 27 |  | 
|---|
| 28 | <p>In SWT, it's assumed that the <code>o.e.swt.widgets.Shell</code> is | 
|---|
| 29 | created with the default size and position assigned by the system.</p> | 
|---|
| 30 |  | 
|---|
| 31 | <p>Since OS/2 handles the <code>FS_SHELLPOSITION</code> flag in a very | 
|---|
| 32 | strange manner (the size/position of the frame after creation remains zero | 
|---|
| 33 | until the frame is shown for the first time, and there's no way | 
|---|
| 34 | neither to get the size/position the system is going to assign nor to | 
|---|
| 35 | change them before the frame is shown) the workaround is made using | 
|---|
| 36 | <code>WinQueryTaskSizePos()</code> (it seems to return the same values the | 
|---|
| 37 | system uses when <code>FS_SHELLPOSITION</code> is specified). This means, | 
|---|
| 38 | that the <code>Shell.getBounds()</code> method will return system assigned | 
|---|
| 39 | values (but not zero as it would be in the case of <code>FS_SHELLPOSITION</code>) | 
|---|
| 40 | after <code>Shell</code> creation and before opening (showing) it and | 
|---|
| 41 | it's also possible to change them -- the same behavior is shown in | 
|---|
| 42 | Windows.</p> | 
|---|
| 43 |  | 
|---|
| 44 | <h3>Notification messages</h3> | 
|---|
| 45 |  | 
|---|
| 46 | <p>In OS/2 control notification messages (<code>WM_CONTROL</code>, | 
|---|
| 47 | <code>WM_COMMAND</code>) do not necessarily contain the control window | 
|---|
| 48 | handle in their parameters, only the identity is guaranteed to present in | 
|---|
| 49 | most cases. Therefore, in order to send the message back to the widget | 
|---|
| 50 | (this is an SWT logic and it is quite handy) the only way to determine its | 
|---|
| 51 | handle, which we need to obtain a reference to the widget, is to use its | 
|---|
| 52 | window ID. This, in turn, requires an algorithm to generate IDs during | 
|---|
| 53 | window creation, that are unique within the owner window context. The | 
|---|
| 54 | window handle could be such unique identifier, but the problem is that the | 
|---|
| 55 | window ID is a 16-bit value. However, at the present, we still use it for | 
|---|
| 56 | that purpose taking its low 16 bits, which is based on the assumption that | 
|---|
| 57 | handles in OS/2 always have a form of <code>0x8000nnnn</code>. But this | 
|---|
| 58 | assumtion is possibly erroneous, so in the future this algorithm should be | 
|---|
| 59 | replaced with another one.</p> | 
|---|
| 60 |  | 
|---|
| 61 | <h3><a name="WidgetHeight">Widget height</a></h3> | 
|---|
| 62 |  | 
|---|
| 63 | <p>As mentioned in task notes of the <a | 
|---|
| 64 | href="swt002.html#ScreenCoordinates">SWT002</a> step about screen | 
|---|
| 65 | coordinates, we need an easy way to obtain the height of a widget as well | 
|---|
| 66 | as the height of its parent to do necessary calculations related to the | 
|---|
| 67 | coordinate space flipping. The package method <code>Control.getHeight()</code> | 
|---|
| 68 | can still be used to get the height of the widget itself (respecting the | 
|---|
| 69 | situation when the widget is the <code>Decorations</code> instance and it | 
|---|
| 70 | is minimized). The height of the widget's parent can be obtained by | 
|---|
| 71 | the <code>Control.getParentHeight()</code> call (which, for the | 
|---|
| 72 | <code>Shell</code> class, returns the value of the <code>Shell.display.getHeight()</code> | 
|---|
| 73 | method, rather then <code>parent.getHeight()</code>, if the parent is | 
|---|
| 74 | <code>null</code>). The situation for non-<code>Shell</code> windows when | 
|---|
| 75 | the parent is <code>null</code> is inapplicable, so the exception is | 
|---|
| 76 | thrown in this case. The <code>Control.getBounds(SWP)</code> package | 
|---|
| 77 | method returns the height of the parent just as it returned by the | 
|---|
| 78 | <code>getParentHeight()</code> method.</p> | 
|---|
| 79 |  | 
|---|
| 80 | <h2>Step checklist</h2> | 
|---|
| 81 |  | 
|---|
| 82 | <table> | 
|---|
| 83 | <col width="40%" /> | 
|---|
| 84 |  | 
|---|
| 85 | <col /> | 
|---|
| 86 |  | 
|---|
| 87 | <col width="50%" /> | 
|---|
| 88 |  | 
|---|
| 89 | <thead> | 
|---|
| 90 | <tr> | 
|---|
| 91 | <th>Operation</th> | 
|---|
| 92 |  | 
|---|
| 93 | <th>Status</th> | 
|---|
| 94 |  | 
|---|
| 95 | <th>Remarks</th> | 
|---|
| 96 | </tr> | 
|---|
| 97 | </thead> | 
|---|
| 98 |  | 
|---|
| 99 | <tr> | 
|---|
| 100 | <td>Make the size and position methods of widgets to work correcty | 
|---|
| 101 | (add <code>OS.SWP</code> structre, <code>OS.WinQueryTaskSizePos()</code>, | 
|---|
| 102 | <code>WinQueryWindowPos()</code>); implement <code>Display.getBounds()</code></td> | 
|---|
| 103 |  | 
|---|
| 104 | <td>Done [dmik]</td> | 
|---|
| 105 |  | 
|---|
| 106 | <td>Size and position relative methods are completely rewritten: now | 
|---|
| 107 | they use the package helper method <code>getBounds(SWP)</code> which | 
|---|
| 108 | uses <code>WinQueryWindowPos()</code> instead of <code>WinQueryWindowRect()</code>.</td> | 
|---|
| 109 | </tr> | 
|---|
| 110 |  | 
|---|
| 111 | <tr> | 
|---|
| 112 | <td>Implement <code>Decorations.{get|set}{Minimized|Maximized}()</code> | 
|---|
| 113 | methods</td> | 
|---|
| 114 |  | 
|---|
| 115 | <td>Done [dmik]</td> | 
|---|
| 116 |  | 
|---|
| 117 | <td></td> | 
|---|
| 118 | </tr> | 
|---|
| 119 |  | 
|---|
| 120 | <tr> | 
|---|
| 121 | <td>Add <code>OS.objcpy (int, SWP)</code>, <code>objcpy(SWP, int)</code>; | 
|---|
| 122 | <code>WM_WINDOWPOSCHANGED</code>, <code>WM_ADJUSTWINDOWPOS</code> | 
|---|
| 123 | message handling and <code>AWP_*</code> constants; implement | 
|---|
| 124 | <code>SWT.Resize</code>, <code>SWT.Move</code>, <code>SWT.Iconify</code>, | 
|---|
| 125 | <code>SWT.Deiconify</code> events... Activate?</td> | 
|---|
| 126 |  | 
|---|
| 127 | <td>Done [dmik]</td> | 
|---|
| 128 |  | 
|---|
| 129 | <td></td> | 
|---|
| 130 | </tr> | 
|---|
| 131 |  | 
|---|
| 132 | <tr> | 
|---|
| 133 | <td>Add <code>OS.WinGetSysBitmap()</code> and <code>SBMP_*</code> | 
|---|
| 134 | constants, <code>GpiQueryBitmapInfoHeader()</code> and <code>BITMAPINFOHEADER2</code> | 
|---|
| 135 | class, <code>GpiDeleteBitmap()</code></td> | 
|---|
| 136 |  | 
|---|
| 137 | <td>Done [dmik]</td> | 
|---|
| 138 |  | 
|---|
| 139 | <td>Currently used to detect dimensions of the check box</td> | 
|---|
| 140 | </tr> | 
|---|
| 141 |  | 
|---|
| 142 | <tr> | 
|---|
| 143 | <td>Add <code>OS.WinSetPresParam()</code> and <code>PP_*</code> | 
|---|
| 144 | constants, implement two helper methods (<code>Control.setPres{Foreground|Background}()</code>)</td> | 
|---|
| 145 |  | 
|---|
| 146 | <td>Done [dmik]</td> | 
|---|
| 147 |  | 
|---|
| 148 | <td>Used to set the background and foreground colors of standard | 
|---|
| 149 | controls drawn by the system</td> | 
|---|
| 150 | </tr> | 
|---|
| 151 |  | 
|---|
| 152 | <tr> | 
|---|
| 153 | <td>add <code>BS_*</code>, <code>BM_*</code>, <code>BN_*</code>, | 
|---|
| 154 | <code>BDS_*</code> constants</td> | 
|---|
| 155 |  | 
|---|
| 156 | <td>Done [dmik]</td> | 
|---|
| 157 |  | 
|---|
| 158 | <td></td> | 
|---|
| 159 | </tr> | 
|---|
| 160 |  | 
|---|
| 161 | <tr> | 
|---|
| 162 | <td>Add <code>malloc()</code>, <code>free()</code>, <code>memcpy()</code>, | 
|---|
| 163 | <code>memset()</code>; add 3 static helper methods to <code>Control</code>: | 
|---|
| 164 | <code>beginDeferWindowPos()</code>, <code>endDeferWindowPos()</code> | 
|---|
| 165 | and <code>deferWindowPos()</code>; add <code>OS.WinSetMultWindowPos()</code>, | 
|---|
| 166 | <code>WinIsWindow()</code></td> | 
|---|
| 167 |  | 
|---|
| 168 | <td>Done [dmik]</td> | 
|---|
| 169 |  | 
|---|
| 170 | <td>We use standard C memory management functions because there's | 
|---|
| 171 | no advantage to organize a heap on the Java level. Without the heap, | 
|---|
| 172 | direct calls to <code>DosAllocMem()</code> to allocate small amounts | 
|---|
| 173 | waste memory since they always allocate it by blocks of 4KB.<br /><br /><code>OS.WinSetMultWindowPos()</code> | 
|---|
| 174 | is used to improve the performance of sizing/moving operations.</td> | 
|---|
| 175 | </tr> | 
|---|
| 176 |  | 
|---|
| 177 | <tr> | 
|---|
| 178 | <td>Add handlers for <code>WM_CONTROL</code>, <code>WM_COMMAND</code> | 
|---|
| 179 | messages, <code>CMDSRC_*</code> constants; Add and partially implement | 
|---|
| 180 | the <code>Button</code> class (basic OS/2 buttons, <code>setSelection()</code>, | 
|---|
| 181 | <code>getSelection()</code>, <code>SWT.Selection</code> event)</td> | 
|---|
| 182 |  | 
|---|
| 183 | <td>Done [dmik]</td> | 
|---|
| 184 |  | 
|---|
| 185 | <td>Only OS/2 basic button styles are now implemented (excluding | 
|---|
| 186 | imaged ones)</td> | 
|---|
| 187 | </tr> | 
|---|
| 188 |  | 
|---|
| 189 | <tr> | 
|---|
| 190 | <td>Add <code>OS.WinCalcFrameRect()</code>, Implement <code>Composite.setLayout()</code>, | 
|---|
| 191 | <code>getLayout()</code>, <code>layout()</code>, <code>Control.computeSize()</code>, | 
|---|
| 192 | <code>Scrollable.computeTrim()</code></td> | 
|---|
| 193 |  | 
|---|
| 194 | <td>Done [dmik]</td> | 
|---|
| 195 |  | 
|---|
| 196 | <td>Currently scrollbars are not taken into account when calculating | 
|---|
| 197 | the widget's preferred size</td> | 
|---|
| 198 | </tr> | 
|---|
| 199 |  | 
|---|
| 200 | <tr> | 
|---|
| 201 | <td>Replace the <code>SWT004</code> testcase with <code>SWT004_01</code> | 
|---|
| 202 | and <code>SWT004_02</code> ones</td> | 
|---|
| 203 |  | 
|---|
| 204 | <td>Done [dmik]</td> | 
|---|
| 205 |  | 
|---|
| 206 | <td></td> | 
|---|
| 207 | </tr> | 
|---|
| 208 |  | 
|---|
| 209 | <tr> | 
|---|
| 210 | <td>Make <code>Control.getBorderWidth()</code> to return values | 
|---|
| 211 | applicable for individual widgets</td> | 
|---|
| 212 |  | 
|---|
| 213 | <td>Will be done on next steps</td> | 
|---|
| 214 |  | 
|---|
| 215 | <td>Now it always returns the value of <code>SV_CXBORDER</code>, which | 
|---|
| 216 | is not the case for many widgets</td> | 
|---|
| 217 | </tr> | 
|---|
| 218 | </table> | 
|---|
| 219 | </body> | 
|---|
| 220 | </html> | 
|---|