Mercurial > projects > dwt-mac
comparison dwt/widgets/Control.d @ 0:380af2bdd8e5
Upload of whole dwt tree
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Sat, 09 Aug 2008 17:00:02 +0200 |
parents | |
children | 649b8e223d5a 2952d5604c0a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:380af2bdd8e5 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
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 *******************************************************************************/ | |
11 module dwt.widgets.Control; | |
12 | |
13 import dwt.dwthelper.utils; | |
14 | |
15 import dwt.DWT; | |
16 import dwt.DWTException; | |
17 import dwt.accessibility.Accessible; | |
18 import dwt.events.ControlListener; | |
19 import dwt.events.DragDetectListener; | |
20 import dwt.events.FocusListener; | |
21 import dwt.events.HelpListener; | |
22 import dwt.events.KeyListener; | |
23 import dwt.events.MenuDetectListener; | |
24 import dwt.events.MouseEvent; | |
25 import dwt.events.MouseListener; | |
26 import dwt.events.MouseMoveListener; | |
27 import dwt.events.MouseTrackListener; | |
28 import dwt.events.MouseWheelListener; | |
29 import dwt.events.PaintListener; | |
30 import dwt.events.TraverseListener; | |
31 import dwt.graphics.Color; | |
32 import dwt.graphics.Cursor; | |
33 import dwt.graphics.Drawable; | |
34 import dwt.graphics.Font; | |
35 import dwt.graphics.GC; | |
36 import dwt.graphics.GCData; | |
37 import dwt.graphics.Image; | |
38 import dwt.graphics.Point; | |
39 import dwt.graphics.Rectangle; | |
40 import dwt.graphics.Region; | |
41 import dwt.internal.cocoa.NSControl; | |
42 import dwt.internal.cocoa.NSEvent; | |
43 import dwt.internal.cocoa.NSFont; | |
44 import dwt.internal.cocoa.NSGraphicsContext; | |
45 import dwt.internal.cocoa.NSPoint; | |
46 import dwt.internal.cocoa.NSRect; | |
47 import dwt.internal.cocoa.NSSize; | |
48 import dwt.internal.cocoa.NSString; | |
49 import dwt.internal.cocoa.NSView; | |
50 import dwt.internal.cocoa.NSWindow; | |
51 import dwt.internal.cocoa.OS; | |
52 import dwt.internal.cocoa.objc_super; | |
53 | |
54 /** | |
55 * Control is the abstract superclass of all windowed user interface classes. | |
56 * <p> | |
57 * <dl> | |
58 * <dt><b>Styles:</b> | |
59 * <dd>BORDER</dd> | |
60 * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd> | |
61 * <dt><b>Events:</b> | |
62 * <dd>DragDetect, FocusIn, FocusOut, Help, KeyDown, KeyUp, MenuDetect, MouseDoubleClick, MouseDown, MouseEnter, | |
63 * MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize, Traverse</dd> | |
64 * </dl> | |
65 * </p><p> | |
66 * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified. | |
67 * </p><p> | |
68 * IMPORTANT: This class is intended to be subclassed <em>only</em> | |
69 * within the DWT implementation. | |
70 * </p> | |
71 */ | |
72 public abstract class Control extends Widget implements Drawable { | |
73 /** | |
74 * the handle to the OS resource | |
75 * (Warning: This field is platform dependent) | |
76 * <p> | |
77 * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT | |
78 * public API. It is marked public only so that it can be shared | |
79 * within the packages provided by DWT. It is not available on all | |
80 * platforms and should never be accessed from application code. | |
81 * </p> | |
82 */ | |
83 public NSView view; | |
84 Composite parent; | |
85 String toolTipText; | |
86 Object layoutData; | |
87 int drawCount; | |
88 // int visibleRgn; | |
89 Menu menu; | |
90 Color foreground, background; | |
91 Image backgroundImage; | |
92 Font font; | |
93 Cursor cursor; | |
94 Region region; | |
95 // GCData gcs[]; | |
96 Accessible accessible; | |
97 | |
98 // static final String RESET_VISIBLE_REGION = "dwt.internal.resetVisibleRegion"; | |
99 | |
100 Control () { | |
101 /* Do nothing */ | |
102 } | |
103 | |
104 /** | |
105 * Constructs a new instance of this class given its parent | |
106 * and a style value describing its behavior and appearance. | |
107 * <p> | |
108 * The style value is either one of the style constants defined in | |
109 * class <code>DWT</code> which is applicable to instances of this | |
110 * class, or must be built by <em>bitwise OR</em>'ing together | |
111 * (that is, using the <code>int</code> "|" operator) two or more | |
112 * of those <code>DWT</code> style constants. The class description | |
113 * lists the style constants that are applicable to the class. | |
114 * Style bits are also inherited from superclasses. | |
115 * </p> | |
116 * | |
117 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
118 * @param style the style of control to construct | |
119 * | |
120 * @exception IllegalArgumentException <ul> | |
121 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
122 * </ul> | |
123 * @exception DWTException <ul> | |
124 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
125 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
126 * </ul> | |
127 * | |
128 * @see DWT#BORDER | |
129 * @see Widget#checkSubclass | |
130 * @see Widget#getStyle | |
131 */ | |
132 public Control (Composite parent, int style) { | |
133 super (parent, style); | |
134 this.parent = parent; | |
135 createWidget (); | |
136 } | |
137 | |
138 bool acceptsFirstResponder () { | |
139 objc_super super_struct = new objc_super(); | |
140 super_struct.receiver = view.id; | |
141 super_struct.cls = OS.objc_msgSend(view.id, OS.sel_superclass); | |
142 return OS.objc_msgSendSuper(super_struct, OS.sel_acceptsFirstResponder) !is 0; | |
143 } | |
144 | |
145 bool becomeFirstResponder () { | |
146 //TODO - query focusControl() in DWT.FocusIn/Out is the control | |
147 sendEvent (DWT.FocusIn); | |
148 objc_super super_struct = new objc_super(); | |
149 super_struct.receiver = view.id; | |
150 super_struct.cls = OS.objc_msgSend(view.id, OS.sel_superclass); | |
151 return OS.objc_msgSendSuper(super_struct, OS.sel_becomeFirstResponder) !is 0; | |
152 } | |
153 | |
154 bool resignFirstResponder () { | |
155 //TODO - query focusControl() in DWT.FocusIn/Out is the control | |
156 sendEvent (DWT.FocusOut); | |
157 objc_super super_struct = new objc_super(); | |
158 super_struct.receiver = view.id; | |
159 super_struct.cls = OS.objc_msgSend(view.id, OS.sel_superclass); | |
160 return OS.objc_msgSendSuper(super_struct, OS.sel_resignFirstResponder) !is 0; | |
161 } | |
162 | |
163 /** | |
164 * Adds the listener to the collection of listeners who will | |
165 * be notified when the control is moved or resized, by sending | |
166 * it one of the messages defined in the <code>ControlListener</code> | |
167 * interface. | |
168 * | |
169 * @param listener the listener which should be notified | |
170 * | |
171 * @exception IllegalArgumentException <ul> | |
172 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
173 * </ul> | |
174 * @exception DWTException <ul> | |
175 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
176 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
177 * </ul> | |
178 * | |
179 * @see ControlListener | |
180 * @see #removeControlListener | |
181 */ | |
182 public void addControlListener(ControlListener listener) { | |
183 checkWidget(); | |
184 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
185 TypedListener typedListener = new TypedListener (listener); | |
186 addListener (DWT.Resize,typedListener); | |
187 addListener (DWT.Move,typedListener); | |
188 } | |
189 | |
190 /** | |
191 * Adds the listener to the collection of listeners who will | |
192 * be notified when a drag gesture occurs, by sending it | |
193 * one of the messages defined in the <code>DragDetectListener</code> | |
194 * interface. | |
195 * | |
196 * @param listener the listener which should be notified | |
197 * | |
198 * @exception IllegalArgumentException <ul> | |
199 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
200 * </ul> | |
201 * @exception DWTException <ul> | |
202 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
203 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
204 * </ul> | |
205 * | |
206 * @see DragDetectListener | |
207 * @see #removeDragDetectListener | |
208 * | |
209 * @since 3.3 | |
210 */ | |
211 public void addDragDetectListener (DragDetectListener listener) { | |
212 checkWidget (); | |
213 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
214 TypedListener typedListener = new TypedListener (listener); | |
215 addListener (DWT.DragDetect,typedListener); | |
216 } | |
217 | |
218 /** | |
219 * Adds the listener to the collection of listeners who will | |
220 * be notified when the control gains or loses focus, by sending | |
221 * it one of the messages defined in the <code>FocusListener</code> | |
222 * interface. | |
223 * | |
224 * @param listener the listener which should be notified | |
225 * | |
226 * @exception IllegalArgumentException <ul> | |
227 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
228 * </ul> | |
229 * @exception DWTException <ul> | |
230 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
231 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
232 * </ul> | |
233 * | |
234 * @see FocusListener | |
235 * @see #removeFocusListener | |
236 */ | |
237 public void addFocusListener(FocusListener listener) { | |
238 checkWidget(); | |
239 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
240 TypedListener typedListener = new TypedListener (listener); | |
241 addListener(DWT.FocusIn,typedListener); | |
242 addListener(DWT.FocusOut,typedListener); | |
243 } | |
244 | |
245 /** | |
246 * Adds the listener to the collection of listeners who will | |
247 * be notified when help events are generated for the control, | |
248 * by sending it one of the messages defined in the | |
249 * <code>HelpListener</code> interface. | |
250 * | |
251 * @param listener the listener which should be notified | |
252 * | |
253 * @exception IllegalArgumentException <ul> | |
254 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
255 * </ul> | |
256 * @exception DWTException <ul> | |
257 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
258 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
259 * </ul> | |
260 * | |
261 * @see HelpListener | |
262 * @see #removeHelpListener | |
263 */ | |
264 public void addHelpListener (HelpListener listener) { | |
265 checkWidget(); | |
266 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
267 TypedListener typedListener = new TypedListener (listener); | |
268 addListener (DWT.Help, typedListener); | |
269 } | |
270 | |
271 /** | |
272 * Adds the listener to the collection of listeners who will | |
273 * be notified when keys are pressed and released on the system keyboard, by sending | |
274 * it one of the messages defined in the <code>KeyListener</code> | |
275 * interface. | |
276 * <p> | |
277 * When a key listener is added to a control, the control | |
278 * will take part in widget traversal. By default, all | |
279 * traversal keys (such as the tab key and so on) are | |
280 * delivered to the control. In order for a control to take | |
281 * part in traversal, it should listen for traversal events. | |
282 * Otherwise, the user can traverse into a control but not | |
283 * out. Note that native controls such as table and tree | |
284 * implement key traversal in the operating system. It is | |
285 * not necessary to add traversal listeners for these controls, | |
286 * unless you want to override the default traversal. | |
287 * </p> | |
288 * @param listener the listener which should be notified | |
289 * | |
290 * @exception IllegalArgumentException <ul> | |
291 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
292 * </ul> | |
293 * @exception DWTException <ul> | |
294 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
295 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
296 * </ul> | |
297 * | |
298 * @see KeyListener | |
299 * @see #removeKeyListener | |
300 */ | |
301 public void addKeyListener(KeyListener listener) { | |
302 checkWidget(); | |
303 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
304 TypedListener typedListener = new TypedListener (listener); | |
305 addListener(DWT.KeyUp,typedListener); | |
306 addListener(DWT.KeyDown,typedListener); | |
307 } | |
308 | |
309 /** | |
310 * Adds the listener to the collection of listeners who will | |
311 * be notified when the platform-specific context menu trigger | |
312 * has occurred, by sending it one of the messages defined in | |
313 * the <code>MenuDetectListener</code> interface. | |
314 * | |
315 * @param listener the listener which should be notified | |
316 * | |
317 * @exception IllegalArgumentException <ul> | |
318 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
319 * </ul> | |
320 * @exception DWTException <ul> | |
321 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
322 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
323 * </ul> | |
324 * | |
325 * @see MenuDetectListener | |
326 * @see #removeMenuDetectListener | |
327 * | |
328 * @since 3.3 | |
329 */ | |
330 public void addMenuDetectListener (MenuDetectListener listener) { | |
331 checkWidget (); | |
332 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
333 TypedListener typedListener = new TypedListener (listener); | |
334 addListener (DWT.MenuDetect, typedListener); | |
335 } | |
336 | |
337 /** | |
338 * Adds the listener to the collection of listeners who will | |
339 * be notified when mouse buttons are pressed and released, by sending | |
340 * it one of the messages defined in the <code>MouseListener</code> | |
341 * interface. | |
342 * | |
343 * @param listener the listener which should be notified | |
344 * | |
345 * @exception IllegalArgumentException <ul> | |
346 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
347 * </ul> | |
348 * @exception DWTException <ul> | |
349 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
350 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
351 * </ul> | |
352 * | |
353 * @see MouseListener | |
354 * @see #removeMouseListener | |
355 */ | |
356 public void addMouseListener(MouseListener listener) { | |
357 checkWidget(); | |
358 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
359 TypedListener typedListener = new TypedListener (listener); | |
360 addListener(DWT.MouseDown,typedListener); | |
361 addListener(DWT.MouseUp,typedListener); | |
362 addListener(DWT.MouseDoubleClick,typedListener); | |
363 } | |
364 | |
365 /** | |
366 * Adds the listener to the collection of listeners who will | |
367 * be notified when the mouse passes or hovers over controls, by sending | |
368 * it one of the messages defined in the <code>MouseTrackListener</code> | |
369 * interface. | |
370 * | |
371 * @param listener the listener which should be notified | |
372 * | |
373 * @exception IllegalArgumentException <ul> | |
374 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
375 * </ul> | |
376 * @exception DWTException <ul> | |
377 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
378 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
379 * </ul> | |
380 * | |
381 * @see MouseTrackListener | |
382 * @see #removeMouseTrackListener | |
383 */ | |
384 public void addMouseTrackListener (MouseTrackListener listener) { | |
385 checkWidget(); | |
386 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
387 TypedListener typedListener = new TypedListener (listener); | |
388 addListener (DWT.MouseEnter,typedListener); | |
389 addListener (DWT.MouseExit,typedListener); | |
390 addListener (DWT.MouseHover,typedListener); | |
391 } | |
392 | |
393 /** | |
394 * Adds the listener to the collection of listeners who will | |
395 * be notified when the mouse moves, by sending it one of the | |
396 * messages defined in the <code>MouseMoveListener</code> | |
397 * interface. | |
398 * | |
399 * @param listener the listener which should be notified | |
400 * | |
401 * @exception IllegalArgumentException <ul> | |
402 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
403 * </ul> | |
404 * @exception DWTException <ul> | |
405 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
406 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
407 * </ul> | |
408 * | |
409 * @see MouseMoveListener | |
410 * @see #removeMouseMoveListener | |
411 */ | |
412 public void addMouseMoveListener(MouseMoveListener listener) { | |
413 checkWidget(); | |
414 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
415 TypedListener typedListener = new TypedListener (listener); | |
416 addListener(DWT.MouseMove,typedListener); | |
417 } | |
418 | |
419 /** | |
420 * Adds the listener to the collection of listeners who will | |
421 * be notified when the mouse wheel is scrolled, by sending | |
422 * it one of the messages defined in the | |
423 * <code>MouseWheelListener</code> interface. | |
424 * | |
425 * @param listener the listener which should be notified | |
426 * | |
427 * @exception IllegalArgumentException <ul> | |
428 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
429 * </ul> | |
430 * @exception DWTException <ul> | |
431 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
432 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
433 * </ul> | |
434 * | |
435 * @see MouseWheelListener | |
436 * @see #removeMouseWheelListener | |
437 * | |
438 * @since 3.3 | |
439 */ | |
440 public void addMouseWheelListener (MouseWheelListener listener) { | |
441 checkWidget (); | |
442 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
443 TypedListener typedListener = new TypedListener (listener); | |
444 addListener (DWT.MouseWheel, typedListener); | |
445 } | |
446 | |
447 /** | |
448 * Adds the listener to the collection of listeners who will | |
449 * be notified when the receiver needs to be painted, by sending it | |
450 * one of the messages defined in the <code>PaintListener</code> | |
451 * interface. | |
452 * | |
453 * @param listener the listener which should be notified | |
454 * | |
455 * @exception IllegalArgumentException <ul> | |
456 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
457 * </ul> | |
458 * @exception DWTException <ul> | |
459 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
460 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
461 * </ul> | |
462 * | |
463 * @see PaintListener | |
464 * @see #removePaintListener | |
465 */ | |
466 public void addPaintListener(PaintListener listener) { | |
467 checkWidget(); | |
468 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
469 TypedListener typedListener = new TypedListener (listener); | |
470 addListener(DWT.Paint,typedListener); | |
471 } | |
472 | |
473 /** | |
474 * Adds the listener to the collection of listeners who will | |
475 * be notified when traversal events occur, by sending it | |
476 * one of the messages defined in the <code>TraverseListener</code> | |
477 * interface. | |
478 * | |
479 * @param listener the listener which should be notified | |
480 * | |
481 * @exception IllegalArgumentException <ul> | |
482 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
483 * </ul> | |
484 * @exception DWTException <ul> | |
485 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
486 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
487 * </ul> | |
488 * | |
489 * @see TraverseListener | |
490 * @see #removeTraverseListener | |
491 */ | |
492 public void addTraverseListener (TraverseListener listener) { | |
493 checkWidget(); | |
494 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
495 TypedListener typedListener = new TypedListener (listener); | |
496 addListener (DWT.Traverse,typedListener); | |
497 } | |
498 | |
499 void checkBackground () { | |
500 Shell shell = getShell (); | |
501 if (this is shell) return; | |
502 state &= ~PARENT_BACKGROUND; | |
503 Composite composite = parent; | |
504 do { | |
505 int mode = composite.backgroundMode; | |
506 if (mode !is 0) { | |
507 if (mode is DWT.INHERIT_DEFAULT) { | |
508 Control control = this; | |
509 do { | |
510 if ((control.state & THEME_BACKGROUND) is 0) { | |
511 return; | |
512 } | |
513 control = control.parent; | |
514 } while (control !is composite); | |
515 } | |
516 state |= PARENT_BACKGROUND; | |
517 return; | |
518 } | |
519 if (composite is shell) break; | |
520 composite = composite.parent; | |
521 } while (true); | |
522 } | |
523 | |
524 void checkBuffered () { | |
525 style |= DWT.DOUBLE_BUFFERED; | |
526 } | |
527 | |
528 /** | |
529 * Returns the preferred size of the receiver. | |
530 * <p> | |
531 * The <em>preferred size</em> of a control is the size that it would | |
532 * best be displayed at. The width hint and height hint arguments | |
533 * allow the caller to ask a control questions such as "Given a particular | |
534 * width, how high does the control need to be to show all of the contents?" | |
535 * To indicate that the caller does not wish to constrain a particular | |
536 * dimension, the constant <code>DWT.DEFAULT</code> is passed for the hint. | |
537 * </p> | |
538 * | |
539 * @param wHint the width hint (can be <code>DWT.DEFAULT</code>) | |
540 * @param hHint the height hint (can be <code>DWT.DEFAULT</code>) | |
541 * @return the preferred size of the control | |
542 * | |
543 * @exception DWTException <ul> | |
544 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
545 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
546 * </ul> | |
547 * | |
548 * @see Layout | |
549 * @see #getBorderWidth | |
550 * @see #getBounds | |
551 * @see #getSize | |
552 * @see #pack(bool) | |
553 * @see "computeTrim, getClientArea for controls that implement them" | |
554 */ | |
555 public Point computeSize (int wHint, int hHint) { | |
556 return computeSize (wHint, hHint, true); | |
557 } | |
558 | |
559 /** | |
560 * Returns the preferred size of the receiver. | |
561 * <p> | |
562 * The <em>preferred size</em> of a control is the size that it would | |
563 * best be displayed at. The width hint and height hint arguments | |
564 * allow the caller to ask a control questions such as "Given a particular | |
565 * width, how high does the control need to be to show all of the contents?" | |
566 * To indicate that the caller does not wish to constrain a particular | |
567 * dimension, the constant <code>DWT.DEFAULT</code> is passed for the hint. | |
568 * </p><p> | |
569 * If the changed flag is <code>true</code>, it indicates that the receiver's | |
570 * <em>contents</em> have changed, therefore any caches that a layout manager | |
571 * containing the control may have been keeping need to be flushed. When the | |
572 * control is resized, the changed flag will be <code>false</code>, so layout | |
573 * manager caches can be retained. | |
574 * </p> | |
575 * | |
576 * @param wHint the width hint (can be <code>DWT.DEFAULT</code>) | |
577 * @param hHint the height hint (can be <code>DWT.DEFAULT</code>) | |
578 * @param changed <code>true</code> if the control's contents have changed, and <code>false</code> otherwise | |
579 * @return the preferred size of the control. | |
580 * | |
581 * @exception DWTException <ul> | |
582 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
583 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
584 * </ul> | |
585 * | |
586 * @see Layout | |
587 * @see #getBorderWidth | |
588 * @see #getBounds | |
589 * @see #getSize | |
590 * @see #pack(bool) | |
591 * @see "computeTrim, getClientArea for controls that implement them" | |
592 */ | |
593 public Point computeSize (int wHint, int hHint, bool changed) { | |
594 checkWidget(); | |
595 int width = DEFAULT_WIDTH; | |
596 int height = DEFAULT_HEIGHT; | |
597 // if (wHint !is DWT.DEFAULT) width = wHint; | |
598 // if (hHint !is DWT.DEFAULT) height = hHint; | |
599 // int border = getBorderWidth (); | |
600 // width += border * 2; | |
601 // height += border * 2; | |
602 // return new Point (width, height); | |
603 if (topView() instanceof NSControl) { | |
604 NSRect oldRect = topView().frame(); | |
605 ((NSControl)topView()).sizeToFit(); | |
606 NSRect newRect = topView().frame(); | |
607 topView().setFrame (oldRect); | |
608 return new Point ((int)newRect.width, (int)newRect.height); | |
609 } | |
610 return new Point (width, height); | |
611 } | |
612 | |
613 Control computeTabGroup () { | |
614 if (isTabGroup()) return this; | |
615 return parent.computeTabGroup (); | |
616 } | |
617 | |
618 Control[] computeTabList() { | |
619 if (isTabGroup()) { | |
620 if (getVisible() && getEnabled()) { | |
621 return new Control[] {this}; | |
622 } | |
623 } | |
624 return new Control[0]; | |
625 } | |
626 | |
627 Control computeTabRoot () { | |
628 Control[] tabList = parent._getTabList(); | |
629 if (tabList !is null) { | |
630 int index = 0; | |
631 while (index < tabList.length) { | |
632 if (tabList [index] is this) break; | |
633 index++; | |
634 } | |
635 if (index is tabList.length) { | |
636 if (isTabGroup ()) return this; | |
637 } | |
638 } | |
639 return parent.computeTabRoot (); | |
640 } | |
641 | |
642 void createWidget () { | |
643 state |= DRAG_DETECT; | |
644 checkOrientation (parent); | |
645 super.createWidget (); | |
646 checkBackground (); | |
647 checkBuffered (); | |
648 setDefaultFont (); | |
649 setZOrder (); | |
650 } | |
651 | |
652 Color defaultBackground () { | |
653 return display.getSystemColor (DWT.COLOR_WIDGET_BACKGROUND); | |
654 } | |
655 | |
656 Font defaultFont () { | |
657 //TODO - Controls only, does this leak? | |
658 if (view instanceof NSControl) { | |
659 NSFont nsFont = ((NSControl)view).font (); | |
660 if (nsFont !is null) { | |
661 return Font.cocoa_new (display, nsFont); | |
662 } | |
663 } | |
664 return display.getSystemFont (); | |
665 } | |
666 | |
667 Color defaultForeground () { | |
668 return display.getSystemColor (DWT.COLOR_WIDGET_FOREGROUND); | |
669 } | |
670 | |
671 void destroyWidget () { | |
672 NSView view = topView (); | |
673 view.removeFromSuperview (); | |
674 releaseHandle (); | |
675 } | |
676 | |
677 /** | |
678 * Detects a drag and drop gesture. This method is used | |
679 * to detect a drag gesture when called from within a mouse | |
680 * down listener. | |
681 * | |
682 * <p>By default, a drag is detected when the gesture | |
683 * occurs anywhere within the client area of a control. | |
684 * Some controls, such as tables and trees, override this | |
685 * behavior. In addition to the operating system specific | |
686 * drag gesture, they require the mouse to be inside an | |
687 * item. Custom widget writers can use <code>setDragDetect</code> | |
688 * to disable the default detection, listen for mouse down, | |
689 * and then call <code>dragDetect()</code> from within the | |
690 * listener to conditionally detect a drag. | |
691 * </p> | |
692 * | |
693 * @param event the mouse down event | |
694 * | |
695 * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise. | |
696 * | |
697 * @exception IllegalArgumentException <ul> | |
698 * <li>ERROR_NULL_ARGUMENT when the event is null</li> | |
699 * </ul> | |
700 * @exception DWTException <ul> | |
701 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
702 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
703 * </ul> | |
704 * | |
705 * @see DragDetectListener | |
706 * @see #addDragDetectListener | |
707 * | |
708 * @see #getDragDetect | |
709 * @see #setDragDetect | |
710 * | |
711 * @since 3.3 | |
712 */ | |
713 public bool dragDetect (Event event) { | |
714 checkWidget (); | |
715 if (event is null) error (DWT.ERROR_NULL_ARGUMENT); | |
716 return dragDetect (event.button, event.count, event.stateMask, event.x, event.y); | |
717 } | |
718 | |
719 /** | |
720 * Detects a drag and drop gesture. This method is used | |
721 * to detect a drag gesture when called from within a mouse | |
722 * down listener. | |
723 * | |
724 * <p>By default, a drag is detected when the gesture | |
725 * occurs anywhere within the client area of a control. | |
726 * Some controls, such as tables and trees, override this | |
727 * behavior. In addition to the operating system specific | |
728 * drag gesture, they require the mouse to be inside an | |
729 * item. Custom widget writers can use <code>setDragDetect</code> | |
730 * to disable the default detection, listen for mouse down, | |
731 * and then call <code>dragDetect()</code> from within the | |
732 * listener to conditionally detect a drag. | |
733 * </p> | |
734 * | |
735 * @param event the mouse down event | |
736 * | |
737 * @return <code>true</code> if the gesture occurred, and <code>false</code> otherwise. | |
738 * | |
739 * @exception IllegalArgumentException <ul> | |
740 * <li>ERROR_NULL_ARGUMENT when the event is null</li> | |
741 * </ul> | |
742 * @exception DWTException <ul> | |
743 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
744 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
745 * </ul> | |
746 * | |
747 * @see DragDetectListener | |
748 * @see #addDragDetectListener | |
749 * | |
750 * @see #getDragDetect | |
751 * @see #setDragDetect | |
752 * | |
753 * @since 3.3 | |
754 */ | |
755 public bool dragDetect (MouseEvent event) { | |
756 checkWidget (); | |
757 if (event is null) error (DWT.ERROR_NULL_ARGUMENT); | |
758 return dragDetect (event.button, event.count, event.stateMask, event.x, event.y); | |
759 } | |
760 | |
761 bool dragDetect (int button, int count, int stateMask, int x, int y) { | |
762 if (button !is 1 || count !is 1) return false; | |
763 if (!dragDetect (x, y, false, null)) return false; | |
764 return sendDragEvent (button, stateMask, x, y); | |
765 } | |
766 | |
767 bool dragDetect (int x, int y, bool filter, bool [] consume) { | |
768 // Rect rect = new Rect (); | |
769 // int window = OS.GetControlOwner (handle); | |
770 // CGPoint pt = new CGPoint (); | |
771 // OS.HIViewConvertPoint (pt, handle, 0); | |
772 // x += (int) pt.x; | |
773 // y += (int) pt.y; | |
774 // OS.GetWindowBounds (window, (short) OS.kWindowStructureRgn, rect); | |
775 // x += rect.left; | |
776 // y += rect.top; | |
777 // dwt.internal.carbon.Point pt1 = new dwt.internal.carbon.Point (); | |
778 // pt1.h = (short) x; | |
779 // pt1.v = (short) y; | |
780 // return OS.WaitMouseMoved (pt1); | |
781 return false; | |
782 } | |
783 | |
784 bool drawGripper (int x, int y, int width, int height, bool vertical) { | |
785 return false; | |
786 } | |
787 | |
788 void drawRect(int id, NSRect rect) { | |
789 super.drawRect(id, rect); | |
790 if (!hooks (DWT.Paint) && !filters (DWT.Paint)) return; | |
791 | |
792 /* Send paint event */ | |
793 GCData data = new GCData (); | |
794 data.paintRect = rect; | |
795 GC gc = GC.cocoa_new (this, data); | |
796 Event event = new Event (); | |
797 event.gc = gc; | |
798 event.x = (int)rect.x; | |
799 event.y = (int)rect.y; | |
800 event.width = (int)rect.width; | |
801 event.height = (int)rect.height; | |
802 sendEvent (DWT.Paint, event); | |
803 event.gc = null; | |
804 gc.dispose (); | |
805 } | |
806 | |
807 void enableWidget (bool enabled) { | |
808 //TODO - other views | |
809 if (view instanceof NSControl) { | |
810 ((NSControl)view).setEnabled(enabled); | |
811 } | |
812 } | |
813 | |
814 Cursor findCursor () { | |
815 if (cursor !is null) return cursor; | |
816 return parent.findCursor (); | |
817 } | |
818 | |
819 Control findBackgroundControl () { | |
820 if (backgroundImage !is null || background !is null) return this; | |
821 return (state & PARENT_BACKGROUND) !is 0 ? parent.findBackgroundControl () : null; | |
822 } | |
823 | |
824 Menu [] findMenus (Control control) { | |
825 if (menu !is null && this !is control) return new Menu [] {menu}; | |
826 return new Menu [0]; | |
827 } | |
828 | |
829 void fixChildren (Shell newShell, Shell oldShell, Decorations newDecorations, Decorations oldDecorations, Menu [] menus) { | |
830 oldShell.fixShell (newShell, this); | |
831 oldDecorations.fixDecorations (newDecorations, this, menus); | |
832 } | |
833 | |
834 void fixFocus (Control focusControl) { | |
835 Shell shell = getShell (); | |
836 Control control = this; | |
837 while (control !is shell && (control = control.parent) !is null) { | |
838 if (control.setFocus ()) return; | |
839 } | |
840 shell.setSavedFocus (focusControl); | |
841 // int window = OS.GetControlOwner (handle); | |
842 // OS.ClearKeyboardFocus (window); | |
843 } | |
844 | |
845 /** | |
846 * Forces the receiver to have the <em>keyboard focus</em>, causing | |
847 * all keyboard events to be delivered to it. | |
848 * | |
849 * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. | |
850 * | |
851 * @exception DWTException <ul> | |
852 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
853 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
854 * </ul> | |
855 * | |
856 * @see #setFocus | |
857 */ | |
858 public bool forceFocus () { | |
859 checkWidget(); | |
860 // if (display.focusEvent is DWT.FocusOut) return false; | |
861 Decorations shell = menuShell (); | |
862 shell.setSavedFocus (this); | |
863 if (!isEnabled () || !isVisible ()/* || !isActive ()*/) return false; | |
864 if (isFocusControl ()) return true; | |
865 shell.setSavedFocus (null); | |
866 shell.bringToTop (false); | |
867 if (isDisposed ()) return false; | |
868 view.window ().makeFirstResponder (view); | |
869 if (isDisposed ()) return false; | |
870 shell.setSavedFocus (this); | |
871 return hasFocus (); | |
872 } | |
873 | |
874 /** | |
875 * Returns the accessible object for the receiver. | |
876 * If this is the first time this object is requested, | |
877 * then the object is created and returned. | |
878 * | |
879 * @return the accessible object | |
880 * | |
881 * @exception DWTException <ul> | |
882 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
883 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
884 * </ul> | |
885 * | |
886 * @see Accessible#addAccessibleListener | |
887 * @see Accessible#addAccessibleControlListener | |
888 * | |
889 * @since 2.0 | |
890 */ | |
891 public Accessible getAccessible () { | |
892 checkWidget (); | |
893 if (accessible is null) accessible = new_Accessible (this); | |
894 return accessible; | |
895 } | |
896 | |
897 /** | |
898 * Returns the receiver's background color. | |
899 * | |
900 * @return the background color | |
901 * | |
902 * @exception DWTException <ul> | |
903 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
904 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
905 * </ul> | |
906 */ | |
907 public Color getBackground () { | |
908 checkWidget(); | |
909 Control control = findBackgroundControl (); | |
910 if (control is null) control = this; | |
911 return control.getBackgroundColor (); | |
912 } | |
913 | |
914 Color getBackgroundColor () { | |
915 return background !is null ? background : defaultBackground (); | |
916 } | |
917 | |
918 /** | |
919 * Returns the receiver's background image. | |
920 * | |
921 * @return the background image | |
922 * | |
923 * @exception DWTException <ul> | |
924 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
925 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
926 * </ul> | |
927 * | |
928 * @since 3.2 | |
929 */ | |
930 public Image getBackgroundImage () { | |
931 checkWidget(); | |
932 Control control = findBackgroundControl (); | |
933 if (control is null) control = this; | |
934 return control.backgroundImage; | |
935 } | |
936 | |
937 /** | |
938 * Returns the receiver's border width. | |
939 * | |
940 * @return the border width | |
941 * | |
942 * @exception DWTException <ul> | |
943 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
944 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
945 * </ul> | |
946 */ | |
947 public int getBorderWidth () { | |
948 checkWidget(); | |
949 return 0; | |
950 } | |
951 | |
952 /** | |
953 * Returns a rectangle describing the receiver's size and location | |
954 * relative to its parent (or its display if its parent is null), | |
955 * unless the receiver is a shell. In this case, the location is | |
956 * relative to the display. | |
957 * | |
958 * @return the receiver's bounding rectangle | |
959 * | |
960 * @exception DWTException <ul> | |
961 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
962 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
963 * </ul> | |
964 */ | |
965 public Rectangle getBounds () { | |
966 checkWidget(); | |
967 NSRect rect = topView().frame(); | |
968 return new Rectangle((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height); | |
969 } | |
970 | |
971 /** | |
972 * Returns <code>true</code> if the receiver is detecting | |
973 * drag gestures, and <code>false</code> otherwise. | |
974 * | |
975 * @return the receiver's drag detect state | |
976 * | |
977 * @exception DWTException <ul> | |
978 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
979 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
980 * </ul> | |
981 * | |
982 * @since 3.3 | |
983 */ | |
984 public bool getDragDetect () { | |
985 checkWidget (); | |
986 return (state & DRAG_DETECT) !is 0; | |
987 } | |
988 | |
989 /** | |
990 * Returns the receiver's cursor, or null if it has not been set. | |
991 * <p> | |
992 * When the mouse pointer passes over a control its appearance | |
993 * is changed to match the control's cursor. | |
994 * </p> | |
995 * </ul> | |
996 * @exception DWTException <ul> | |
997 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
998 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
999 * </ul> | |
1000 * | |
1001 * @since 3.3 | |
1002 */ | |
1003 public Cursor getCursor () { | |
1004 checkWidget(); | |
1005 return cursor; | |
1006 } | |
1007 | |
1008 /** | |
1009 * Returns <code>true</code> if the receiver is enabled, and | |
1010 * <code>false</code> otherwise. A disabled control is typically | |
1011 * not selectable from the user interface and draws with an | |
1012 * inactive or "grayed" look. | |
1013 * | |
1014 * @return the receiver's enabled state | |
1015 * | |
1016 * @exception DWTException <ul> | |
1017 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1018 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1019 * </ul> | |
1020 * | |
1021 * @see #isEnabled | |
1022 */ | |
1023 public bool getEnabled () { | |
1024 checkWidget(); | |
1025 return (state & DISABLED) is 0; | |
1026 } | |
1027 | |
1028 /** | |
1029 * Returns the font that the receiver will use to paint textual information. | |
1030 * | |
1031 * @return the receiver's font | |
1032 * | |
1033 * @exception DWTException <ul> | |
1034 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1035 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1036 * </ul> | |
1037 */ | |
1038 public Font getFont () { | |
1039 checkWidget(); | |
1040 return font !is null ? font : defaultFont (); | |
1041 } | |
1042 | |
1043 /** | |
1044 * Returns the foreground color that the receiver will use to draw. | |
1045 * | |
1046 * @return the receiver's foreground color | |
1047 * | |
1048 * @exception DWTException <ul> | |
1049 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1050 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1051 * </ul> | |
1052 */ | |
1053 public Color getForeground () { | |
1054 checkWidget(); | |
1055 return getForegroundColor (); | |
1056 } | |
1057 | |
1058 Color getForegroundColor () { | |
1059 return foreground !is null ? foreground: defaultForeground (); | |
1060 } | |
1061 | |
1062 /** | |
1063 * Returns layout data which is associated with the receiver. | |
1064 * | |
1065 * @return the receiver's layout data | |
1066 * | |
1067 * @exception DWTException <ul> | |
1068 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1069 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1070 * </ul> | |
1071 */ | |
1072 public Object getLayoutData () { | |
1073 checkWidget(); | |
1074 return layoutData; | |
1075 } | |
1076 | |
1077 /** | |
1078 * Returns a point describing the receiver's location relative | |
1079 * to its parent (or its display if its parent is null), unless | |
1080 * the receiver is a shell. In this case, the point is | |
1081 * relative to the display. | |
1082 * | |
1083 * @return the receiver's location | |
1084 * | |
1085 * @exception DWTException <ul> | |
1086 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1087 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1088 * </ul> | |
1089 */ | |
1090 public Point getLocation () { | |
1091 checkWidget(); | |
1092 NSRect rect = topView().frame(); | |
1093 return new Point((int)rect.x, (int)rect.y); | |
1094 } | |
1095 | |
1096 /** | |
1097 * Returns the receiver's pop up menu if it has one, or null | |
1098 * if it does not. All controls may optionally have a pop up | |
1099 * menu that is displayed when the user requests one for | |
1100 * the control. The sequence of key strokes, button presses | |
1101 * and/or button releases that are used to request a pop up | |
1102 * menu is platform specific. | |
1103 * | |
1104 * @return the receiver's menu | |
1105 * | |
1106 * @exception DWTException <ul> | |
1107 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1108 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1109 * </ul> | |
1110 */ | |
1111 public Menu getMenu () { | |
1112 checkWidget(); | |
1113 return menu; | |
1114 } | |
1115 | |
1116 int getMininumHeight () { | |
1117 return 0; | |
1118 } | |
1119 | |
1120 /** | |
1121 * Returns the receiver's monitor. | |
1122 * | |
1123 * @return the receiver's monitor | |
1124 * | |
1125 * @since 3.0 | |
1126 */ | |
1127 public Monitor getMonitor () { | |
1128 checkWidget(); | |
1129 Monitor [] monitors = display.getMonitors (); | |
1130 if (monitors.length is 1) return monitors [0]; | |
1131 int index = -1, value = -1; | |
1132 Rectangle bounds = getBounds (); | |
1133 if (this !is getShell ()) { | |
1134 bounds = display.map (this.parent, null, bounds); | |
1135 } | |
1136 for (int i=0; i<monitors.length; i++) { | |
1137 Rectangle rect = bounds.intersection (monitors [i].getBounds ()); | |
1138 int area = rect.width * rect.height; | |
1139 if (area > 0 && area > value) { | |
1140 index = i; | |
1141 value = area; | |
1142 } | |
1143 } | |
1144 if (index >= 0) return monitors [index]; | |
1145 int centerX = bounds.x + bounds.width / 2, centerY = bounds.y + bounds.height / 2; | |
1146 for (int i=0; i<monitors.length; i++) { | |
1147 Rectangle rect = monitors [i].getBounds (); | |
1148 int x = centerX < rect.x ? rect.x - centerX : centerX > rect.x + rect.width ? centerX - rect.x - rect.width : 0; | |
1149 int y = centerY < rect.y ? rect.y - centerY : centerY > rect.y + rect.height ? centerY - rect.y - rect.height : 0; | |
1150 int distance = x * x + y * y; | |
1151 if (index is -1 || distance < value) { | |
1152 index = i; | |
1153 value = distance; | |
1154 } | |
1155 } | |
1156 return monitors [index]; | |
1157 } | |
1158 | |
1159 /** | |
1160 * Returns the receiver's parent, which must be a <code>Composite</code> | |
1161 * or null when the receiver is a shell that was created with null or | |
1162 * a display for a parent. | |
1163 * | |
1164 * @return the receiver's parent | |
1165 * | |
1166 * @exception DWTException <ul> | |
1167 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1168 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1169 * </ul> | |
1170 */ | |
1171 public Composite getParent () { | |
1172 checkWidget(); | |
1173 return parent; | |
1174 } | |
1175 | |
1176 Control [] getPath () { | |
1177 int count = 0; | |
1178 Shell shell = getShell (); | |
1179 Control control = this; | |
1180 while (control !is shell) { | |
1181 count++; | |
1182 control = control.parent; | |
1183 } | |
1184 control = this; | |
1185 Control [] result = new Control [count]; | |
1186 while (control !is shell) { | |
1187 result [--count] = control; | |
1188 control = control.parent; | |
1189 } | |
1190 return result; | |
1191 } | |
1192 | |
1193 public Region getRegion () { | |
1194 checkWidget (); | |
1195 return region; | |
1196 } | |
1197 | |
1198 /** | |
1199 * Returns the receiver's shell. For all controls other than | |
1200 * shells, this simply returns the control's nearest ancestor | |
1201 * shell. Shells return themselves, even if they are children | |
1202 * of other shells. | |
1203 * | |
1204 * @return the receiver's shell | |
1205 * | |
1206 * @exception DWTException <ul> | |
1207 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1208 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1209 * </ul> | |
1210 * | |
1211 * @see #getParent | |
1212 */ | |
1213 public Shell getShell () { | |
1214 checkWidget(); | |
1215 return parent.getShell (); | |
1216 } | |
1217 | |
1218 /** | |
1219 * Returns a point describing the receiver's size. The | |
1220 * x coordinate of the result is the width of the receiver. | |
1221 * The y coordinate of the result is the height of the | |
1222 * receiver. | |
1223 * | |
1224 * @return the receiver's size | |
1225 * | |
1226 * @exception DWTException <ul> | |
1227 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1228 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1229 * </ul> | |
1230 */ | |
1231 public Point getSize () { | |
1232 checkWidget(); | |
1233 NSRect rect = topView().frame(); | |
1234 return new Point((int)rect.width, (int)rect.height); | |
1235 } | |
1236 | |
1237 /** | |
1238 * Returns the receiver's tool tip text, or null if it has | |
1239 * not been set. | |
1240 * | |
1241 * @return the receiver's tool tip text | |
1242 * | |
1243 * @exception DWTException <ul> | |
1244 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1245 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1246 * </ul> | |
1247 */ | |
1248 public String getToolTipText () { | |
1249 checkWidget(); | |
1250 return toolTipText; | |
1251 } | |
1252 | |
1253 /** | |
1254 * Returns <code>true</code> if the receiver is visible, and | |
1255 * <code>false</code> otherwise. | |
1256 * <p> | |
1257 * If one of the receiver's ancestors is not visible or some | |
1258 * other condition makes the receiver not visible, this method | |
1259 * may still indicate that it is considered visible even though | |
1260 * it may not actually be showing. | |
1261 * </p> | |
1262 * | |
1263 * @return the receiver's visibility state | |
1264 * | |
1265 * @exception DWTException <ul> | |
1266 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1267 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1268 * </ul> | |
1269 */ | |
1270 public bool getVisible () { | |
1271 checkWidget(); | |
1272 return (state & HIDDEN) is 0; | |
1273 } | |
1274 | |
1275 bool hasBorder () { | |
1276 return (style & DWT.BORDER) !is 0; | |
1277 } | |
1278 | |
1279 bool hasFocus () { | |
1280 return this is display.getFocusControl (); | |
1281 } | |
1282 | |
1283 /** | |
1284 * Invokes platform specific functionality to allocate a new GC handle. | |
1285 * <p> | |
1286 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
1287 * API for <code>Control</code>. It is marked public only so that it | |
1288 * can be shared within the packages provided by DWT. It is not | |
1289 * available on all platforms, and should never be called from | |
1290 * application code. | |
1291 * </p> | |
1292 * | |
1293 * @param data the platform specific GC data | |
1294 * @return the platform specific GC handle | |
1295 */ | |
1296 public int internal_new_GC (GCData data) { | |
1297 checkWidget(); | |
1298 int context = 0; | |
1299 if (data !is null && data.paintRect !is null) { | |
1300 context = NSGraphicsContext.currentContext().id; | |
1301 } else { | |
1302 context = NSGraphicsContext.graphicsContextWithWindow(view.window()).id; | |
1303 } | |
1304 if (data !is null) { | |
1305 int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; | |
1306 if ((data.style & mask) is 0) { | |
1307 data.style |= style & (mask | DWT.MIRRORED); | |
1308 } | |
1309 data.device = display; | |
1310 data.view = view; | |
1311 data.foreground = getForegroundColor ().handle; | |
1312 Control control = findBackgroundControl (); | |
1313 if (control is null) control = this; | |
1314 data.background = control.getBackgroundColor ().handle; | |
1315 data.font = font !is null ? font : defaultFont (); | |
1316 } | |
1317 return context; | |
1318 } | |
1319 | |
1320 /** | |
1321 * Invokes platform specific functionality to dispose a GC handle. | |
1322 * <p> | |
1323 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
1324 * API for <code>Control</code>. It is marked public only so that it | |
1325 * can be shared within the packages provided by DWT. It is not | |
1326 * available on all platforms, and should never be called from | |
1327 * application code. | |
1328 * </p> | |
1329 * | |
1330 * @param hDC the platform specific GC handle | |
1331 * @param data the platform specific GC data | |
1332 */ | |
1333 public void internal_dispose_GC (int context, GCData data) { | |
1334 checkWidget (); | |
1335 } | |
1336 | |
1337 /** | |
1338 * Returns <code>true</code> if the receiver is enabled and all | |
1339 * ancestors up to and including the receiver's nearest ancestor | |
1340 * shell are enabled. Otherwise, <code>false</code> is returned. | |
1341 * A disabled control is typically not selectable from the user | |
1342 * interface and draws with an inactive or "grayed" look. | |
1343 * | |
1344 * @return the receiver's enabled state | |
1345 * | |
1346 * @exception DWTException <ul> | |
1347 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1348 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1349 * </ul> | |
1350 * | |
1351 * @see #getEnabled | |
1352 */ | |
1353 public bool isEnabled () { | |
1354 checkWidget(); | |
1355 return getEnabled () && parent.isEnabled (); | |
1356 } | |
1357 | |
1358 bool isEnabledCursor () { | |
1359 return isEnabled (); | |
1360 } | |
1361 | |
1362 bool isFocusAncestor (Control control) { | |
1363 while (control !is null && control !is this && !(control instanceof Shell)) { | |
1364 control = control.parent; | |
1365 } | |
1366 return control is this; | |
1367 } | |
1368 | |
1369 /** | |
1370 * Returns <code>true</code> if the receiver has the user-interface | |
1371 * focus, and <code>false</code> otherwise. | |
1372 * | |
1373 * @return the receiver's focus state | |
1374 * | |
1375 * @exception DWTException <ul> | |
1376 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1377 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1378 * </ul> | |
1379 */ | |
1380 public bool isFocusControl () { | |
1381 checkWidget(); | |
1382 // Control focusControl = display.focusControl; | |
1383 // if (focusControl !is null && !focusControl.isDisposed ()) { | |
1384 // return this is focusControl; | |
1385 // } | |
1386 return hasFocus (); | |
1387 } | |
1388 | |
1389 /** | |
1390 * Returns <code>true</code> if the underlying operating | |
1391 * system supports this reparenting, otherwise <code>false</code> | |
1392 * | |
1393 * @return <code>true</code> if the widget can be reparented, otherwise <code>false</code> | |
1394 * | |
1395 * @exception DWTException <ul> | |
1396 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1397 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1398 * </ul> | |
1399 */ | |
1400 public bool isReparentable () { | |
1401 checkWidget(); | |
1402 return true; | |
1403 } | |
1404 | |
1405 bool isShowing () { | |
1406 /* | |
1407 * This is not complete. Need to check if the | |
1408 * widget is obscurred by a parent or sibling. | |
1409 */ | |
1410 if (!isVisible ()) return false; | |
1411 Control control = this; | |
1412 while (control !is null) { | |
1413 Point size = control.getSize (); | |
1414 if (size.x is 0 || size.y is 0) { | |
1415 return false; | |
1416 } | |
1417 control = control.parent; | |
1418 } | |
1419 return true; | |
1420 } | |
1421 | |
1422 bool isTabGroup () { | |
1423 Control [] tabList = parent._getTabList (); | |
1424 if (tabList !is null) { | |
1425 for (int i=0; i<tabList.length; i++) { | |
1426 if (tabList [i] is this) return true; | |
1427 } | |
1428 } | |
1429 int code = traversalCode (0, null); | |
1430 if ((code & (DWT.TRAVERSE_ARROW_PREVIOUS | DWT.TRAVERSE_ARROW_NEXT)) !is 0) return false; | |
1431 return (code & (DWT.TRAVERSE_TAB_PREVIOUS | DWT.TRAVERSE_TAB_NEXT)) !is 0; | |
1432 } | |
1433 | |
1434 bool isTabItem () { | |
1435 Control [] tabList = parent._getTabList (); | |
1436 if (tabList !is null) { | |
1437 for (int i=0; i<tabList.length; i++) { | |
1438 if (tabList [i] is this) return false; | |
1439 } | |
1440 } | |
1441 int code = traversalCode (0, null); | |
1442 return (code & (DWT.TRAVERSE_ARROW_PREVIOUS | DWT.TRAVERSE_ARROW_NEXT)) !is 0; | |
1443 } | |
1444 | |
1445 /** | |
1446 * Returns <code>true</code> if the receiver is visible and all | |
1447 * ancestors up to and including the receiver's nearest ancestor | |
1448 * shell are visible. Otherwise, <code>false</code> is returned. | |
1449 * | |
1450 * @return the receiver's visibility state | |
1451 * | |
1452 * @exception DWTException <ul> | |
1453 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1454 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1455 * </ul> | |
1456 * | |
1457 * @see #getVisible | |
1458 */ | |
1459 public bool isVisible () { | |
1460 checkWidget(); | |
1461 return getVisible () && parent.isVisible (); | |
1462 } | |
1463 | |
1464 int menuForEvent (int nsEvent) { | |
1465 NSPoint pt = NSEvent.mouseLocation(); | |
1466 NSWindow window = view.window(); | |
1467 pt.y = (int) (window.screen().frame().height - pt.y); | |
1468 int x = (int) pt.x; | |
1469 int y = (int) pt.y; | |
1470 Event event = new Event (); | |
1471 event.x = x; | |
1472 event.y = y; | |
1473 sendEvent (DWT.MenuDetect, event); | |
1474 if (!event.doit) return 0; | |
1475 Menu menu = getMenu (); | |
1476 if (menu !is null && !menu.isDisposed ()) { | |
1477 if (x !is event.x || y !is event.y) { | |
1478 menu.setLocation (event.x, event.y); | |
1479 } | |
1480 return menu.nsMenu.id; | |
1481 } | |
1482 objc_super super_struct = new objc_super(); | |
1483 super_struct.receiver = view.id; | |
1484 super_struct.cls = OS.objc_msgSend(view.id, OS.sel_superclass); | |
1485 return OS.objc_msgSendSuper(super_struct, OS.sel_menuForEvent_1, nsEvent); | |
1486 } | |
1487 | |
1488 Decorations menuShell () { | |
1489 return parent.menuShell (); | |
1490 } | |
1491 | |
1492 bool setInputState (Event event, NSEvent nsEvent, int type) { | |
1493 int modifierFlags = nsEvent.modifierFlags(); | |
1494 if ((modifierFlags & OS.NSAlternateKeyMask) !is 0) event.stateMask |= DWT.ALT; | |
1495 if ((modifierFlags & OS.NSShiftKeyMask) !is 0) event.stateMask |= DWT.SHIFT; | |
1496 if ((modifierFlags & OS.NSControlKeyMask) !is 0) event.stateMask |= DWT.CONTROL; | |
1497 if ((modifierFlags & OS.NSCommandKeyMask) !is 0) event.stateMask |= DWT.COMMAND; | |
1498 | |
1499 //WRONG | |
1500 if ((modifierFlags & OS.NSLeftMouseDownMask) !is 0) event.stateMask |= DWT.BUTTON1; | |
1501 if ((modifierFlags & OS.NSLeftMouseDraggedMask) !is 0) event.stateMask |= DWT.BUTTON1; | |
1502 if ((modifierFlags & OS.NSLeftMouseUpMask) !is 0) event.stateMask |= DWT.BUTTON1; | |
1503 if ((modifierFlags & OS.NSOtherMouseDownMask) !is 0) event.stateMask |= DWT.BUTTON2; | |
1504 if ((modifierFlags & OS.NSOtherMouseDraggedMask) !is 0) event.stateMask |= DWT.BUTTON2; | |
1505 if ((modifierFlags & OS.NSOtherMouseUpMask) !is 0) event.stateMask |= DWT.BUTTON1; | |
1506 if ((modifierFlags & OS.NSRightMouseDownMask) !is 0) event.stateMask |= DWT.BUTTON3; | |
1507 if ((modifierFlags & OS.NSRightMouseDraggedMask) !is 0) event.stateMask |= DWT.BUTTON3; | |
1508 if ((modifierFlags & OS.NSRightMouseUpMask) !is 0) event.stateMask |= DWT.BUTTON3; | |
1509 | |
1510 // if (OS.GetKeyState (OS.VK_XBUTTON1) < 0) event.stateMask |= DWT.BUTTON4; | |
1511 // if (OS.GetKeyState (OS.VK_XBUTTON2) < 0) event.stateMask |= DWT.BUTTON5; | |
1512 // switch (type) { | |
1513 // case DWT.MouseDown: | |
1514 // case DWT.MouseDoubleClick: | |
1515 // if (event.button is 1) event.stateMask &= ~DWT.BUTTON1; | |
1516 // if (event.button is 2) event.stateMask &= ~DWT.BUTTON2; | |
1517 // if (event.button is 3) event.stateMask &= ~DWT.BUTTON3; | |
1518 // if (event.button is 4) event.stateMask &= ~DWT.BUTTON4; | |
1519 // if (event.button is 5) event.stateMask &= ~DWT.BUTTON5; | |
1520 // break; | |
1521 // case DWT.MouseUp: | |
1522 // if (event.button is 1) event.stateMask |= DWT.BUTTON1; | |
1523 // if (event.button is 2) event.stateMask |= DWT.BUTTON2; | |
1524 // if (event.button is 3) event.stateMask |= DWT.BUTTON3; | |
1525 // if (event.button is 4) event.stateMask |= DWT.BUTTON4; | |
1526 // if (event.button is 5) event.stateMask |= DWT.BUTTON5; | |
1527 // break; | |
1528 // case DWT.KeyDown: | |
1529 // case DWT.Traverse: | |
1530 // if (event.keyCode is DWT.ALT) event.stateMask &= ~DWT.ALT; | |
1531 // if (event.keyCode is DWT.SHIFT) event.stateMask &= ~DWT.SHIFT; | |
1532 // if (event.keyCode is DWT.CONTROL) event.stateMask &= ~DWT.CONTROL; | |
1533 // break; | |
1534 // case DWT.KeyUp: | |
1535 // if (event.keyCode is DWT.ALT) event.stateMask |= DWT.ALT; | |
1536 // if (event.keyCode is DWT.SHIFT) event.stateMask |= DWT.SHIFT; | |
1537 // if (event.keyCode is DWT.CONTROL) event.stateMask |= DWT.CONTROL; | |
1538 // break; | |
1539 // } | |
1540 return true; | |
1541 } | |
1542 | |
1543 void sendMouseEvent (NSEvent nsEvent, int type, int button) { | |
1544 Event event = new Event (); | |
1545 event.button = button; | |
1546 // event.detail = detail; | |
1547 event.count = nsEvent.clickCount(); | |
1548 NSPoint location = nsEvent.locationInWindow(); | |
1549 NSPoint point = view.convertPoint_fromView_(location, null); | |
1550 event.x = (int) point.x; | |
1551 event.y = (int) point.y; | |
1552 setInputState (event, nsEvent, type); | |
1553 sendEvent (type, event); | |
1554 } | |
1555 | |
1556 void mouseDown(int theEvent) { | |
1557 NSEvent nsEvent = new NSEvent (theEvent); | |
1558 sendMouseEvent (nsEvent, DWT.MouseDown, 1); | |
1559 } | |
1560 | |
1561 void mouseDragged(int theEvent) { | |
1562 NSEvent nsEvent = new NSEvent (theEvent); | |
1563 sendMouseEvent (nsEvent, DWT.MouseMove, 1); | |
1564 } | |
1565 | |
1566 void mouseUp(int theEvent) { | |
1567 NSEvent nsEvent = new NSEvent (theEvent); | |
1568 sendMouseEvent (nsEvent, DWT.MouseUp, 1); | |
1569 } | |
1570 | |
1571 bool sendKeyEvent (Event event) { | |
1572 sendEvent (event); | |
1573 return event.doit; | |
1574 } | |
1575 | |
1576 //TODO - missing modifier keys (see flagsChanged:) | |
1577 bool sendKeyEvent (NSEvent nsEvent, int type) { | |
1578 if ((state & SAFARI_EVENTS_FIX) !is 0) return false; | |
1579 int count = 0; | |
1580 NSString keys = nsEvent.characters(); | |
1581 //TODO - check lowercase doesn't mangle char codes | |
1582 NSString keyCodes = nsEvent.charactersIgnoringModifiers().lowercaseString(); | |
1583 char [] chars = new char [keys.length()]; | |
1584 for (int i=0; i<keys.length(); i++) { | |
1585 Event event = new Event (); | |
1586 int keyCode = Display.translateKey (keys.characterAtIndex (i) & 0xFFFF); | |
1587 if (keyCode !is 0) { | |
1588 event.keyCode = keyCode; | |
1589 } else { | |
1590 event.character = (char) keys.characterAtIndex (i); | |
1591 //TODO - get unshifted values for Shift+1 | |
1592 event.keyCode = keyCodes.characterAtIndex (i); | |
1593 } | |
1594 setInputState (event, nsEvent, type); | |
1595 if (!setKeyState(event, type, nsEvent)) return false; | |
1596 if (sendKeyEvent (type, event)) { | |
1597 chars [count++] = chars [i]; | |
1598 } | |
1599 } | |
1600 // if (count is 0) return false; | |
1601 if (count !is keys.length () - 1) { | |
1602 // OS.SetEventParameter (theEvent, OS.kEventParamKeyUnicodes, OS.typeUnicodeText, count * 2, chars); | |
1603 } | |
1604 return count is keys.length (); | |
1605 } | |
1606 | |
1607 void markLayout (bool changed, bool all) { | |
1608 /* Do nothing */ | |
1609 } | |
1610 | |
1611 /** | |
1612 * Moves the receiver above the specified control in the | |
1613 * drawing order. If the argument is null, then the receiver | |
1614 * is moved to the top of the drawing order. The control at | |
1615 * the top of the drawing order will not be covered by other | |
1616 * controls even if they occupy intersecting areas. | |
1617 * | |
1618 * @param control the sibling control (or null) | |
1619 * | |
1620 * @exception IllegalArgumentException <ul> | |
1621 * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> | |
1622 * </ul> | |
1623 * @exception DWTException <ul> | |
1624 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1625 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1626 * </ul> | |
1627 * | |
1628 * @see Control#moveBelow | |
1629 * @see Composite#getChildren | |
1630 */ | |
1631 public void moveAbove (Control control) { | |
1632 checkWidget(); | |
1633 if (control !is null) { | |
1634 if (control.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); | |
1635 if (parent !is control.parent) return; | |
1636 } | |
1637 setZOrder (control, true); | |
1638 } | |
1639 | |
1640 /** | |
1641 * Moves the receiver below the specified control in the | |
1642 * drawing order. If the argument is null, then the receiver | |
1643 * is moved to the bottom of the drawing order. The control at | |
1644 * the bottom of the drawing order will be covered by all other | |
1645 * controls which occupy intersecting areas. | |
1646 * | |
1647 * @param control the sibling control (or null) | |
1648 * | |
1649 * @exception IllegalArgumentException <ul> | |
1650 * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> | |
1651 * </ul> | |
1652 * @exception DWTException <ul> | |
1653 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1654 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1655 * </ul> | |
1656 * | |
1657 * @see Control#moveAbove | |
1658 * @see Composite#getChildren | |
1659 */ | |
1660 public void moveBelow (Control control) { | |
1661 checkWidget(); | |
1662 if (control !is null) { | |
1663 if (control.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); | |
1664 if (parent !is control.parent) return; | |
1665 } | |
1666 setZOrder (control, false); | |
1667 } | |
1668 | |
1669 Accessible new_Accessible (Control control) { | |
1670 return Accessible.internal_new_Accessible (this); | |
1671 } | |
1672 | |
1673 /** | |
1674 * Causes the receiver to be resized to its preferred size. | |
1675 * For a composite, this involves computing the preferred size | |
1676 * from its layout, if there is one. | |
1677 * | |
1678 * @exception DWTException <ul> | |
1679 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1680 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1681 * </ul> | |
1682 * | |
1683 * @see #computeSize(int, int, bool) | |
1684 */ | |
1685 public void pack () { | |
1686 checkWidget(); | |
1687 pack (true); | |
1688 } | |
1689 | |
1690 /** | |
1691 * Causes the receiver to be resized to its preferred size. | |
1692 * For a composite, this involves computing the preferred size | |
1693 * from its layout, if there is one. | |
1694 * <p> | |
1695 * If the changed flag is <code>true</code>, it indicates that the receiver's | |
1696 * <em>contents</em> have changed, therefore any caches that a layout manager | |
1697 * containing the control may have been keeping need to be flushed. When the | |
1698 * control is resized, the changed flag will be <code>false</code>, so layout | |
1699 * manager caches can be retained. | |
1700 * </p> | |
1701 * | |
1702 * @param changed whether or not the receiver's contents have changed | |
1703 * | |
1704 * @exception DWTException <ul> | |
1705 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1706 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1707 * </ul> | |
1708 * | |
1709 * @see #computeSize(int, int, bool) | |
1710 */ | |
1711 public void pack (bool changed) { | |
1712 checkWidget(); | |
1713 setSize (computeSize (DWT.DEFAULT, DWT.DEFAULT, changed)); | |
1714 } | |
1715 | |
1716 public bool print (GC gc) { | |
1717 checkWidget (); | |
1718 if (gc is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1719 if (gc.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); | |
1720 // int [] outImage = new int [1]; | |
1721 // CGRect outFrame = new CGRect (); | |
1722 // if (OS.HIViewCreateOffscreenImage (handle, 0, outFrame, outImage) is OS.noErr) { | |
1723 // int width = OS.CGImageGetWidth (outImage [0]); | |
1724 // int height = OS.CGImageGetHeight (outImage [0]); | |
1725 // CGRect rect = new CGRect(); | |
1726 // rect.width = width; | |
1727 // rect.height = height; | |
1728 // //TODO - does not draw the browser (cocoa widgets?) | |
1729 // OS.HIViewDrawCGImage (gc.handle, rect, outImage [0]); | |
1730 // OS.CGImageRelease (outImage [0]); | |
1731 // } | |
1732 // return true; | |
1733 return false; | |
1734 } | |
1735 | |
1736 /** | |
1737 * Causes the entire bounds of the receiver to be marked | |
1738 * as needing to be redrawn. The next time a paint request | |
1739 * is processed, the control will be completely painted, | |
1740 * including the background. | |
1741 * | |
1742 * @exception DWTException <ul> | |
1743 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1744 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1745 * </ul> | |
1746 * | |
1747 * @see #update() | |
1748 * @see PaintListener | |
1749 * @see DWT#Paint | |
1750 * @see DWT#NO_BACKGROUND | |
1751 * @see DWT#NO_REDRAW_RESIZE | |
1752 * @see DWT#NO_MERGE_PAINTS | |
1753 * @see DWT#DOUBLE_BUFFERED | |
1754 */ | |
1755 public void redraw () { | |
1756 checkWidget(); | |
1757 view.setNeedsDisplay(true); | |
1758 } | |
1759 | |
1760 void redraw (bool children) { | |
1761 // checkWidget(); | |
1762 | |
1763 } | |
1764 | |
1765 /** | |
1766 * Causes the rectangular area of the receiver specified by | |
1767 * the arguments to be marked as needing to be redrawn. | |
1768 * The next time a paint request is processed, that area of | |
1769 * the receiver will be painted, including the background. | |
1770 * If the <code>all</code> flag is <code>true</code>, any | |
1771 * children of the receiver which intersect with the specified | |
1772 * area will also paint their intersecting areas. If the | |
1773 * <code>all</code> flag is <code>false</code>, the children | |
1774 * will not be painted. | |
1775 * | |
1776 * @param x the x coordinate of the area to draw | |
1777 * @param y the y coordinate of the area to draw | |
1778 * @param width the width of the area to draw | |
1779 * @param height the height of the area to draw | |
1780 * @param all <code>true</code> if children should redraw, and <code>false</code> otherwise | |
1781 * | |
1782 * @exception DWTException <ul> | |
1783 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1784 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1785 * </ul> | |
1786 * | |
1787 * @see #update() | |
1788 * @see PaintListener | |
1789 * @see DWT#Paint | |
1790 * @see DWT#NO_BACKGROUND | |
1791 * @see DWT#NO_REDRAW_RESIZE | |
1792 * @see DWT#NO_MERGE_PAINTS | |
1793 * @see DWT#DOUBLE_BUFFERED | |
1794 */ | |
1795 public void redraw (int x, int y, int width, int height, bool all) { | |
1796 checkWidget (); | |
1797 NSRect rect = new NSRect(); | |
1798 rect.x = x; | |
1799 rect.y = y; | |
1800 rect.width = width; | |
1801 rect.height = height; | |
1802 view.setNeedsDisplayInRect(rect); | |
1803 } | |
1804 | |
1805 void releaseHandle () { | |
1806 super.releaseHandle (); | |
1807 if (view !is null) { | |
1808 OS.objc_msgSend(view.id, OS.sel_setTag_1, -1); | |
1809 view.release(); | |
1810 } | |
1811 view = null; | |
1812 parent = null; | |
1813 } | |
1814 | |
1815 void releaseParent () { | |
1816 // setVisible (topHandle (), false); | |
1817 parent.removeControl (this); | |
1818 } | |
1819 | |
1820 void releaseWidget () { | |
1821 super.releaseWidget (); | |
1822 if (menu !is null && !menu.isDisposed ()) { | |
1823 menu.dispose (); | |
1824 } | |
1825 menu = null; | |
1826 layoutData = null; | |
1827 if (accessible !is null) { | |
1828 accessible.internal_dispose_Accessible (); | |
1829 } | |
1830 accessible = null; | |
1831 region = null; | |
1832 } | |
1833 | |
1834 /** | |
1835 * Removes the listener from the collection of listeners who will | |
1836 * be notified when the control is moved or resized. | |
1837 * | |
1838 * @param listener the listener which should no longer be notified | |
1839 * | |
1840 * @exception IllegalArgumentException <ul> | |
1841 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1842 * </ul> | |
1843 * @exception DWTException <ul> | |
1844 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1845 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1846 * </ul> | |
1847 * | |
1848 * @see ControlListener | |
1849 * @see #addControlListener | |
1850 */ | |
1851 public void removeControlListener (ControlListener listener) { | |
1852 checkWidget(); | |
1853 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1854 if (eventTable is null) return; | |
1855 eventTable.unhook (DWT.Move, listener); | |
1856 eventTable.unhook (DWT.Resize, listener); | |
1857 } | |
1858 | |
1859 /** | |
1860 * Removes the listener from the collection of listeners who will | |
1861 * be notified when a drag gesture occurs. | |
1862 * | |
1863 * @param listener the listener which should no longer be notified | |
1864 * | |
1865 * @exception IllegalArgumentException <ul> | |
1866 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1867 * </ul> | |
1868 * @exception DWTException <ul> | |
1869 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1870 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1871 * </ul> | |
1872 * | |
1873 * @see DragDetectListener | |
1874 * @see #addDragDetectListener | |
1875 * | |
1876 * @since 3.3 | |
1877 */ | |
1878 public void removeDragDetectListener(DragDetectListener listener) { | |
1879 checkWidget (); | |
1880 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1881 if (eventTable is null) return; | |
1882 eventTable.unhook (DWT.DragDetect, listener); | |
1883 } | |
1884 | |
1885 /** | |
1886 * Removes the listener from the collection of listeners who will | |
1887 * be notified when the control gains or loses focus. | |
1888 * | |
1889 * @param listener the listener which should no longer be notified | |
1890 * | |
1891 * @exception IllegalArgumentException <ul> | |
1892 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1893 * </ul> | |
1894 * @exception DWTException <ul> | |
1895 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1896 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1897 * </ul> | |
1898 * | |
1899 * @see FocusListener | |
1900 * @see #addFocusListener | |
1901 */ | |
1902 public void removeFocusListener(FocusListener listener) { | |
1903 checkWidget(); | |
1904 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1905 if (eventTable is null) return; | |
1906 eventTable.unhook(DWT.FocusIn, listener); | |
1907 eventTable.unhook(DWT.FocusOut, listener); | |
1908 } | |
1909 | |
1910 /** | |
1911 * Removes the listener from the collection of listeners who will | |
1912 * be notified when the help events are generated for the control. | |
1913 * | |
1914 * @param listener the listener which should no longer be notified | |
1915 * | |
1916 * @exception IllegalArgumentException <ul> | |
1917 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1918 * </ul> | |
1919 * @exception DWTException <ul> | |
1920 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1921 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1922 * </ul> | |
1923 * | |
1924 * @see HelpListener | |
1925 * @see #addHelpListener | |
1926 */ | |
1927 public void removeHelpListener (HelpListener listener) { | |
1928 checkWidget(); | |
1929 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1930 if (eventTable is null) return; | |
1931 eventTable.unhook (DWT.Help, listener); | |
1932 } | |
1933 | |
1934 /** | |
1935 * Removes the listener from the collection of listeners who will | |
1936 * be notified when keys are pressed and released on the system keyboard. | |
1937 * | |
1938 * @param listener the listener which should no longer be notified | |
1939 * | |
1940 * @exception IllegalArgumentException <ul> | |
1941 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1942 * </ul> | |
1943 * @exception DWTException <ul> | |
1944 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1945 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1946 * </ul> | |
1947 * | |
1948 * @see KeyListener | |
1949 * @see #addKeyListener | |
1950 */ | |
1951 public void removeKeyListener(KeyListener listener) { | |
1952 checkWidget(); | |
1953 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1954 if (eventTable is null) return; | |
1955 eventTable.unhook(DWT.KeyUp, listener); | |
1956 eventTable.unhook(DWT.KeyDown, listener); | |
1957 } | |
1958 | |
1959 /** | |
1960 * Removes the listener from the collection of listeners who will | |
1961 * be notified when the platform-specific context menu trigger has | |
1962 * occurred. | |
1963 * | |
1964 * @param listener the listener which should no longer be notified | |
1965 * | |
1966 * @exception IllegalArgumentException <ul> | |
1967 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1968 * </ul> | |
1969 * @exception DWTException <ul> | |
1970 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1971 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1972 * </ul> | |
1973 * | |
1974 * @see MenuDetectListener | |
1975 * @see #addMenuDetectListener | |
1976 * | |
1977 * @since 3.3 | |
1978 */ | |
1979 public void removeMenuDetectListener (MenuDetectListener listener) { | |
1980 checkWidget (); | |
1981 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
1982 if (eventTable is null) return; | |
1983 eventTable.unhook (DWT.MenuDetect, listener); | |
1984 } | |
1985 | |
1986 /** | |
1987 * Removes the listener from the collection of listeners who will | |
1988 * be notified when mouse buttons are pressed and released. | |
1989 * | |
1990 * @param listener the listener which should no longer be notified | |
1991 * | |
1992 * @exception IllegalArgumentException <ul> | |
1993 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1994 * </ul> | |
1995 * @exception DWTException <ul> | |
1996 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1997 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1998 * </ul> | |
1999 * | |
2000 * @see MouseListener | |
2001 * @see #addMouseListener | |
2002 */ | |
2003 public void removeMouseListener(MouseListener listener) { | |
2004 checkWidget(); | |
2005 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2006 if (eventTable is null) return; | |
2007 eventTable.unhook(DWT.MouseDown, listener); | |
2008 eventTable.unhook(DWT.MouseUp, listener); | |
2009 eventTable.unhook(DWT.MouseDoubleClick, listener); | |
2010 } | |
2011 | |
2012 /** | |
2013 * Removes the listener from the collection of listeners who will | |
2014 * be notified when the mouse moves. | |
2015 * | |
2016 * @param listener the listener which should no longer be notified | |
2017 * | |
2018 * @exception IllegalArgumentException <ul> | |
2019 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
2020 * </ul> | |
2021 * @exception DWTException <ul> | |
2022 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2023 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2024 * </ul> | |
2025 * | |
2026 * @see MouseMoveListener | |
2027 * @see #addMouseMoveListener | |
2028 */ | |
2029 public void removeMouseMoveListener(MouseMoveListener listener) { | |
2030 checkWidget(); | |
2031 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2032 if (eventTable is null) return; | |
2033 eventTable.unhook(DWT.MouseMove, listener); | |
2034 } | |
2035 | |
2036 /** | |
2037 * Removes the listener from the collection of listeners who will | |
2038 * be notified when the mouse passes or hovers over controls. | |
2039 * | |
2040 * @param listener the listener which should no longer be notified | |
2041 * | |
2042 * @exception IllegalArgumentException <ul> | |
2043 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
2044 * </ul> | |
2045 * @exception DWTException <ul> | |
2046 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2047 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2048 * </ul> | |
2049 * | |
2050 * @see MouseTrackListener | |
2051 * @see #addMouseTrackListener | |
2052 */ | |
2053 public void removeMouseTrackListener(MouseTrackListener listener) { | |
2054 checkWidget(); | |
2055 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2056 if (eventTable is null) return; | |
2057 eventTable.unhook (DWT.MouseEnter, listener); | |
2058 eventTable.unhook (DWT.MouseExit, listener); | |
2059 eventTable.unhook (DWT.MouseHover, listener); | |
2060 } | |
2061 | |
2062 /** | |
2063 * Removes the listener from the collection of listeners who will | |
2064 * be notified when the mouse wheel is scrolled. | |
2065 * | |
2066 * @param listener the listener which should no longer be notified | |
2067 * | |
2068 * @exception IllegalArgumentException <ul> | |
2069 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
2070 * </ul> | |
2071 * @exception DWTException <ul> | |
2072 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2073 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2074 * </ul> | |
2075 * | |
2076 * @see MouseWheelListener | |
2077 * @see #addMouseWheelListener | |
2078 * | |
2079 * @since 3.3 | |
2080 */ | |
2081 public void removeMouseWheelListener (MouseWheelListener listener) { | |
2082 checkWidget (); | |
2083 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2084 if (eventTable is null) return; | |
2085 eventTable.unhook (DWT.MouseWheel, listener); | |
2086 } | |
2087 | |
2088 /** | |
2089 * Removes the listener from the collection of listeners who will | |
2090 * be notified when the receiver needs to be painted. | |
2091 * | |
2092 * @param listener the listener which should no longer be notified | |
2093 * | |
2094 * @exception IllegalArgumentException <ul> | |
2095 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
2096 * </ul> | |
2097 * @exception DWTException <ul> | |
2098 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2099 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2100 * </ul> | |
2101 * | |
2102 * @see PaintListener | |
2103 * @see #addPaintListener | |
2104 */ | |
2105 public void removePaintListener(PaintListener listener) { | |
2106 checkWidget(); | |
2107 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2108 if (eventTable is null) return; | |
2109 eventTable.unhook(DWT.Paint, listener); | |
2110 } | |
2111 | |
2112 /** | |
2113 * Removes the listener from the collection of listeners who will | |
2114 * be notified when traversal events occur. | |
2115 * | |
2116 * @param listener the listener which should no longer be notified | |
2117 * | |
2118 * @exception IllegalArgumentException <ul> | |
2119 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
2120 * </ul> | |
2121 * @exception DWTException <ul> | |
2122 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2123 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2124 * </ul> | |
2125 * | |
2126 * @see TraverseListener | |
2127 * @see #addTraverseListener | |
2128 */ | |
2129 public void removeTraverseListener(TraverseListener listener) { | |
2130 checkWidget(); | |
2131 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2132 if (eventTable is null) return; | |
2133 eventTable.unhook (DWT.Traverse, listener); | |
2134 } | |
2135 | |
2136 bool sendDragEvent (int button, int stateMask, int x, int y) { | |
2137 Event event = new Event (); | |
2138 event.button = button; | |
2139 event.x = x; | |
2140 event.y = y; | |
2141 event.stateMask = stateMask; | |
2142 postEvent (DWT.DragDetect, event); | |
2143 return event.doit; | |
2144 } | |
2145 | |
2146 bool sendDragEvent (int button, int chord, int modifiers, int x, int y) { | |
2147 Event event = new Event (); | |
2148 switch (button) { | |
2149 case 1: event.button = 1; break; | |
2150 case 2: event.button = 3; break; | |
2151 case 3: event.button = 2; break; | |
2152 case 4: event.button = 4; break; | |
2153 case 5: event.button = 5; break; | |
2154 } | |
2155 event.x = x; | |
2156 event.y = y; | |
2157 setInputState (event, DWT.DragDetect, chord, modifiers); | |
2158 postEvent (DWT.DragDetect, event); | |
2159 return event.doit; | |
2160 } | |
2161 | |
2162 void sendFocusEvent (int type, bool post) { | |
2163 Display display = this.display; | |
2164 Shell shell = getShell (); | |
2165 /* | |
2166 * Feature in the Macintosh. GetKeyboardFocus() returns NULL during | |
2167 * kEventControlSetFocusPart if the focus part is not kControlFocusNoPart. | |
2168 * The fix is to remember the focus control and return it during | |
2169 * kEventControlSetFocusPart. | |
2170 */ | |
2171 // display.focusControl = this; | |
2172 // display.focusEvent = type; | |
2173 if (post) { | |
2174 postEvent (type); | |
2175 } else { | |
2176 sendEvent (type); | |
2177 } | |
2178 /* | |
2179 * It is possible that the shell may be | |
2180 * disposed at this point. If this happens | |
2181 * don't send the activate and deactivate | |
2182 * events. | |
2183 */ | |
2184 if (!shell.isDisposed ()) { | |
2185 switch (type) { | |
2186 case DWT.FocusIn: | |
2187 shell.setActiveControl (this); | |
2188 break; | |
2189 case DWT.FocusOut: | |
2190 if (shell !is display.getActiveShell ()) { | |
2191 shell.setActiveControl (null); | |
2192 } | |
2193 break; | |
2194 } | |
2195 } | |
2196 // display.focusEvent = DWT.None; | |
2197 // display.focusControl = null; | |
2198 } | |
2199 | |
2200 bool sendMouseEvent (int type, short button, int count, int detail, bool send, int theEvent) { | |
2201 // CGPoint pt = new CGPoint (); | |
2202 // OS.GetEventParameter (theEvent, OS.kEventParamWindowMouseLocation, OS.typeHIPoint, null, CGPoint.sizeof, null, pt); | |
2203 // OS.HIViewConvertPoint (pt, 0, handle); | |
2204 // int x = (int) pt.x; | |
2205 // int y = (int) pt.y; | |
2206 // display.lastX = x; | |
2207 // display.lastY = y; | |
2208 // int [] chord = new int [1]; | |
2209 // OS.GetEventParameter (theEvent, OS.kEventParamMouseChord, OS.typeUInt32, null, 4, null, chord); | |
2210 // int [] modifiers = new int [1]; | |
2211 // OS.GetEventParameter (theEvent, OS.kEventParamKeyModifiers, OS.typeUInt32, null, 4, null, modifiers); | |
2212 // return sendMouseEvent (type, button, count, detail, send, chord [0], (short) x, (short) y, modifiers [0]); | |
2213 return false; | |
2214 } | |
2215 | |
2216 bool sendMouseEvent (int type, short button, int count, bool send, int chord, short x, short y, int modifiers) { | |
2217 return sendMouseEvent (type, button, count, 0, send, chord, x, y, modifiers); | |
2218 } | |
2219 | |
2220 bool sendMouseEvent (int type, short button, int count, int detail, bool send, int chord, short x, short y, int modifiers) { | |
2221 if (!hooks (type) && !filters (type)) return true; | |
2222 Event event = new Event (); | |
2223 switch (button) { | |
2224 case 1: event.button = 1; break; | |
2225 case 2: event.button = 3; break; | |
2226 case 3: event.button = 2; break; | |
2227 case 4: event.button = 4; break; | |
2228 case 5: event.button = 5; break; | |
2229 } | |
2230 event.x = x; | |
2231 event.y = y; | |
2232 event.count = count; | |
2233 event.detail = detail; | |
2234 setInputState (event, type, chord, modifiers); | |
2235 if (send) { | |
2236 sendEvent (type, event); | |
2237 if (isDisposed ()) return false; | |
2238 } else { | |
2239 postEvent (type, event); | |
2240 } | |
2241 return event.doit; | |
2242 } | |
2243 | |
2244 bool sendMouseWheel (short wheelAxis, int wheelDelta) { | |
2245 return false; | |
2246 } | |
2247 | |
2248 void setBackground () { | |
2249 // redrawWidget (handle, false); | |
2250 } | |
2251 | |
2252 /** | |
2253 * Sets the receiver's background color to the color specified | |
2254 * by the argument, or to the default system color for the control | |
2255 * if the argument is null. | |
2256 * <p> | |
2257 * Note: This operation is a hint and may be overridden by the platform. | |
2258 * For example, on Windows the background of a Button cannot be changed. | |
2259 * </p> | |
2260 * @param color the new color (or null) | |
2261 * | |
2262 * @exception IllegalArgumentException <ul> | |
2263 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
2264 * </ul> | |
2265 * @exception DWTException <ul> | |
2266 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2267 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2268 * </ul> | |
2269 */ | |
2270 public void setBackground (Color color) { | |
2271 checkWidget(); | |
2272 if (color !is null) { | |
2273 if (color.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2274 } | |
2275 // if (equals (background, this.background)) return; | |
2276 this.background = color; | |
2277 setBackground (color !is null ? color.handle : null); | |
2278 view.setNeedsDisplay(true); | |
2279 } | |
2280 | |
2281 /** | |
2282 * Sets the receiver's background image to the image specified | |
2283 * by the argument, or to the default system color for the control | |
2284 * if the argument is null. The background image is tiled to fill | |
2285 * the available space. | |
2286 * <p> | |
2287 * Note: This operation is a hint and may be overridden by the platform. | |
2288 * For example, on Windows the background of a Button cannot be changed. | |
2289 * </p> | |
2290 * @param image the new image (or null) | |
2291 * | |
2292 * @exception IllegalArgumentException <ul> | |
2293 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
2294 * <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li> | |
2295 * </ul> | |
2296 * @exception DWTException <ul> | |
2297 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2298 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2299 * </ul> | |
2300 * | |
2301 * @since 3.2 | |
2302 */ | |
2303 public void setBackgroundImage (Image image) { | |
2304 checkWidget(); | |
2305 if (image !is null && image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2306 if (image is backgroundImage) return; | |
2307 backgroundImage = image; | |
2308 // redrawWidget (handle, false); | |
2309 } | |
2310 | |
2311 void setBackground (float [] color) { | |
2312 } | |
2313 | |
2314 void setBackground (int control, float [] color) { | |
2315 // ControlFontStyleRec fontStyle = new ControlFontStyleRec (); | |
2316 // OS.GetControlData (control, (short) OS.kControlEntireControl, OS.kControlFontStyleTag, ControlFontStyleRec.sizeof, fontStyle, null); | |
2317 // if (color !is null) { | |
2318 // fontStyle.backColor_red = (short) (color [0] * 0xffff); | |
2319 // fontStyle.backColor_green = (short) (color [1] * 0xffff); | |
2320 // fontStyle.backColor_blue = (short) (color [2] * 0xffff); | |
2321 // fontStyle.flags |= OS.kControlUseBackColorMask; | |
2322 // } else { | |
2323 // fontStyle.flags &= ~OS.kControlUseBackColorMask; | |
2324 // } | |
2325 // OS.SetControlFontStyle (control, fontStyle); | |
2326 } | |
2327 | |
2328 /** | |
2329 * Sets the receiver's size and location to the rectangular | |
2330 * area specified by the arguments. The <code>x</code> and | |
2331 * <code>y</code> arguments are relative to the receiver's | |
2332 * parent (or its display if its parent is null), unless | |
2333 * the receiver is a shell. In this case, the <code>x</code> | |
2334 * and <code>y</code> arguments are relative to the display. | |
2335 * <p> | |
2336 * Note: Attempting to set the width or height of the | |
2337 * receiver to a negative number will cause that | |
2338 * value to be set to zero instead. | |
2339 * </p> | |
2340 * | |
2341 * @param x the new x coordinate for the receiver | |
2342 * @param y the new y coordinate for the receiver | |
2343 * @param width the new width for the receiver | |
2344 * @param height the new height for the receiver | |
2345 * | |
2346 * @exception DWTException <ul> | |
2347 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2348 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2349 * </ul> | |
2350 */ | |
2351 public void setBounds (int x, int y, int width, int height) { | |
2352 checkWidget(); | |
2353 setBounds (x, y, Math.max (0, width), Math.max (0, height), true, true); | |
2354 } | |
2355 | |
2356 int setBounds (int x, int y, int width, int height, bool move, bool resize) { | |
2357 int result = 0; | |
2358 NSView topView = topView(); | |
2359 NSRect rect = topView.frame(); | |
2360 if (move && resize) { | |
2361 if (rect.x !is x || rect.y !is y) result |= MOVED; | |
2362 if (rect.width !is width || rect.height !is height) result |= RESIZED; | |
2363 if (result !is 0) { | |
2364 rect.x = x; | |
2365 rect.y = y; | |
2366 rect.width = width; | |
2367 rect.height = height; | |
2368 topView.setFrame (rect); | |
2369 } | |
2370 } else if (move) { | |
2371 if (rect.x !is x || rect.y !is y) { | |
2372 result |= MOVED; | |
2373 NSPoint point = new NSPoint(); | |
2374 point.x = x; | |
2375 point.y = y; | |
2376 topView.setFrameOrigin(point); | |
2377 } | |
2378 } else if (resize) { | |
2379 if (rect.width !is width || rect.height !is height) { | |
2380 result |= RESIZED; | |
2381 NSSize size = new NSSize(); | |
2382 size.width = width; | |
2383 size.height = height; | |
2384 topView.setFrameSize(size); | |
2385 } | |
2386 } | |
2387 if ((result & MOVED) !is 0) { | |
2388 sendEvent(DWT.Move); | |
2389 } | |
2390 if ((result & RESIZED) !is 0) { | |
2391 sendEvent(DWT.Resize); | |
2392 } | |
2393 return result; | |
2394 } | |
2395 | |
2396 /** | |
2397 * Sets the receiver's size and location to the rectangular | |
2398 * area specified by the argument. The <code>x</code> and | |
2399 * <code>y</code> fields of the rectangle are relative to | |
2400 * the receiver's parent (or its display if its parent is null). | |
2401 * <p> | |
2402 * Note: Attempting to set the width or height of the | |
2403 * receiver to a negative number will cause that | |
2404 * value to be set to zero instead. | |
2405 * </p> | |
2406 * | |
2407 * @param rect the new bounds for the receiver | |
2408 * | |
2409 * @exception DWTException <ul> | |
2410 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2411 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2412 * </ul> | |
2413 */ | |
2414 public void setBounds (Rectangle rect) { | |
2415 checkWidget (); | |
2416 if (rect is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2417 setBounds (rect.x, rect.y, Math.max (0, rect.width), Math.max (0, rect.height), true, true); | |
2418 } | |
2419 | |
2420 /** | |
2421 * If the argument is <code>true</code>, causes the receiver to have | |
2422 * all mouse events delivered to it until the method is called with | |
2423 * <code>false</code> as the argument. | |
2424 * | |
2425 * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it | |
2426 * | |
2427 * @exception DWTException <ul> | |
2428 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2429 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2430 * </ul> | |
2431 */ | |
2432 public void setCapture (bool capture) { | |
2433 checkWidget(); | |
2434 } | |
2435 | |
2436 /** | |
2437 * Sets the receiver's cursor to the cursor specified by the | |
2438 * argument, or to the default cursor for that kind of control | |
2439 * if the argument is null. | |
2440 * <p> | |
2441 * When the mouse pointer passes over a control its appearance | |
2442 * is changed to match the control's cursor. | |
2443 * </p> | |
2444 * | |
2445 * @param cursor the new cursor (or null) | |
2446 * | |
2447 * @exception IllegalArgumentException <ul> | |
2448 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
2449 * </ul> | |
2450 * @exception DWTException <ul> | |
2451 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2452 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2453 * </ul> | |
2454 */ | |
2455 public void setCursor (Cursor cursor) { | |
2456 checkWidget(); | |
2457 if (cursor !is null && cursor.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); | |
2458 this.cursor = cursor; | |
2459 //TODO null | |
2460 // view.addCursorRect(view.frame(), cursor.handle); | |
2461 } | |
2462 | |
2463 void setDefaultFont () { | |
2464 // if (display.smallFonts) setFontStyle (defaultFont ()); | |
2465 } | |
2466 | |
2467 /** | |
2468 * Sets the receiver's drag detect state. If the argument is | |
2469 * <code>true</code>, the receiver will detect drag gestures, | |
2470 * otherwise these gestures will be ignored. | |
2471 * | |
2472 * @param dragDetect the new drag detect state | |
2473 * | |
2474 * @exception DWTException <ul> | |
2475 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2476 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2477 * </ul> | |
2478 * | |
2479 * @since 3.3 | |
2480 */ | |
2481 public void setDragDetect (bool dragDetect) { | |
2482 checkWidget (); | |
2483 if (dragDetect) { | |
2484 state |= DRAG_DETECT; | |
2485 } else { | |
2486 state &= ~DRAG_DETECT; | |
2487 } | |
2488 } | |
2489 | |
2490 /** | |
2491 * Enables the receiver if the argument is <code>true</code>, | |
2492 * and disables it otherwise. A disabled control is typically | |
2493 * not selectable from the user interface and draws with an | |
2494 * inactive or "grayed" look. | |
2495 * | |
2496 * @param enabled the new enabled state | |
2497 * | |
2498 * @exception DWTException <ul> | |
2499 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2500 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2501 * </ul> | |
2502 */ | |
2503 public void setEnabled (bool enabled) { | |
2504 checkWidget(); | |
2505 if (((state & DISABLED) is 0) is enabled) return; | |
2506 Control control = null; | |
2507 bool fixFocus = false; | |
2508 if (!enabled) { | |
2509 // if (display.focusEvent !is DWT.FocusOut) { | |
2510 control = display.getFocusControl (); | |
2511 fixFocus = isFocusAncestor (control); | |
2512 // } | |
2513 } | |
2514 if (enabled) { | |
2515 state &= ~DISABLED; | |
2516 } else { | |
2517 state |= DISABLED; | |
2518 } | |
2519 enableWidget (enabled); | |
2520 if (fixFocus) fixFocus (control); | |
2521 } | |
2522 | |
2523 /** | |
2524 * Causes the receiver to have the <em>keyboard focus</em>, | |
2525 * such that all keyboard events will be delivered to it. Focus | |
2526 * reassignment will respect applicable platform constraints. | |
2527 * | |
2528 * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to. | |
2529 * | |
2530 * @exception DWTException <ul> | |
2531 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2532 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2533 * </ul> | |
2534 * | |
2535 * @see #forceFocus | |
2536 */ | |
2537 public bool setFocus () { | |
2538 checkWidget(); | |
2539 if ((style & DWT.NO_FOCUS) !is 0) return false; | |
2540 return forceFocus (); | |
2541 } | |
2542 | |
2543 /** | |
2544 * Sets the font that the receiver will use to paint textual information | |
2545 * to the font specified by the argument, or to the default font for that | |
2546 * kind of control if the argument is null. | |
2547 * | |
2548 * @param font the new font (or null) | |
2549 * | |
2550 * @exception IllegalArgumentException <ul> | |
2551 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
2552 * </ul> | |
2553 * @exception DWTException <ul> | |
2554 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2555 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2556 * </ul> | |
2557 */ | |
2558 public void setFont (Font font) { | |
2559 checkWidget(); | |
2560 if (font !is null) { | |
2561 if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2562 } | |
2563 this.font = font; | |
2564 setFont (font !is null ? font.handle : defaultFont().handle); | |
2565 } | |
2566 | |
2567 void setFont (NSFont font) { | |
2568 //TODO - bad cast | |
2569 if (view instanceof NSControl) { | |
2570 ((NSControl)view).setFont(font); | |
2571 } | |
2572 } | |
2573 | |
2574 /** | |
2575 * Sets the receiver's foreground color to the color specified | |
2576 * by the argument, or to the default system color for the control | |
2577 * if the argument is null. | |
2578 * <p> | |
2579 * Note: This operation is a hint and may be overridden by the platform. | |
2580 * </p> | |
2581 * @param color the new color (or null) | |
2582 * | |
2583 * @exception IllegalArgumentException <ul> | |
2584 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
2585 * </ul> | |
2586 * @exception DWTException <ul> | |
2587 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2588 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2589 * </ul> | |
2590 */ | |
2591 public void setForeground (Color color) { | |
2592 checkWidget(); | |
2593 if (color !is null) { | |
2594 if (color.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2595 } | |
2596 // if (equals (foreground, this.foreground)) return; | |
2597 this.foreground = color; | |
2598 setForeground (color !is null ? color.handle : null); | |
2599 view.setNeedsDisplay(true); | |
2600 } | |
2601 | |
2602 void setForeground (float [] color) { | |
2603 } | |
2604 | |
2605 void setForeground (int control, float [] color) { | |
2606 // ControlFontStyleRec fontStyle = new ControlFontStyleRec (); | |
2607 // OS.GetControlData (control, (short) OS.kControlEntireControl, OS.kControlFontStyleTag, ControlFontStyleRec.sizeof, fontStyle, null); | |
2608 // if (color !is null) { | |
2609 // fontStyle.foreColor_red = (short) (color [0] * 0xffff); | |
2610 // fontStyle.foreColor_green = (short) (color [1] * 0xffff); | |
2611 // fontStyle.foreColor_blue = (short) (color [2] * 0xffff); | |
2612 // fontStyle.flags |= OS.kControlUseForeColorMask; | |
2613 // } else { | |
2614 // fontStyle.flags &= ~OS.kControlUseForeColorMask; | |
2615 // } | |
2616 // OS.SetControlFontStyle (control, fontStyle); | |
2617 } | |
2618 | |
2619 /** | |
2620 * Sets the layout data associated with the receiver to the argument. | |
2621 * | |
2622 * @param layoutData the new layout data for the receiver. | |
2623 * | |
2624 * @exception DWTException <ul> | |
2625 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2626 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2627 * </ul> | |
2628 */ | |
2629 public void setLayoutData (Object layoutData) { | |
2630 checkWidget(); | |
2631 this.layoutData = layoutData; | |
2632 } | |
2633 | |
2634 /** | |
2635 * Sets the receiver's location to the point specified by | |
2636 * the arguments which are relative to the receiver's | |
2637 * parent (or its display if its parent is null), unless | |
2638 * the receiver is a shell. In this case, the point is | |
2639 * relative to the display. | |
2640 * | |
2641 * @param x the new x coordinate for the receiver | |
2642 * @param y the new y coordinate for the receiver | |
2643 * | |
2644 * @exception DWTException <ul> | |
2645 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2646 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2647 * </ul> | |
2648 */ | |
2649 public void setLocation (int x, int y) { | |
2650 checkWidget(); | |
2651 setBounds (x, y, 0, 0, true, false); | |
2652 } | |
2653 | |
2654 /** | |
2655 * Sets the receiver's location to the point specified by | |
2656 * the arguments which are relative to the receiver's | |
2657 * parent (or its display if its parent is null), unless | |
2658 * the receiver is a shell. In this case, the point is | |
2659 * relative to the display. | |
2660 * | |
2661 * @param location the new location for the receiver | |
2662 * | |
2663 * @exception DWTException <ul> | |
2664 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2665 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2666 * </ul> | |
2667 */ | |
2668 public void setLocation (Point location) { | |
2669 checkWidget(); | |
2670 if (location is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2671 setBounds (location.x, location.y, 0, 0, true, false); | |
2672 } | |
2673 | |
2674 /** | |
2675 * Sets the receiver's pop up menu to the argument. | |
2676 * All controls may optionally have a pop up | |
2677 * menu that is displayed when the user requests one for | |
2678 * the control. The sequence of key strokes, button presses | |
2679 * and/or button releases that are used to request a pop up | |
2680 * menu is platform specific. | |
2681 * <p> | |
2682 * Note: Disposing of a control that has a pop up menu will | |
2683 * dispose of the menu. To avoid this behavior, set the | |
2684 * menu to null before the control is disposed. | |
2685 * </p> | |
2686 * | |
2687 * @param menu the new pop up menu | |
2688 * | |
2689 * @exception IllegalArgumentException <ul> | |
2690 * <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li> | |
2691 * <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li> | |
2692 * <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li> | |
2693 * </ul> | |
2694 * @exception DWTException <ul> | |
2695 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2696 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2697 * </ul> | |
2698 */ | |
2699 public void setMenu (Menu menu) { | |
2700 checkWidget(); | |
2701 if (menu !is null) { | |
2702 if (menu.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2703 if ((menu.style & DWT.POP_UP) is 0) { | |
2704 error (DWT.ERROR_MENU_NOT_POP_UP); | |
2705 } | |
2706 if (menu.parent !is menuShell ()) { | |
2707 error (DWT.ERROR_INVALID_PARENT); | |
2708 } | |
2709 } | |
2710 this.menu = menu; | |
2711 } | |
2712 | |
2713 /** | |
2714 * Changes the parent of the widget to be the one provided if | |
2715 * the underlying operating system supports this feature. | |
2716 * Returns <code>true</code> if the parent is successfully changed. | |
2717 * | |
2718 * @param parent the new parent for the control. | |
2719 * @return <code>true</code> if the parent is changed and <code>false</code> otherwise. | |
2720 * | |
2721 * @exception IllegalArgumentException <ul> | |
2722 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
2723 * <li>ERROR_NULL_ARGUMENT - if the parent is <code>null</code></li> | |
2724 * </ul> | |
2725 * @exception DWTException <ul> | |
2726 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2727 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2728 * </ul> | |
2729 */ | |
2730 public bool setParent (Composite parent) { | |
2731 checkWidget(); | |
2732 if (parent is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2733 if (parent.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2734 if (this.parent is parent) return true; | |
2735 if (!isReparentable ()) return false; | |
2736 releaseParent (); | |
2737 Shell newShell = parent.getShell (), oldShell = getShell (); | |
2738 Decorations newDecorations = parent.menuShell (), oldDecorations = menuShell (); | |
2739 if (oldShell !is newShell || oldDecorations !is newDecorations) { | |
2740 Menu [] menus = oldShell.findMenus (this); | |
2741 fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus); | |
2742 } | |
2743 // int topHandle = topHandle (); | |
2744 // OS.HIViewAddSubview (parent.handle, topHandle); | |
2745 // OS.HIViewSetVisible (topHandle, (state & HIDDEN) is 0); | |
2746 // OS.HIViewSetZOrder (topHandle, OS.kHIViewZOrderBelow, 0); | |
2747 this.parent = parent; | |
2748 return true; | |
2749 } | |
2750 | |
2751 /** | |
2752 * If the argument is <code>false</code>, causes subsequent drawing | |
2753 * operations in the receiver to be ignored. No drawing of any kind | |
2754 * can occur in the receiver until the flag is set to true. | |
2755 * Graphics operations that occurred while the flag was | |
2756 * <code>false</code> are lost. When the flag is set to <code>true</code>, | |
2757 * the entire widget is marked as needing to be redrawn. Nested calls | |
2758 * to this method are stacked. | |
2759 * <p> | |
2760 * Note: This operation is a hint and may not be supported on some | |
2761 * platforms or for some widgets. | |
2762 * </p> | |
2763 * | |
2764 * @param redraw the new redraw state | |
2765 * | |
2766 * @exception DWTException <ul> | |
2767 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2768 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2769 * </ul> | |
2770 * | |
2771 * @see #redraw(int, int, int, int, bool) | |
2772 * @see #update() | |
2773 */ | |
2774 public void setRedraw (bool redraw) { | |
2775 checkWidget(); | |
2776 if (redraw) { | |
2777 if (--drawCount is 0) { | |
2778 // OS.HIViewSetDrawingEnabled (handle, true); | |
2779 // invalidateVisibleRegion (handle); | |
2780 // redrawWidget (handle, true); | |
2781 } | |
2782 } else { | |
2783 if (drawCount is 0) { | |
2784 // OS.HIViewSetDrawingEnabled (handle, false); | |
2785 // invalidateVisibleRegion (handle); | |
2786 } | |
2787 drawCount++; | |
2788 } | |
2789 } | |
2790 | |
2791 public void setRegion (Region region) { | |
2792 checkWidget (); | |
2793 if (region !is null && region.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT); | |
2794 this.region = region; | |
2795 // redrawWidget (handle, true); | |
2796 } | |
2797 | |
2798 bool setRadioSelection (bool value){ | |
2799 return false; | |
2800 } | |
2801 | |
2802 /** | |
2803 * Sets the receiver's size to the point specified by the arguments. | |
2804 * <p> | |
2805 * Note: Attempting to set the width or height of the | |
2806 * receiver to a negative number will cause that | |
2807 * value to be set to zero instead. | |
2808 * </p> | |
2809 * | |
2810 * @param width the new width for the receiver | |
2811 * @param height the new height for the receiver | |
2812 * | |
2813 * @exception DWTException <ul> | |
2814 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2815 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2816 * </ul> | |
2817 */ | |
2818 public void setSize (int width, int height) { | |
2819 checkWidget(); | |
2820 setBounds (0, 0, Math.max (0, width), Math.max (0, height), false, true); | |
2821 } | |
2822 | |
2823 /** | |
2824 * Sets the receiver's size to the point specified by the argument. | |
2825 * <p> | |
2826 * Note: Attempting to set the width or height of the | |
2827 * receiver to a negative number will cause them to be | |
2828 * set to zero instead. | |
2829 * </p> | |
2830 * | |
2831 * @param size the new size for the receiver | |
2832 * | |
2833 * @exception IllegalArgumentException <ul> | |
2834 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> | |
2835 * </ul> | |
2836 * @exception DWTException <ul> | |
2837 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2838 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2839 * </ul> | |
2840 */ | |
2841 public void setSize (Point size) { | |
2842 checkWidget (); | |
2843 if (size is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2844 setBounds (0, 0, Math.max (0, size.x), Math.max (0, size.y), false, true); | |
2845 } | |
2846 | |
2847 bool setTabGroupFocus () { | |
2848 return setTabItemFocus (); | |
2849 } | |
2850 | |
2851 bool setTabItemFocus () { | |
2852 if (!isShowing ()) return false; | |
2853 return forceFocus (); | |
2854 } | |
2855 | |
2856 /** | |
2857 * Sets the receiver's tool tip text to the argument, which | |
2858 * may be null indicating that no tool tip text should be shown. | |
2859 * | |
2860 * @param string the new tool tip text (or null) | |
2861 * | |
2862 * @exception DWTException <ul> | |
2863 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2864 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2865 * </ul> | |
2866 */ | |
2867 public void setToolTipText (String string) { | |
2868 checkWidget(); | |
2869 toolTipText = string; | |
2870 view.setToolTip(string !is null ? NSString.stringWith(string) : null); | |
2871 } | |
2872 | |
2873 /** | |
2874 * Marks the receiver as visible if the argument is <code>true</code>, | |
2875 * and marks it invisible otherwise. | |
2876 * <p> | |
2877 * If one of the receiver's ancestors is not visible or some | |
2878 * other condition makes the receiver not visible, marking | |
2879 * it visible may not actually cause it to be displayed. | |
2880 * </p> | |
2881 * | |
2882 * @param visible the new visibility state | |
2883 * | |
2884 * @exception DWTException <ul> | |
2885 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2886 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2887 * </ul> | |
2888 */ | |
2889 public void setVisible (bool visible) { | |
2890 checkWidget(); | |
2891 if (visible) { | |
2892 if ((state & HIDDEN) is 0) return; | |
2893 state &= ~HIDDEN; | |
2894 } else { | |
2895 if ((state & HIDDEN) !is 0) return; | |
2896 state |= HIDDEN; | |
2897 } | |
2898 if (visible) { | |
2899 /* | |
2900 * It is possible (but unlikely), that application | |
2901 * code could have disposed the widget in the show | |
2902 * event. If this happens, just return. | |
2903 */ | |
2904 sendEvent (DWT.Show); | |
2905 if (isDisposed ()) return; | |
2906 } | |
2907 | |
2908 /* | |
2909 * Feature in the Macintosh. If the receiver has focus, hiding | |
2910 * the receiver causes no control to have focus. Also, the focus | |
2911 * needs to be cleared from any TXNObject so that it stops blinking | |
2912 * the caret. The fix is to assign focus to the first ancestor | |
2913 * control that takes focus. If no control will take focus, clear | |
2914 * the focus control. | |
2915 */ | |
2916 Control control = null; | |
2917 bool fixFocus = false; | |
2918 if (!visible) { | |
2919 // if (display.focusEvent !is DWT.FocusOut) { | |
2920 control = display.getFocusControl (); | |
2921 fixFocus = isFocusAncestor (control); | |
2922 // } | |
2923 } | |
2924 topView().setHidden(!visible); | |
2925 if (!visible) { | |
2926 /* | |
2927 * It is possible (but unlikely), that application | |
2928 * code could have disposed the widget in the show | |
2929 * event. If this happens, just return. | |
2930 */ | |
2931 sendEvent (DWT.Hide); | |
2932 if (isDisposed ()) return; | |
2933 } | |
2934 if (fixFocus) fixFocus (control); | |
2935 } | |
2936 | |
2937 void setZOrder () { | |
2938 // int topHandle = topHandle (); | |
2939 // int parentHandle = parent.handle; | |
2940 // OS.HIViewAddSubview (parentHandle, topHandle); | |
2941 // OS.HIViewSetZOrder (topHandle, OS.kHIViewZOrderBelow, 0); | |
2942 // Rect rect = getInset (); | |
2943 // rect.right = rect.left; | |
2944 // rect.bottom = rect.top; | |
2945 // OS.SetControlBounds (topHandle, rect); | |
2946 } | |
2947 | |
2948 void setZOrder (Control control, bool above) { | |
2949 NSView otherView = control is null ? null : control.topView (); | |
2950 view.retain(); | |
2951 view.removeFromSuperview(); | |
2952 parent.contentView().addSubview_positioned_relativeTo_(view, above ? OS.NSWindowAbove : OS.NSWindowBelow, otherView); | |
2953 view.release(); | |
2954 } | |
2955 | |
2956 void sort (int [] items) { | |
2957 /* Shell Sort from K&R, pg 108 */ | |
2958 int length = items.length; | |
2959 for (int gap=length/2; gap>0; gap/=2) { | |
2960 for (int i=gap; i<length; i++) { | |
2961 for (int j=i-gap; j>=0; j-=gap) { | |
2962 if (items [j] <= items [j + gap]) { | |
2963 int swap = items [j]; | |
2964 items [j] = items [j + gap]; | |
2965 items [j + gap] = swap; | |
2966 } | |
2967 } | |
2968 } | |
2969 } | |
2970 } | |
2971 | |
2972 /** | |
2973 * Returns a point which is the result of converting the | |
2974 * argument, which is specified in display relative coordinates, | |
2975 * to coordinates relative to the receiver. | |
2976 * <p> | |
2977 * @param x the x coordinate to be translated | |
2978 * @param y the y coordinate to be translated | |
2979 * @return the translated coordinates | |
2980 * | |
2981 * @exception DWTException <ul> | |
2982 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2983 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2984 * </ul> | |
2985 * | |
2986 * @since 2.1 | |
2987 */ | |
2988 public Point toControl (int x, int y) { | |
2989 checkWidget(); | |
2990 return display.map (null, this, x, y); | |
2991 } | |
2992 | |
2993 /** | |
2994 * Returns a point which is the result of converting the | |
2995 * argument, which is specified in display relative coordinates, | |
2996 * to coordinates relative to the receiver. | |
2997 * <p> | |
2998 * @param point the point to be translated (must not be null) | |
2999 * @return the translated coordinates | |
3000 * | |
3001 * @exception IllegalArgumentException <ul> | |
3002 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> | |
3003 * </ul> | |
3004 * @exception DWTException <ul> | |
3005 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
3006 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
3007 * </ul> | |
3008 */ | |
3009 public Point toControl (Point point) { | |
3010 checkWidget(); | |
3011 if (point is null) error (DWT.ERROR_NULL_ARGUMENT); | |
3012 return toControl (point.x, point.y); | |
3013 } | |
3014 | |
3015 /** | |
3016 * Returns a point which is the result of converting the | |
3017 * argument, which is specified in coordinates relative to | |
3018 * the receiver, to display relative coordinates. | |
3019 * <p> | |
3020 * @param x the x coordinate to be translated | |
3021 * @param y the y coordinate to be translated | |
3022 * @return the translated coordinates | |
3023 * | |
3024 * @exception DWTException <ul> | |
3025 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
3026 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
3027 * </ul> | |
3028 * | |
3029 * @since 2.1 | |
3030 */ | |
3031 public Point toDisplay (int x, int y) { | |
3032 checkWidget(); | |
3033 return display.map (this, null, x, y); | |
3034 } | |
3035 | |
3036 /** | |
3037 * Returns a point which is the result of converting the | |
3038 * argument, which is specified in coordinates relative to | |
3039 * the receiver, to display relative coordinates. | |
3040 * <p> | |
3041 * @param point the point to be translated (must not be null) | |
3042 * @return the translated coordinates | |
3043 * | |
3044 * @exception IllegalArgumentException <ul> | |
3045 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> | |
3046 * </ul> | |
3047 * @exception DWTException <ul> | |
3048 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
3049 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
3050 * </ul> | |
3051 */ | |
3052 public Point toDisplay (Point point) { | |
3053 checkWidget(); | |
3054 if (point is null) error (DWT.ERROR_NULL_ARGUMENT); | |
3055 return toDisplay (point.x, point.y); | |
3056 } | |
3057 | |
3058 NSView topView () { | |
3059 return view; | |
3060 } | |
3061 | |
3062 bool translateTraversal (int key, NSEvent theEvent, bool [] consume) { | |
3063 int detail = DWT.TRAVERSE_NONE; | |
3064 int code = traversalCode (key, theEvent); | |
3065 bool all = false; | |
3066 switch (key) { | |
3067 case 53: /* Esc */ { | |
3068 all = true; | |
3069 detail = DWT.TRAVERSE_ESCAPE; | |
3070 break; | |
3071 } | |
3072 case 76: /* KP Enter */ | |
3073 case 36: /* Return */ { | |
3074 all = true; | |
3075 detail = DWT.TRAVERSE_RETURN; | |
3076 break; | |
3077 } | |
3078 case 48: /* Tab */ { | |
3079 int modifiers = display.lastModifiers; | |
3080 bool next = (modifiers & OS.NSShiftKeyMask) is 0; | |
3081 detail = next ? DWT.TRAVERSE_TAB_NEXT : DWT.TRAVERSE_TAB_PREVIOUS; | |
3082 break; | |
3083 } | |
3084 case 126: /* Up arrow */ | |
3085 case 123: /* Left arrow */ | |
3086 case 125: /* Down arrow */ | |
3087 case 124: /* Right arrow */ { | |
3088 bool next = key is 125 /* Down arrow */ || key is 124 /* Right arrow */; | |
3089 detail = next ? DWT.TRAVERSE_ARROW_NEXT : DWT.TRAVERSE_ARROW_PREVIOUS; | |
3090 break; | |
3091 } | |
3092 case 116: /* Page up */ | |
3093 case 121: /* Page down */ { | |
3094 all = true; | |
3095 // int [] modifiers = new int [1]; | |
3096 // OS.GetEventParameter (theEvent, OS.kEventParamKeyModifiers, OS.typeUInt32, null, 4, null, modifiers); | |
3097 // if ((modifiers [0] & OS.controlKey) is 0) return false; | |
3098 // detail = key is 121 /* Page down */ ? DWT.TRAVERSE_PAGE_NEXT : DWT.TRAVERSE_PAGE_PREVIOUS; | |
3099 break; | |
3100 } | |
3101 default: | |
3102 return false; | |
3103 } | |
3104 Event event = new Event (); | |
3105 event.doit = consume [0] = (code & detail) !is 0; | |
3106 event.detail = detail; | |
3107 if (!setKeyState (event, DWT.Traverse, theEvent)) return false; | |
3108 Shell shell = getShell (); | |
3109 Control control = this; | |
3110 do { | |
3111 if (control.traverse (event)) return true; | |
3112 if (!event.doit && control.hooks (DWT.Traverse)) { | |
3113 return false; | |
3114 } | |
3115 if (control is shell) return false; | |
3116 control = control.parent; | |
3117 } while (all && control !is null); | |
3118 return false; | |
3119 } | |
3120 | |
3121 int traversalCode (int key, NSEvent theEvent) { | |
3122 int code = DWT.TRAVERSE_RETURN | DWT.TRAVERSE_TAB_NEXT | DWT.TRAVERSE_TAB_PREVIOUS; | |
3123 Shell shell = getShell (); | |
3124 if (shell.parent !is null) code |= DWT.TRAVERSE_ESCAPE; | |
3125 return code; | |
3126 } | |
3127 | |
3128 bool traverseMnemonic (char key) { | |
3129 return false; | |
3130 } | |
3131 | |
3132 /** | |
3133 * Based on the argument, perform one of the expected platform | |
3134 * traversal action. The argument should be one of the constants: | |
3135 * <code>DWT.TRAVERSE_ESCAPE</code>, <code>DWT.TRAVERSE_RETURN</code>, | |
3136 * <code>DWT.TRAVERSE_TAB_NEXT</code>, <code>DWT.TRAVERSE_TAB_PREVIOUS</code>, | |
3137 * <code>DWT.TRAVERSE_ARROW_NEXT</code> and <code>DWT.TRAVERSE_ARROW_PREVIOUS</code>. | |
3138 * | |
3139 * @param traversal the type of traversal | |
3140 * @return true if the traversal succeeded | |
3141 * | |
3142 * @exception DWTException <ul> | |
3143 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
3144 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
3145 * </ul> | |
3146 */ | |
3147 public bool traverse (int traversal) { | |
3148 checkWidget(); | |
3149 Event event = new Event (); | |
3150 event.doit = true; | |
3151 event.detail = traversal; | |
3152 return traverse (event); | |
3153 } | |
3154 | |
3155 bool traverse (Event event) { | |
3156 sendEvent (DWT.Traverse, event); | |
3157 if (isDisposed ()) return true; | |
3158 if (!event.doit) return false; | |
3159 switch (event.detail) { | |
3160 case DWT.TRAVERSE_NONE: return true; | |
3161 case DWT.TRAVERSE_ESCAPE: return traverseEscape (); | |
3162 case DWT.TRAVERSE_RETURN: return traverseReturn (); | |
3163 case DWT.TRAVERSE_TAB_NEXT: return traverseGroup (true); | |
3164 case DWT.TRAVERSE_TAB_PREVIOUS: return traverseGroup (false); | |
3165 case DWT.TRAVERSE_ARROW_NEXT: return traverseItem (true); | |
3166 case DWT.TRAVERSE_ARROW_PREVIOUS: return traverseItem (false); | |
3167 case DWT.TRAVERSE_MNEMONIC: return traverseMnemonic (event); | |
3168 case DWT.TRAVERSE_PAGE_NEXT: return traversePage (true); | |
3169 case DWT.TRAVERSE_PAGE_PREVIOUS: return traversePage (false); | |
3170 } | |
3171 return false; | |
3172 } | |
3173 | |
3174 bool traverseEscape () { | |
3175 return false; | |
3176 } | |
3177 | |
3178 bool traverseGroup (bool next) { | |
3179 Control root = computeTabRoot (); | |
3180 Control group = computeTabGroup (); | |
3181 Control [] list = root.computeTabList (); | |
3182 int length = list.length; | |
3183 int index = 0; | |
3184 while (index < length) { | |
3185 if (list [index] is group) break; | |
3186 index++; | |
3187 } | |
3188 /* | |
3189 * It is possible (but unlikely), that application | |
3190 * code could have disposed the widget in focus in | |
3191 * or out events. Ensure that a disposed widget is | |
3192 * not accessed. | |
3193 */ | |
3194 if (index is length) return false; | |
3195 int start = index, offset = (next) ? 1 : -1; | |
3196 while ((index = ((index + offset + length) % length)) !is start) { | |
3197 Control control = list [index]; | |
3198 if (!control.isDisposed () && control.setTabGroupFocus ()) { | |
3199 return true; | |
3200 } | |
3201 } | |
3202 if (group.isDisposed ()) return false; | |
3203 return group.setTabGroupFocus (); | |
3204 } | |
3205 | |
3206 bool traverseItem (bool next) { | |
3207 Control [] children = parent._getChildren (); | |
3208 int length = children.length; | |
3209 int index = 0; | |
3210 while (index < length) { | |
3211 if (children [index] is this) break; | |
3212 index++; | |
3213 } | |
3214 /* | |
3215 * It is possible (but unlikely), that application | |
3216 * code could have disposed the widget in focus in | |
3217 * or out events. Ensure that a disposed widget is | |
3218 * not accessed. | |
3219 */ | |
3220 if (index is length) return false; | |
3221 int start = index, offset = (next) ? 1 : -1; | |
3222 while ((index = (index + offset + length) % length) !is start) { | |
3223 Control child = children [index]; | |
3224 if (!child.isDisposed () && child.isTabItem ()) { | |
3225 if (child.setTabItemFocus ()) return true; | |
3226 } | |
3227 } | |
3228 return false; | |
3229 } | |
3230 | |
3231 bool traverseReturn () { | |
3232 return false; | |
3233 } | |
3234 | |
3235 bool traversePage (bool next) { | |
3236 return false; | |
3237 } | |
3238 | |
3239 bool traverseMnemonic (Event event) { | |
3240 return false; | |
3241 } | |
3242 | |
3243 /** | |
3244 * Forces all outstanding paint requests for the widget | |
3245 * to be processed before this method returns. If there | |
3246 * are no outstanding paint request, this method does | |
3247 * nothing. | |
3248 * <p> | |
3249 * Note: This method does not cause a redraw. | |
3250 * </p> | |
3251 * | |
3252 * @exception DWTException <ul> | |
3253 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
3254 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
3255 * </ul> | |
3256 * | |
3257 * @see #redraw() | |
3258 * @see #redraw(int, int, int, int, bool) | |
3259 * @see PaintListener | |
3260 * @see DWT#Paint | |
3261 */ | |
3262 public void update () { | |
3263 checkWidget(); | |
3264 update (false); | |
3265 } | |
3266 | |
3267 void update (bool all) { | |
3268 // checkWidget(); | |
3269 //TODO - not all | |
3270 // OS.HIViewRender (handle); | |
3271 } | |
3272 | |
3273 void updateBackgroundMode () { | |
3274 int oldState = state & PARENT_BACKGROUND; | |
3275 checkBackground (); | |
3276 if (oldState !is (state & PARENT_BACKGROUND)) { | |
3277 setBackground (); | |
3278 } | |
3279 } | |
3280 | |
3281 void updateLayout (bool all) { | |
3282 /* Do nothing */ | |
3283 } | |
3284 | |
3285 } |