Mercurial > projects > dwt-win
annotate dwt/custom/ViewForm.d @ 315:349b8c12e243
Sync dwt/custom with dwt-linux
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 07 Oct 2008 16:18:26 +0200 |
parents | fd9c62a2998e |
children |
rev | line source |
---|---|
155 | 1 /******************************************************************************* |
246 | 2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
155 | 3 * All rights reserved. This program and the accompanying materials |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwt.custom.ViewForm; | |
14 | |
315
349b8c12e243
Sync dwt/custom with dwt-linux
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
15 import dwt.dwthelper.utils; |
349b8c12e243
Sync dwt/custom with dwt-linux
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
16 |
155 | 17 |
18 | |
19 import dwt.DWT; | |
20 import dwt.DWTException; | |
21 import dwt.graphics.Color; | |
22 import dwt.graphics.GC; | |
23 import dwt.graphics.Point; | |
24 import dwt.graphics.RGB; | |
25 import dwt.graphics.Rectangle; | |
26 import dwt.widgets.Composite; | |
27 import dwt.widgets.Control; | |
28 import dwt.widgets.Event; | |
29 import dwt.widgets.Layout; | |
30 import dwt.widgets.Listener; | |
31 import dwt.custom.ViewFormLayout; | |
32 | |
33 /** | |
34 * Instances of this class implement a Composite that positions and sizes | |
35 * children and allows programmatic control of layout and border parameters. | |
36 * ViewForm is used in the workbench to lay out a view's label/menu/toolbar | |
37 * local bar. | |
38 * <p> | |
39 * Note that although this class is a subclass of <code>Composite</code>, | |
40 * it does not make sense to set a layout on it. | |
41 * </p><p> | |
42 * <dl> | |
43 * <dt><b>Styles:</b></dt> | |
44 * <dd>BORDER, FLAT</dd> | |
45 * <dt><b>Events:</b></dt> | |
46 * <dd>(None)</dd> | |
47 * </dl> | |
48 * <p> | |
49 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
50 * </p> | |
246 | 51 * |
52 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
155 | 53 */ |
54 | |
55 public class ViewForm : Composite { | |
56 | |
57 /** | |
58 * marginWidth specifies the number of pixels of horizontal margin | |
59 * that will be placed along the left and right edges of the form. | |
60 * | |
61 * The default value is 0. | |
62 */ | |
63 public int marginWidth = 0; | |
64 /** | |
65 * marginHeight specifies the number of pixels of vertical margin | |
66 * that will be placed along the top and bottom edges of the form. | |
67 * | |
68 * The default value is 0. | |
69 */ | |
70 public int marginHeight = 0; | |
71 /** | |
72 * horizontalSpacing specifies the number of pixels between the right | |
73 * edge of one cell and the left edge of its neighbouring cell to | |
74 * the right. | |
75 * | |
76 * The default value is 1. | |
77 */ | |
78 public int horizontalSpacing = 1; | |
79 /** | |
80 * verticalSpacing specifies the number of pixels between the bottom | |
81 * edge of one cell and the top edge of its neighbouring cell underneath. | |
82 * | |
83 * The default value is 1. | |
84 */ | |
85 public int verticalSpacing = 1; | |
86 | |
87 /** | |
88 * Color of innermost line of drop shadow border. | |
89 * | |
90 * NOTE This field is badly named and can not be fixed for backwards compatibility. | |
91 * It should be capitalized. | |
92 * | |
93 * @deprecated | |
94 */ | |
95 public static RGB borderInsideRGB; | |
96 /** | |
97 * Color of middle line of drop shadow border. | |
98 * | |
99 * NOTE This field is badly named and can not be fixed for backwards compatibility. | |
100 * It should be capitalized. | |
101 * | |
102 * @deprecated | |
103 */ | |
104 public static RGB borderMiddleRGB; | |
105 /** | |
106 * Color of outermost line of drop shadow border. | |
107 * | |
108 * NOTE This field is badly named and can not be fixed for backwards compatibility. | |
109 * It should be capitalized. | |
110 * | |
111 * @deprecated | |
112 */ | |
113 public static RGB borderOutsideRGB; | |
114 | |
115 // DWT widgets | |
116 Control topLeft; | |
117 Control topCenter; | |
118 Control topRight; | |
119 Control content; | |
120 | |
121 // Configuration and state info | |
122 bool separateTopCenter = false; | |
123 bool showBorder = false; | |
124 | |
125 int separator = -1; | |
126 int borderTop = 0; | |
127 int borderBottom = 0; | |
128 int borderLeft = 0; | |
129 int borderRight = 0; | |
130 int highlight = 0; | |
131 Point oldSize; | |
132 | |
133 Color selectionBackground; | |
134 | |
135 static final int OFFSCREEN = -200; | |
136 static final int BORDER1_COLOR = DWT.COLOR_WIDGET_NORMAL_SHADOW; | |
137 static final int SELECTION_BACKGROUND = DWT.COLOR_LIST_BACKGROUND; | |
138 | |
139 | |
140 static this(){ | |
141 borderInsideRGB = new RGB (132, 130, 132); | |
142 borderMiddleRGB = new RGB (143, 141, 138); | |
143 borderOutsideRGB = new RGB (171, 168, 165); | |
144 } | |
145 /** | |
146 * Constructs a new instance of this class given its parent | |
147 * and a style value describing its behavior and appearance. | |
148 * <p> | |
149 * The style value is either one of the style constants defined in | |
150 * class <code>DWT</code> which is applicable to instances of this | |
151 * class, or must be built by <em>bitwise OR</em>'ing together | |
152 * (that is, using the <code>int</code> "|" operator) two or more | |
153 * of those <code>DWT</code> style constants. The class description | |
154 * lists the style constants that are applicable to the class. | |
155 * Style bits are also inherited from superclasses. | |
156 * </p> | |
157 * | |
158 * @param parent a widget which will be the parent of the new instance (cannot be null) | |
159 * @param style the style of widget to construct | |
160 * | |
161 * @exception IllegalArgumentException <ul> | |
162 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
163 * </ul> | |
164 * @exception DWTException <ul> | |
165 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
166 * </ul> | |
167 * | |
168 * @see DWT#BORDER | |
169 * @see DWT#FLAT | |
170 * @see #getStyle() | |
171 */ | |
172 public this(Composite parent, int style) { | |
173 super(parent, checkStyle(style)); | |
174 super.setLayout(new ViewFormLayout()); | |
175 | |
176 setBorderVisible((style & DWT.BORDER) !is 0); | |
177 | |
178 Listener listener = new class() Listener { | |
179 public void handleEvent(Event e) { | |
180 switch (e.type) { | |
181 case DWT.Dispose: onDispose(); break; | |
182 case DWT.Paint: onPaint(e.gc); break; | |
183 case DWT.Resize: onResize(); break; | |
184 default: | |
185 } | |
186 } | |
187 }; | |
188 | |
189 int[] events = [DWT.Dispose, DWT.Paint, DWT.Resize]; | |
190 | |
191 for (int i = 0; i < events.length; i++) { | |
192 addListener(events[i], listener); | |
193 } | |
194 } | |
195 | |
196 static int checkStyle (int style) { | |
197 int mask = DWT.FLAT | DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; | |
198 return style & mask | DWT.NO_REDRAW_RESIZE; | |
199 } | |
200 | |
201 //protected void checkSubclass () { | |
202 // String name = getClass().getName (); | |
203 // String validName = ViewForm.class.getName(); | |
204 // if (!validName.equals(name)) { | |
205 // DWT.error (DWT.ERROR_INVALID_SUBCLASS); | |
206 // } | |
207 //} | |
208 | |
209 public override Rectangle computeTrim (int x, int y, int width, int height) { | |
210 checkWidget (); | |
211 int trimX = x - borderLeft - highlight; | |
212 int trimY = y - borderTop - highlight; | |
213 int trimWidth = width + borderLeft + borderRight + 2*highlight; | |
214 int trimHeight = height + borderTop + borderBottom + 2*highlight; | |
215 return new Rectangle(trimX, trimY, trimWidth, trimHeight); | |
216 } | |
217 public override Rectangle getClientArea() { | |
218 checkWidget(); | |
219 Rectangle clientArea = super.getClientArea(); | |
220 clientArea.x += borderLeft; | |
221 clientArea.y += borderTop; | |
222 clientArea.width -= borderLeft + borderRight; | |
223 clientArea.height -= borderTop + borderBottom; | |
224 return clientArea; | |
225 } | |
226 /** | |
227 * Returns the content area. | |
228 * | |
229 * @return the control in the content area of the pane or null | |
230 */ | |
231 public Control getContent() { | |
232 //checkWidget(); | |
233 return content; | |
234 } | |
235 /** | |
236 * Returns Control that appears in the top center of the pane. | |
237 * Typically this is a toolbar. | |
238 * | |
239 * @return the control in the top center of the pane or null | |
240 */ | |
241 public Control getTopCenter() { | |
242 //checkWidget(); | |
243 return topCenter; | |
244 } | |
245 /** | |
246 * Returns the Control that appears in the top left corner of the pane. | |
247 * Typically this is a label such as CLabel. | |
248 * | |
249 * @return the control in the top left corner of the pane or null | |
250 */ | |
251 public Control getTopLeft() { | |
252 //checkWidget(); | |
253 return topLeft; | |
254 } | |
255 /** | |
256 * Returns the control in the top right corner of the pane. | |
257 * Typically this is a Close button or a composite with a Menu and Close button. | |
258 * | |
259 * @return the control in the top right corner of the pane or null | |
260 */ | |
261 public Control getTopRight() { | |
262 //checkWidget(); | |
263 return topRight; | |
264 } | |
265 void onDispose() { | |
266 topLeft = null; | |
267 topCenter = null; | |
268 topRight = null; | |
269 content = null; | |
270 oldSize = null; | |
271 selectionBackground = null; | |
272 } | |
273 void onPaint(GC gc) { | |
274 Color gcForeground = gc.getForeground(); | |
275 Point size = getSize(); | |
276 Color border = getDisplay().getSystemColor(BORDER1_COLOR); | |
277 if (showBorder) { | |
278 gc.setForeground(border); | |
279 gc.drawRectangle(0, 0, size.x - 1, size.y - 1); | |
280 if (highlight > 0) { | |
281 int x1 = 1; | |
282 int y1 = 1; | |
283 int x2 = size.x - 1; | |
284 int y2 = size.y - 1; | |
285 int[] shape = [x1,y1, x2,y1, x2,y2, x1,y2, x1,y1+highlight, | |
286 x1+highlight,y1+highlight, x1+highlight,y2-highlight, | |
287 x2-highlight,y2-highlight, x2-highlight,y1+highlight, x1,y1+highlight]; | |
288 Color highlightColor = getDisplay().getSystemColor(DWT.COLOR_LIST_SELECTION); | |
289 gc.setBackground(highlightColor); | |
290 gc.fillPolygon(shape); | |
291 } | |
292 } | |
293 if (separator > -1) { | |
294 gc.setForeground(border); | |
295 gc.drawLine(borderLeft + highlight, separator, size.x - borderLeft - borderRight - highlight, separator); | |
296 } | |
297 gc.setForeground(gcForeground); | |
298 } | |
299 void onResize() { | |
300 Point size = getSize(); | |
301 if (oldSize is null || oldSize.x is 0 || oldSize.y is 0) { | |
302 redraw(); | |
303 } else { | |
304 int width = 0; | |
305 if (oldSize.x < size.x) { | |
306 width = size.x - oldSize.x + borderRight + highlight; | |
307 } else if (oldSize.x > size.x) { | |
308 width = borderRight + highlight; | |
309 } | |
310 redraw(size.x - width, 0, width, size.y, false); | |
311 | |
312 int height = 0; | |
313 if (oldSize.y < size.y) { | |
314 height = size.y - oldSize.y + borderBottom + highlight; | |
315 } | |
316 if (oldSize.y > size.y) { | |
317 height = borderBottom + highlight; | |
318 } | |
319 redraw(0, size.y - height, size.x, height, false); | |
320 } | |
321 oldSize = size; | |
322 } | |
323 /** | |
324 * Sets the content. | |
325 * Setting the content to null will remove it from | |
326 * the pane - however, the creator of the content must dispose of the content. | |
327 * | |
328 * @param content the control to be displayed in the content area or null | |
329 * | |
330 * @exception DWTException <ul> | |
331 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
332 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
333 * <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this ViewForm</li> | |
334 * </ul> | |
335 */ | |
336 public void setContent(Control content) { | |
337 checkWidget(); | |
338 if (content !is null && content.getParent() !is this) { | |
339 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
340 } | |
341 if (this.content !is null && !this.content.isDisposed()) { | |
342 this.content.setBounds(OFFSCREEN, OFFSCREEN, 0, 0); | |
343 } | |
344 this.content = content; | |
345 layout(false); | |
346 } | |
347 /** | |
348 * Sets the layout which is associated with the receiver to be | |
349 * the argument which may be null. | |
350 * <p> | |
351 * Note: No Layout can be set on this Control because it already | |
352 * manages the size and position of its children. | |
353 * </p> | |
354 * | |
355 * @param layout the receiver's new layout or null | |
356 * | |
357 * @exception DWTException <ul> | |
358 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
359 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
360 * </ul> | |
361 */ | |
362 public override void setLayout (Layout layout) { | |
363 checkWidget(); | |
364 return; | |
365 } | |
366 void setSelectionBackground (Color color) { | |
367 checkWidget(); | |
368 if (selectionBackground is color) return; | |
369 if (color is null) color = getDisplay().getSystemColor(SELECTION_BACKGROUND); | |
370 selectionBackground = color; | |
371 redraw(); | |
372 } | |
373 /** | |
374 * Set the control that appears in the top center of the pane. | |
375 * Typically this is a toolbar. | |
376 * The topCenter is optional. Setting the topCenter to null will remove it from | |
377 * the pane - however, the creator of the topCenter must dispose of the topCenter. | |
378 * | |
379 * @param topCenter the control to be displayed in the top center or null | |
380 * | |
381 * @exception DWTException <ul> | |
382 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
383 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
384 * <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this ViewForm</li> | |
385 * </ul> | |
386 */ | |
387 public void setTopCenter(Control topCenter) { | |
388 checkWidget(); | |
389 if (topCenter !is null && topCenter.getParent() !is this) { | |
390 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
391 } | |
392 if (this.topCenter !is null && !this.topCenter.isDisposed()) { | |
393 Point size = this.topCenter.getSize(); | |
394 this.topCenter.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y); | |
395 } | |
396 this.topCenter = topCenter; | |
397 layout(false); | |
398 } | |
399 /** | |
400 * Set the control that appears in the top left corner of the pane. | |
401 * Typically this is a label such as CLabel. | |
402 * The topLeft is optional. Setting the top left control to null will remove it from | |
403 * the pane - however, the creator of the control must dispose of the control. | |
404 * | |
405 * @param c the control to be displayed in the top left corner or null | |
406 * | |
407 * @exception DWTException <ul> | |
408 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
409 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
410 * <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this ViewForm</li> | |
411 * </ul> | |
412 */ | |
413 public void setTopLeft(Control c) { | |
414 checkWidget(); | |
415 if (c !is null && c.getParent() !is this) { | |
416 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
417 } | |
418 if (this.topLeft !is null && !this.topLeft.isDisposed()) { | |
419 Point size = this.topLeft.getSize(); | |
420 this.topLeft.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y); | |
421 } | |
422 this.topLeft = c; | |
423 layout(false); | |
424 } | |
425 /** | |
426 * Set the control that appears in the top right corner of the pane. | |
427 * Typically this is a Close button or a composite with a Menu and Close button. | |
428 * The topRight is optional. Setting the top right control to null will remove it from | |
429 * the pane - however, the creator of the control must dispose of the control. | |
430 * | |
431 * @param c the control to be displayed in the top right corner or null | |
432 * | |
433 * @exception DWTException <ul> | |
434 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
435 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
436 * <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this ViewForm</li> | |
437 * </ul> | |
438 */ | |
439 public void setTopRight(Control c) { | |
440 checkWidget(); | |
441 if (c !is null && c.getParent() !is this) { | |
442 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
443 } | |
444 if (this.topRight !is null && !this.topRight.isDisposed()) { | |
445 Point size = this.topRight.getSize(); | |
446 this.topRight.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y); | |
447 } | |
448 this.topRight = c; | |
449 layout(false); | |
450 } | |
451 /** | |
452 * Specify whether the border should be displayed or not. | |
453 * | |
454 * @param show true if the border should be displayed | |
455 * | |
456 * @exception DWTException <ul> | |
457 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
458 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
459 * </ul> | |
460 */ | |
461 public void setBorderVisible(bool show) { | |
462 checkWidget(); | |
463 if (showBorder is show) return; | |
464 | |
465 showBorder = show; | |
466 if (showBorder) { | |
467 borderLeft = borderTop = borderRight = borderBottom = 1; | |
468 if ((getStyle() & DWT.FLAT)is 0) highlight = 2; | |
469 } else { | |
470 borderBottom = borderTop = borderLeft = borderRight = 0; | |
471 highlight = 0; | |
472 } | |
473 layout(false); | |
474 redraw(); | |
475 } | |
476 /** | |
477 * If true, the topCenter will always appear on a separate line by itself, otherwise the | |
478 * topCenter will appear in the top row if there is room and will be moved to the second row if | |
479 * required. | |
480 * | |
481 * @param show true if the topCenter will always appear on a separate line by itself | |
482 * | |
483 * @exception DWTException <ul> | |
484 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
485 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
486 * </ul> | |
487 */ | |
488 public void setTopCenterSeparate(bool show) { | |
489 checkWidget(); | |
490 separateTopCenter = show; | |
491 layout(false); | |
492 } | |
493 } |