Mercurial > projects > dwt-mac
comparison dwt/widgets/Menu.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 |
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.Menu; | |
12 | |
13 import dwt.dwthelper.utils; | |
14 | |
15 | |
16 import dwt.DWT; | |
17 import dwt.DWTException; | |
18 import dwt.events.HelpListener; | |
19 import dwt.events.MenuListener; | |
20 import dwt.graphics.Point; | |
21 import dwt.internal.cocoa.NSEvent; | |
22 import dwt.internal.cocoa.NSMenu; | |
23 import dwt.internal.cocoa.NSMenuItem; | |
24 import dwt.internal.cocoa.NSPoint; | |
25 import dwt.internal.cocoa.NSString; | |
26 import dwt.internal.cocoa.NSView; | |
27 import dwt.internal.cocoa.NSWindow; | |
28 import dwt.internal.cocoa.OS; | |
29 import dwt.internal.cocoa.SWTMenu; | |
30 import dwt.internal.cocoa.SWTMenuItem; | |
31 | |
32 /** | |
33 * Instances of this class are user interface objects that contain | |
34 * menu items. | |
35 * <dl> | |
36 * <dt><b>Styles:</b></dt> | |
37 * <dd>BAR, DROP_DOWN, POP_UP, NO_RADIO_GROUP</dd> | |
38 * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd> | |
39 * <dt><b>Events:</b></dt> | |
40 * <dd>Help, Hide, Show </dd> | |
41 * </dl> | |
42 * <p> | |
43 * Note: Only one of BAR, DROP_DOWN and POP_UP may be specified. | |
44 * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified. | |
45 * </p><p> | |
46 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
47 * </p> | |
48 */ | |
49 public class Menu extends Widget { | |
50 /** | |
51 * the handle to the OS resource | |
52 * (Warning: This field is platform dependent) | |
53 * <p> | |
54 * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT | |
55 * public API. It is marked public only so that it can be shared | |
56 * within the packages provided by DWT. It is not available on all | |
57 * platforms and should never be accessed from application code. | |
58 * </p> | |
59 */ | |
60 NSMenu nsMenu; | |
61 short id; | |
62 int x, y, itemCount; | |
63 // int width, height; | |
64 bool hasLocation, modified, closed; | |
65 MenuItem [] items; | |
66 MenuItem cascade, defaultItem, lastTarget; | |
67 Decorations parent; | |
68 | |
69 /** | |
70 * Constructs a new instance of this class given its parent, | |
71 * and sets the style for the instance so that the instance | |
72 * will be a popup menu on the given parent's shell. | |
73 * | |
74 * @param parent a control which will be the parent of the new instance (cannot be null) | |
75 * | |
76 * @exception IllegalArgumentException <ul> | |
77 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
78 * </ul> | |
79 * @exception DWTException <ul> | |
80 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
81 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
82 * </ul> | |
83 * | |
84 * @see DWT#POP_UP | |
85 * @see Widget#checkSubclass | |
86 * @see Widget#getStyle | |
87 */ | |
88 public Menu (Control parent) { | |
89 this (checkNull (parent).menuShell (), DWT.POP_UP); | |
90 } | |
91 | |
92 /** | |
93 * Constructs a new instance of this class given its parent | |
94 * (which must be a <code>Decorations</code>) and a style value | |
95 * describing its behavior and appearance. | |
96 * <p> | |
97 * The style value is either one of the style constants defined in | |
98 * class <code>DWT</code> which is applicable to instances of this | |
99 * class, or must be built by <em>bitwise OR</em>'ing together | |
100 * (that is, using the <code>int</code> "|" operator) two or more | |
101 * of those <code>DWT</code> style constants. The class description | |
102 * lists the style constants that are applicable to the class. | |
103 * Style bits are also inherited from superclasses. | |
104 * </p> | |
105 * | |
106 * @param parent a decorations control which will be the parent of the new instance (cannot be null) | |
107 * @param style the style of menu to construct | |
108 * | |
109 * @exception IllegalArgumentException <ul> | |
110 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
111 * </ul> | |
112 * @exception DWTException <ul> | |
113 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
114 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
115 * </ul> | |
116 * | |
117 * @see DWT#BAR | |
118 * @see DWT#DROP_DOWN | |
119 * @see DWT#POP_UP | |
120 * @see Widget#checkSubclass | |
121 * @see Widget#getStyle | |
122 */ | |
123 public Menu (Decorations parent, int style) { | |
124 super (parent, checkStyle (style)); | |
125 this.parent = parent; | |
126 createWidget (); | |
127 } | |
128 | |
129 /** | |
130 * Constructs a new instance of this class given its parent | |
131 * (which must be a <code>Menu</code>) and sets the style | |
132 * for the instance so that the instance will be a drop-down | |
133 * menu on the given parent's parent. | |
134 * | |
135 * @param parentMenu a menu which will be the parent of the new instance (cannot be null) | |
136 * | |
137 * @exception IllegalArgumentException <ul> | |
138 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
139 * </ul> | |
140 * @exception DWTException <ul> | |
141 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
142 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
143 * </ul> | |
144 * | |
145 * @see DWT#DROP_DOWN | |
146 * @see Widget#checkSubclass | |
147 * @see Widget#getStyle | |
148 */ | |
149 public Menu (Menu parentMenu) { | |
150 this (checkNull (parentMenu).parent, DWT.DROP_DOWN); | |
151 } | |
152 | |
153 /** | |
154 * Constructs a new instance of this class given its parent | |
155 * (which must be a <code>MenuItem</code>) and sets the style | |
156 * for the instance so that the instance will be a drop-down | |
157 * menu on the given parent's parent menu. | |
158 * | |
159 * @param parentItem a menu item which will be the parent of the new instance (cannot be null) | |
160 * | |
161 * @exception IllegalArgumentException <ul> | |
162 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
163 * </ul> | |
164 * @exception DWTException <ul> | |
165 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
166 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
167 * </ul> | |
168 * | |
169 * @see DWT#DROP_DOWN | |
170 * @see Widget#checkSubclass | |
171 * @see Widget#getStyle | |
172 */ | |
173 public Menu (MenuItem parentItem) { | |
174 this (checkNull (parentItem).parent); | |
175 } | |
176 | |
177 static Control checkNull (Control control) { | |
178 if (control is null) DWT.error (DWT.ERROR_NULL_ARGUMENT); | |
179 return control; | |
180 } | |
181 | |
182 static Menu checkNull (Menu menu) { | |
183 if (menu is null) DWT.error (DWT.ERROR_NULL_ARGUMENT); | |
184 return menu; | |
185 } | |
186 | |
187 static MenuItem checkNull (MenuItem item) { | |
188 if (item is null) DWT.error (DWT.ERROR_NULL_ARGUMENT); | |
189 return item; | |
190 } | |
191 | |
192 static int checkStyle (int style) { | |
193 return checkBits (style, DWT.POP_UP, DWT.BAR, DWT.DROP_DOWN, 0, 0, 0); | |
194 } | |
195 | |
196 void _setVisible (bool visible) { | |
197 if ((style & (DWT.BAR | DWT.DROP_DOWN)) !is 0) return; | |
198 if (visible) { | |
199 Shell shell = getShell (); | |
200 NSWindow window = shell.window; | |
201 NSPoint location = null; | |
202 if (hasLocation) { | |
203 NSView topView = window.contentView(); | |
204 Point shellCoord = display.map(null, shell, new Point(x,y)); | |
205 location = new NSPoint (); | |
206 location.x = shellCoord.x; | |
207 location.y = topView.frame().height - shellCoord.y; | |
208 } else { | |
209 location = window.mouseLocationOutsideOfEventStream(); | |
210 } | |
211 NSEvent nsEvent = NSEvent.otherEventWithType(OS.NSApplicationDefined, location, 0, 0.0, window.windowNumber(), window.graphicsContext(), (short)0, 0, 0); | |
212 NSMenu.static_popUpContextMenu_withEvent_forView_ (nsMenu, nsEvent, shell.view); | |
213 } else { | |
214 nsMenu.cancelTracking (); | |
215 } | |
216 } | |
217 | |
218 /** | |
219 * Adds the listener to the collection of listeners who will | |
220 * be notified when help events are generated for the control, | |
221 * by sending it one of the messages defined in the | |
222 * <code>HelpListener</code> 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 HelpListener | |
235 * @see #removeHelpListener | |
236 */ | |
237 public void addHelpListener (HelpListener listener) { | |
238 checkWidget (); | |
239 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
240 TypedListener typedListener = new TypedListener (listener); | |
241 addListener (DWT.Help, typedListener); | |
242 } | |
243 | |
244 /** | |
245 * Adds the listener to the collection of listeners who will | |
246 * be notified when menus are hidden or shown, by sending it | |
247 * one of the messages defined in the <code>MenuListener</code> | |
248 * interface. | |
249 * | |
250 * @param listener the listener which should be notified | |
251 * | |
252 * @exception IllegalArgumentException <ul> | |
253 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
254 * </ul> | |
255 * @exception DWTException <ul> | |
256 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
257 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
258 * </ul> | |
259 * | |
260 * @see MenuListener | |
261 * @see #removeMenuListener | |
262 */ | |
263 public void addMenuListener (MenuListener listener) { | |
264 checkWidget (); | |
265 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
266 TypedListener typedListener = new TypedListener (listener); | |
267 addListener (DWT.Hide,typedListener); | |
268 addListener (DWT.Show,typedListener); | |
269 } | |
270 | |
271 void createHandle () { | |
272 // display.addMenu (this); | |
273 SWTMenu widget = (SWTMenu)new SWTMenu().alloc(); | |
274 widget.initWithTitle(NSString.stringWith("")); | |
275 widget.setAutoenablesItems(false); | |
276 widget.setTag(jniRef); | |
277 widget.setDelegate(widget); | |
278 nsMenu = widget; | |
279 } | |
280 | |
281 void createItem (MenuItem item, int index) { | |
282 checkWidget (); | |
283 if (!(0 <= index && index <= itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
284 NSMenuItem nsItem = null; | |
285 if ((item.style & DWT.SEPARATOR) !is 0) { | |
286 nsItem = NSMenuItem.separatorItem(); | |
287 nsItem.retain(); | |
288 } else { | |
289 nsItem = (NSMenuItem)new SWTMenuItem().alloc(); | |
290 nsItem.initWithTitle(NSString.stringWith(""), 0, NSString.stringWith("")); | |
291 nsItem.setTarget(nsItem); | |
292 nsItem.setAction(OS.sel_sendSelection); | |
293 item.createJNIRef(); | |
294 nsItem.setTag(item.jniRef); | |
295 } | |
296 item.nsItem = nsItem; | |
297 nsMenu.insertItem(nsItem, index); | |
298 if (itemCount is items.length) { | |
299 MenuItem [] newItems = new MenuItem [items.length + 4]; | |
300 System.arraycopy (items, 0, newItems, 0, items.length); | |
301 items = newItems; | |
302 } | |
303 System.arraycopy (items, index, items, index + 1, itemCount++ - index); | |
304 items [index] = item; | |
305 | |
306 NSMenu emptyMenu = item.createEmptyMenu (); | |
307 if (emptyMenu !is null) { | |
308 item.nsItem.setSubmenu (emptyMenu); | |
309 } | |
310 } | |
311 | |
312 void createWidget () { | |
313 checkOrientation (parent); | |
314 super.createWidget (); | |
315 items = new MenuItem [4]; | |
316 } | |
317 | |
318 void destroyItem (MenuItem item) { | |
319 int index = 0; | |
320 while (index < itemCount) { | |
321 if (items [index] is item) break; | |
322 index++; | |
323 } | |
324 if (index is itemCount) return; | |
325 System.arraycopy (items, index + 1, items, index, --itemCount - index); | |
326 items [itemCount] = null; | |
327 if (itemCount is 0) items = new MenuItem [4]; | |
328 nsMenu.removeItem (item.nsItem); | |
329 } | |
330 | |
331 void destroyWidget () { | |
332 NSMenu nsMenu = this.nsMenu; | |
333 releaseHandle (); | |
334 if (nsMenu !is null) { | |
335 nsMenu.release(); | |
336 } | |
337 } | |
338 | |
339 void fixMenus (Decorations newParent) { | |
340 this.parent = newParent; | |
341 } | |
342 | |
343 /** | |
344 * Returns the default menu item or null if none has | |
345 * been previously set. | |
346 * | |
347 * @return the default menu item. | |
348 * | |
349 * </ul> | |
350 * @exception DWTException <ul> | |
351 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
352 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
353 * </ul> | |
354 */ | |
355 public MenuItem getDefaultItem () { | |
356 checkWidget(); | |
357 return defaultItem; | |
358 } | |
359 | |
360 /** | |
361 * Returns <code>true</code> if the receiver is enabled, and | |
362 * <code>false</code> otherwise. A disabled menu is typically | |
363 * not selectable from the user interface and draws with an | |
364 * inactive or "grayed" look. | |
365 * | |
366 * @return the receiver's enabled state | |
367 * | |
368 * @exception DWTException <ul> | |
369 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
370 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
371 * </ul> | |
372 * | |
373 * @see #isEnabled | |
374 */ | |
375 public bool getEnabled () { | |
376 checkWidget(); | |
377 return (state & DISABLED) is 0; | |
378 } | |
379 | |
380 /** | |
381 * Returns the item at the given, zero-relative index in the | |
382 * receiver. Throws an exception if the index is out of range. | |
383 * | |
384 * @param index the index of the item to return | |
385 * @return the item at the given index | |
386 * | |
387 * @exception IllegalArgumentException <ul> | |
388 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li> | |
389 * </ul> | |
390 * @exception DWTException <ul> | |
391 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
392 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
393 * </ul> | |
394 */ | |
395 public MenuItem getItem (int index) { | |
396 checkWidget (); | |
397 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); | |
398 return items [index]; | |
399 } | |
400 | |
401 /** | |
402 * Returns the number of items contained in the receiver. | |
403 * | |
404 * @return the number of items | |
405 * | |
406 * @exception DWTException <ul> | |
407 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
408 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
409 * </ul> | |
410 */ | |
411 public int getItemCount () { | |
412 checkWidget (); | |
413 return itemCount; | |
414 } | |
415 | |
416 /** | |
417 * Returns a (possibly empty) array of <code>MenuItem</code>s which | |
418 * are the items in the receiver. | |
419 * <p> | |
420 * Note: This is not the actual structure used by the receiver | |
421 * to maintain its list of items, so modifying the array will | |
422 * not affect the receiver. | |
423 * </p> | |
424 * | |
425 * @return the items in the receiver | |
426 * | |
427 * @exception DWTException <ul> | |
428 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
429 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
430 * </ul> | |
431 */ | |
432 public MenuItem [] getItems () { | |
433 checkWidget (); | |
434 MenuItem [] result = new MenuItem [itemCount]; | |
435 int index = 0; | |
436 if (items !is null) { | |
437 for (int i = 0; i < itemCount; i++) { | |
438 MenuItem item = items [i]; | |
439 if (item !is null && !item.isDisposed ()) { | |
440 result [index++] = item; | |
441 } | |
442 } | |
443 } | |
444 if (index !is result.length) { | |
445 MenuItem [] newItems = new MenuItem[index]; | |
446 System.arraycopy(result, 0, newItems, 0, index); | |
447 result = newItems; | |
448 } | |
449 return result; | |
450 } | |
451 | |
452 String getNameText () { | |
453 String result = ""; | |
454 MenuItem [] items = getItems (); | |
455 int length = items.length; | |
456 if (length > 0) { | |
457 for (int i=0; i<length-1; i++) { | |
458 result = result + items [i].getNameText() + ", "; | |
459 } | |
460 result = result + items [length-1].getNameText (); | |
461 } | |
462 return result; | |
463 } | |
464 | |
465 /** | |
466 * Returns the receiver's parent, which must be a <code>Decorations</code>. | |
467 * | |
468 * @return the receiver's parent | |
469 * | |
470 * @exception DWTException <ul> | |
471 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
472 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
473 * </ul> | |
474 */ | |
475 public Decorations getParent () { | |
476 checkWidget (); | |
477 return parent; | |
478 } | |
479 | |
480 /** | |
481 * Returns the receiver's parent item, which must be a | |
482 * <code>MenuItem</code> or null when the receiver is a | |
483 * root. | |
484 * | |
485 * @return the receiver's parent item | |
486 * | |
487 * @exception DWTException <ul> | |
488 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
489 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
490 * </ul> | |
491 */ | |
492 public MenuItem getParentItem () { | |
493 checkWidget (); | |
494 return cascade; | |
495 } | |
496 | |
497 /** | |
498 * Returns the receiver's parent item, which must be a | |
499 * <code>Menu</code> or null when the receiver is a | |
500 * root. | |
501 * | |
502 * @return the receiver's parent item | |
503 * | |
504 * @exception DWTException <ul> | |
505 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
506 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
507 * </ul> | |
508 */ | |
509 public Menu getParentMenu () { | |
510 checkWidget (); | |
511 if (cascade !is null) return cascade.parent; | |
512 return null; | |
513 } | |
514 | |
515 /** | |
516 * Returns the receiver's shell. For all controls other than | |
517 * shells, this simply returns the control's nearest ancestor | |
518 * shell. Shells return themselves, even if they are children | |
519 * of other shells. | |
520 * | |
521 * @return the receiver's shell | |
522 * | |
523 * @exception DWTException <ul> | |
524 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
525 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
526 * </ul> | |
527 * | |
528 * @see #getParent | |
529 */ | |
530 public Shell getShell () { | |
531 checkWidget (); | |
532 return parent.getShell (); | |
533 } | |
534 | |
535 /** | |
536 * Returns <code>true</code> if the receiver is visible, and | |
537 * <code>false</code> otherwise. | |
538 * <p> | |
539 * If one of the receiver's ancestors is not visible or some | |
540 * other condition makes the receiver not visible, this method | |
541 * may still indicate that it is considered visible even though | |
542 * it may not actually be showing. | |
543 * </p> | |
544 * | |
545 * @return the receiver's visibility state | |
546 * | |
547 * @exception DWTException <ul> | |
548 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
549 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
550 * </ul> | |
551 */ | |
552 public bool getVisible () { | |
553 checkWidget (); | |
554 if ((style & DWT.BAR) !is 0) { | |
555 return this is parent.menuShell ().menuBar; | |
556 } | |
557 if ((style & DWT.POP_UP) !is 0) { | |
558 // Menu [] popups = display.popups; | |
559 // if (popups is null) return false; | |
560 // for (int i=0; i<popups.length; i++) { | |
561 // if (popups [i] is this) return true; | |
562 // } | |
563 } | |
564 // MenuTrackingData outData = new MenuTrackingData (); | |
565 // return OS.GetMenuTrackingData (handle, outData) is OS.noErr; | |
566 return false; | |
567 } | |
568 | |
569 | |
570 /** | |
571 * Searches the receiver's list starting at the first item | |
572 * (index 0) until an item is found that is equal to the | |
573 * argument, and returns the index of that item. If no item | |
574 * is found, returns -1. | |
575 * | |
576 * @param item the search item | |
577 * @return the index of the item | |
578 * | |
579 * @exception IllegalArgumentException <ul> | |
580 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
581 * </ul> | |
582 * @exception DWTException <ul> | |
583 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
584 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
585 * </ul> | |
586 */ | |
587 public int indexOf (MenuItem item) { | |
588 checkWidget (); | |
589 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | |
590 for (int i=0; i<itemCount; i++) { | |
591 if (items [i] is item) return i; | |
592 } | |
593 return -1; | |
594 } | |
595 | |
596 /** | |
597 * Returns <code>true</code> if the receiver is enabled and all | |
598 * of the receiver's ancestors are enabled, and <code>false</code> | |
599 * otherwise. A disabled menu is typically not selectable from the | |
600 * user interface and draws with an inactive or "grayed" look. | |
601 * | |
602 * @return the receiver's enabled state | |
603 * | |
604 * @exception DWTException <ul> | |
605 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
606 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
607 * </ul> | |
608 * | |
609 * @see #getEnabled | |
610 */ | |
611 public bool isEnabled () { | |
612 checkWidget (); | |
613 Menu parentMenu = getParentMenu (); | |
614 if (parentMenu is null) { | |
615 return getEnabled () && parent.isEnabled (); | |
616 } | |
617 return getEnabled () && parentMenu.isEnabled (); | |
618 } | |
619 | |
620 /** | |
621 * Returns <code>true</code> if the receiver is visible and all | |
622 * of the receiver's ancestors are visible and <code>false</code> | |
623 * otherwise. | |
624 * | |
625 * @return the receiver's visibility state | |
626 * | |
627 * @exception DWTException <ul> | |
628 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
629 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
630 * </ul> | |
631 * | |
632 * @see #getVisible | |
633 */ | |
634 public bool isVisible () { | |
635 checkWidget (); | |
636 return getVisible (); | |
637 } | |
638 | |
639 void menu_willHighlightItem(int menu, int itemID) { | |
640 int jniRef = OS.objc_msgSend(itemID, OS.sel_tag); | |
641 if (jniRef !is -1 && jniRef !is 0) { | |
642 Object object = OS.JNIGetObject(jniRef); | |
643 if (object instanceof MenuItem) { | |
644 MenuItem item = (MenuItem)object; | |
645 item.sendEvent (DWT.Arm); | |
646 } | |
647 } | |
648 } | |
649 | |
650 void menuNeedsUpdate(int menu) { | |
651 sendEvent (DWT.Show); | |
652 } | |
653 | |
654 void menuWillClose(int menu) { | |
655 sendEvent (DWT.Hide); | |
656 } | |
657 | |
658 void menuWillOpen(int menu) { | |
659 } | |
660 | |
661 int modifierIndex (String accelText) { | |
662 int start = accelText.length () - 1; | |
663 int index = start; | |
664 while (index >= 0) { | |
665 char c = accelText.charAt (index); | |
666 switch (c) { | |
667 case ' ': | |
668 if (index !is start) return index; | |
669 break; | |
670 case '\u2303': | |
671 case '\u2325': | |
672 case '\u21E7': | |
673 case '\u2318': | |
674 return index; | |
675 } | |
676 index--; | |
677 } | |
678 return -1; | |
679 } | |
680 | |
681 int numberOfItemsInMenu(int menu) { | |
682 System.out.println("numver"); | |
683 return 4; | |
684 } | |
685 | |
686 void releaseChildren (bool destroy) { | |
687 if (items !is null) { | |
688 for (int i=0; i<items.length; i++) { | |
689 MenuItem item = items [i]; | |
690 if (item !is null && !item.isDisposed ()) { | |
691 item.release (false); | |
692 } | |
693 } | |
694 items = null; | |
695 } | |
696 super.releaseChildren (destroy); | |
697 } | |
698 | |
699 void releaseHandle () { | |
700 super.releaseHandle (); | |
701 nsMenu = null; | |
702 } | |
703 | |
704 void releaseParent () { | |
705 super.releaseParent (); | |
706 if (cascade !is null) cascade.setMenu (null); | |
707 if ((style & DWT.BAR) !is 0 && this is parent.menuBar) { | |
708 parent.setMenuBar (null); | |
709 } | |
710 } | |
711 | |
712 void releaseWidget () { | |
713 super.releaseWidget (); | |
714 // display.removeMenu (this); | |
715 parent = null; | |
716 cascade = defaultItem = lastTarget = null; | |
717 } | |
718 | |
719 /** | |
720 * Removes the listener from the collection of listeners who will | |
721 * be notified when the help events are generated for the control. | |
722 * | |
723 * @param listener the listener which should no longer be notified | |
724 * | |
725 * @exception IllegalArgumentException <ul> | |
726 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
727 * </ul> | |
728 * @exception DWTException <ul> | |
729 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
730 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
731 * </ul> | |
732 * | |
733 * @see HelpListener | |
734 * @see #addHelpListener | |
735 */ | |
736 public void removeHelpListener (HelpListener listener) { | |
737 checkWidget (); | |
738 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
739 if (eventTable is null) return; | |
740 eventTable.unhook (DWT.Help, listener); | |
741 } | |
742 | |
743 /** | |
744 * Removes the listener from the collection of listeners who will | |
745 * be notified when the menu events are generated for the control. | |
746 * | |
747 * @param listener the listener which should no longer be notified | |
748 * | |
749 * @exception IllegalArgumentException <ul> | |
750 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
751 * </ul> | |
752 * @exception DWTException <ul> | |
753 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
754 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
755 * </ul> | |
756 * | |
757 * @see MenuListener | |
758 * @see #addMenuListener | |
759 */ | |
760 public void removeMenuListener (MenuListener listener) { | |
761 checkWidget (); | |
762 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); | |
763 if (eventTable is null) return; | |
764 eventTable.unhook (DWT.Hide, listener); | |
765 eventTable.unhook (DWT.Show, listener); | |
766 } | |
767 | |
768 /** | |
769 * Sets the default menu item to the argument or removes | |
770 * the default emphasis when the argument is <code>null</code>. | |
771 * | |
772 * @param item the default menu item or null | |
773 * | |
774 * @exception IllegalArgumentException <ul> | |
775 * <li>ERROR_INVALID_ARGUMENT - if the menu item has been disposed</li> | |
776 * </ul> | |
777 * @exception DWTException <ul> | |
778 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
779 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
780 * </ul> | |
781 */ | |
782 public void setDefaultItem (MenuItem item) { | |
783 checkWidget(); | |
784 if (item !is null && item.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); | |
785 defaultItem = item; | |
786 } | |
787 | |
788 /** | |
789 * Enables the receiver if the argument is <code>true</code>, | |
790 * and disables it otherwise. A disabled menu is typically | |
791 * not selectable from the user interface and draws with an | |
792 * inactive or "grayed" look. | |
793 * | |
794 * @param enabled the new enabled state | |
795 * | |
796 * @exception DWTException <ul> | |
797 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
798 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
799 * </ul> | |
800 */ | |
801 public void setEnabled (bool enabled) { | |
802 checkWidget(); | |
803 if (enabled) { | |
804 state &= ~DISABLED; | |
805 //OS.EnableMenuItem (handle, (short)0); | |
806 } else { | |
807 state |= DISABLED; | |
808 //OS.DisableMenuItem (handle, (short)0); | |
809 } | |
810 } | |
811 | |
812 /** | |
813 * Sets the location of the receiver, which must be a popup, | |
814 * to the point specified by the arguments which are relative | |
815 * to the display. | |
816 * <p> | |
817 * Note that this is different from most widgets where the | |
818 * location of the widget is relative to the parent. | |
819 * </p><p> | |
820 * Note that the platform window manager ultimately has control | |
821 * over the location of popup menus. | |
822 * </p> | |
823 * | |
824 * @param x the new x coordinate for the receiver | |
825 * @param y the new y coordinate for the receiver | |
826 * | |
827 * @exception DWTException <ul> | |
828 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
829 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
830 * </ul> | |
831 */ | |
832 public void setLocation (int x, int y) { | |
833 checkWidget (); | |
834 this.x = x; | |
835 this.y = y; | |
836 hasLocation = true; | |
837 } | |
838 | |
839 /** | |
840 * Sets the location of the receiver, which must be a popup, | |
841 * to the point specified by the argument which is relative | |
842 * to the display. | |
843 * <p> | |
844 * Note that this is different from most widgets where the | |
845 * location of the widget is relative to the parent. | |
846 * </p><p> | |
847 * Note that the platform window manager ultimately has control | |
848 * over the location of popup menus. | |
849 * </p> | |
850 * | |
851 * @param location the new location for the receiver | |
852 * | |
853 * @exception IllegalArgumentException <ul> | |
854 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> | |
855 * </ul> | |
856 * @exception DWTException <ul> | |
857 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
858 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
859 * </ul> | |
860 * | |
861 * @since 2.1 | |
862 */ | |
863 public void setLocation (Point location) { | |
864 checkWidget (); | |
865 if (location is null) error (DWT.ERROR_NULL_ARGUMENT); | |
866 setLocation (location.x, location.y); | |
867 } | |
868 | |
869 /** | |
870 * Marks the receiver as visible if the argument is <code>true</code>, | |
871 * and marks it invisible otherwise. | |
872 * <p> | |
873 * If one of the receiver's ancestors is not visible or some | |
874 * other condition makes the receiver not visible, marking | |
875 * it visible may not actually cause it to be displayed. | |
876 * </p> | |
877 * | |
878 * @param visible the new visibility state | |
879 * | |
880 * @exception DWTException <ul> | |
881 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
882 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
883 * </ul> | |
884 */ | |
885 public void setVisible (bool visible) { | |
886 checkWidget (); | |
887 if ((style & (DWT.BAR | DWT.DROP_DOWN)) !is 0) return; | |
888 if (visible) { | |
889 // display.addPopup (this); | |
890 //TODO -WRONG | |
891 _setVisible (true); | |
892 } else { | |
893 // display.removePopup (this); | |
894 _setVisible (false); | |
895 } | |
896 } | |
897 | |
898 } |