Mercurial > projects > dwt-mac
comparison dwt/widgets/MenuItem.d @ 45:d8635bb48c7c
Merge with SWT 3.5
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 01 Dec 2008 17:07:00 +0100 |
parents | 642f460a0908 |
children | 4444d15131d5 |
comparison
equal
deleted
inserted
replaced
44:ca5e494f2bbf | 45:d8635bb48c7c |
---|---|
1 /******************************************************************************* | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | 2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
3 * All rights reserved. This program and the accompanying materials | 3 * All rights reserved. This program and the accompanying materials |
4 * are made available under the terms of the Eclipse Public License v1.0 | 4 * are made available under the terms of the Eclipse Public License v1.0 |
5 * which accompanies this distribution, and is available at | 5 * which accompanies this distribution, and is available at |
6 * http://www.eclipse.org/legal/epl-v10.html | 6 * http://www.eclipse.org/legal/epl-v10.html |
7 * | 7 * |
8 * Contributors: | 8 * Contributors: |
9 * IBM Corporation - initial API and implementation | 9 * IBM Corporation - initial API and implementation |
10 * | 10 * |
11 * Port to the D programming language: | 11 * Port to the D programming language: |
12 * Jacob Carlborg <jacob.carlborg@gmail.com> | 12 * Jacob Carlborg <doob@me.com> |
13 *******************************************************************************/ | 13 *******************************************************************************/ |
14 module dwt.widgets.MenuItem; | 14 module dwt.widgets.MenuItem; |
15 | 15 |
16 | 16 |
17 import dwt.DWT; | 17 import dwt.DWT; |
18 import dwt.DWTException; | 18 import dwt.DWTException; |
19 import dwt.events.ArmListener; | 19 import dwt.events.ArmListener; |
20 import dwt.events.HelpListener; | 20 import dwt.events.HelpListener; |
21 import dwt.events.SelectionEvent; | 21 import dwt.events.SelectionEvent; |
22 import dwt.events.SelectionListener; | 22 import dwt.events.SelectionListener; |
23 import dwt.graphics.Image; | 23 import dwt.graphics.Image; |
24 import dwt.internal.cocoa.NSApplication; | |
25 import dwt.internal.cocoa.NSEvent; | |
24 import dwt.internal.cocoa.NSMenu; | 26 import dwt.internal.cocoa.NSMenu; |
25 import dwt.internal.cocoa.NSMenuItem; | 27 import dwt.internal.cocoa.NSMenuItem; |
26 import dwt.internal.cocoa.NSString; | 28 import dwt.internal.cocoa.NSString; |
27 import dwt.internal.cocoa.OS; | 29 import dwt.internal.cocoa.OS; |
28 import dwt.internal.cocoa.SWTMenu; | 30 import dwt.internal.cocoa.SWTMenu; |
49 * Note: Only one of the styles CHECK, CASCADE, PUSH, RADIO and SEPARATOR | 51 * Note: Only one of the styles CHECK, CASCADE, PUSH, RADIO and SEPARATOR |
50 * may be specified. | 52 * may be specified. |
51 * </p><p> | 53 * </p><p> |
52 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | 54 * IMPORTANT: This class is <em>not</em> intended to be subclassed. |
53 * </p> | 55 * </p> |
56 * | |
57 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
54 */ | 58 */ |
55 public class MenuItem : Item { | 59 public class MenuItem : Item { |
56 NSMenuItem nsItem; | 60 NSMenuItem nsItem; |
57 Menu parent, menu; | 61 Menu parent, menu; |
58 int accelerator; | 62 int accelerator; |
59 // int x, y, width, height; | |
60 | 63 |
61 /** | 64 /** |
62 * Constructs a new instance of this class given its parent | 65 * Constructs a new instance of this class given its parent |
63 * (which must be a <code>Menu</code>) and a style value | 66 * (which must be a <code>Menu</code>) and a style value |
64 * describing its behavior and appearance. The item is added | 67 * describing its behavior and appearance. The item is added |
237 return cast(NSMenu) (new SWTMenu ()).alloc ().init (); | 240 return cast(NSMenu) (new SWTMenu ()).alloc ().init (); |
238 } | 241 } |
239 return null; | 242 return null; |
240 } | 243 } |
241 | 244 |
245 void deregister () { | |
246 super.deregister (); | |
247 display.removeWidget (nsItem); | |
248 } | |
249 | |
242 void destroyWidget () { | 250 void destroyWidget () { |
243 parent.destroyItem (this); | 251 parent.destroyItem (this); |
244 releaseHandle (); | 252 releaseHandle (); |
245 } | 253 } |
246 | 254 |
338 * </ul> | 346 * </ul> |
339 */ | 347 */ |
340 public bool getSelection () { | 348 public bool getSelection () { |
341 checkWidget (); | 349 checkWidget (); |
342 if ((style & (DWT.CHECK | DWT.RADIO)) is 0) return false; | 350 if ((style & (DWT.CHECK | DWT.RADIO)) is 0) return false; |
343 return (cast(NSMenuItem)nsItem).state() is OS.NSOnState; | 351 return nsItem.state() is OS.NSOnState; |
344 } | 352 } |
345 | |
346 //int kEventProcessCommand (int nextHandler, int theEvent, int userData) { | |
347 // //TEMPORARY CODE | |
348 // if (!isEnabled ()) return OS.noErr; | |
349 // | |
350 // if ((style & DWT.CHECK) !is 0) { | |
351 // setSelection (!getSelection ()); | |
352 // } else { | |
353 // if ((style & DWT.RADIO) !is 0) { | |
354 // if ((parent.getStyle () & DWT.NO_RADIO_GROUP) !is 0) { | |
355 // setSelection (!getSelection ()); | |
356 // } else { | |
357 // selectRadio (); | |
358 // } | |
359 // } | |
360 // } | |
361 // int [] modifiers = new int [1]; | |
362 // OS.GetEventParameter (theEvent, OS.kEventParamKeyModifiers, OS.typeUInt32, null, 4, null, modifiers); | |
363 // Event event = new Event (); | |
364 // setInputState (event, cast(short) 0, OS.GetCurrentEventButtonState (), modifiers [0]); | |
365 // postEvent (DWT.Selection, event); | |
366 // return OS.noErr; | |
367 //} | |
368 | 353 |
369 /** | 354 /** |
370 * Returns <code>true</code> if the receiver is enabled and all | 355 * Returns <code>true</code> if the receiver is enabled and all |
371 * of the receiver's ancestors are enabled, and <code>false</code> | 356 * of the receiver's ancestors are enabled, and <code>false</code> |
372 * otherwise. A disabled menu item is typically not selectable from the | 357 * otherwise. A disabled menu item is typically not selectable from the |
383 */ | 368 */ |
384 public bool isEnabled () { | 369 public bool isEnabled () { |
385 return getEnabled () && parent.isEnabled (); | 370 return getEnabled () && parent.isEnabled (); |
386 } | 371 } |
387 | 372 |
388 //int keyGlyph (int key) { | 373 int keyChar (int key) { |
389 // switch (key) { | 374 //TODO - use the NS key constants |
390 // case DWT.BS: return OS.kMenuDeleteLeftGlyph; | 375 switch (key) { |
391 // case DWT.CR: return OS.kMenuReturnGlyph; | 376 case DWT.BS: return OS.NSBackspaceCharacter; |
392 // case DWT.DEL: return OS.kMenuDeleteRightGlyph; | 377 case DWT.CR: return OS.NSCarriageReturnCharacter; |
393 // case DWT.ESC: return OS.kMenuEscapeGlyph; | 378 case DWT.DEL: return OS.NSDeleteCharacter; |
394 // case DWT.LF: return OS.kMenuReturnGlyph; | 379 case DWT.ESC: return DWT.ESC; |
395 // case DWT.TAB: return OS.kMenuTabRightGlyph; | 380 case DWT.LF: return OS.NSNewlineCharacter; |
381 case DWT.TAB: return OS.NSTabCharacter; | |
396 // case ' ': return OS.kMenuBlankGlyph; | 382 // case ' ': return OS.kMenuBlankGlyph; |
397 //// case ' ': return OS.kMenuSpaceGlyph; | 383 // case ' ': return OS.kMenuSpaceGlyph; |
398 // case DWT.ALT: return OS.kMenuOptionGlyph; | 384 case DWT.ALT: return 0x2325; |
399 // case DWT.SHIFT: return OS.kMenuShiftGlyph; | 385 case DWT.SHIFT: return 0x21E7; |
400 // case DWT.CONTROL: return OS.kMenuControlISOGlyph; | 386 case DWT.CONTROL: return 0xF2303; |
401 // case DWT.COMMAND: return OS.kMenuCommandGlyph; | 387 case DWT.COMMAND: return 0x2318; |
402 // case DWT.ARROW_UP: return OS.kMenuUpArrowGlyph; | 388 case DWT.ARROW_UP: return 0x2191; |
403 // case DWT.ARROW_DOWN: return OS.kMenuDownArrowGlyph; | 389 case DWT.ARROW_DOWN: return 0x2193; |
404 // case DWT.ARROW_LEFT: return OS.kMenuLeftArrowGlyph; | 390 case DWT.ARROW_LEFT: return 0x2190; |
405 // case DWT.ARROW_RIGHT: return OS.kMenuRightArrowGlyph; | 391 case DWT.ARROW_RIGHT: return 0x2192; |
406 // case DWT.PAGE_UP: return OS.kMenuPageUpGlyph; | 392 case DWT.PAGE_UP: return 0x21DE; |
407 // case DWT.PAGE_DOWN: return OS.kMenuPageDownGlyph; | 393 case DWT.PAGE_DOWN: return 0x21DF; |
408 // case DWT.F1: return OS.kMenuF1Glyph; | 394 case DWT.KEYPAD_CR: return OS.NSEnterCharacter; |
409 // case DWT.F2: return OS.kMenuF2Glyph; | 395 case DWT.HELP: return OS.NSHelpFunctionKey; |
410 // case DWT.F3: return OS.kMenuF3Glyph; | 396 case DWT.HOME: return 0xF729; |
411 // case DWT.F4: return OS.kMenuF4Glyph; | 397 case DWT.END: return 0xF72B; |
412 // case DWT.F5: return OS.kMenuF5Glyph; | 398 // case DWT.CAPS_LOCK: return ??; |
413 // case DWT.F6: return OS.kMenuF6Glyph; | 399 case DWT.F1: return 0xF704; |
414 // case DWT.F7: return OS.kMenuF7Glyph; | 400 case DWT.F2: return 0xF705; |
415 // case DWT.F8: return OS.kMenuF8Glyph; | 401 case DWT.F3: return 0xF706; |
416 // case DWT.F9: return OS.kMenuF9Glyph; | 402 case DWT.F4: return 0xF707; |
417 // case DWT.F10: return OS.kMenuF10Glyph; | 403 case DWT.F5: return 0xF708; |
418 // case DWT.F11: return OS.kMenuF11Glyph; | 404 case DWT.F6: return 0xF709; |
419 // case DWT.F12: return OS.kMenuF12Glyph; | 405 case DWT.F7: return 0xF70A; |
420 // } | 406 case DWT.F8: return 0xF70B; |
421 // return OS.kMenuNullGlyph; | 407 case DWT.F9: return 0xF70C; |
422 //} | 408 case DWT.F10: return 0xF70D; |
409 case DWT.F11: return 0xF70E; | |
410 case DWT.F12: return 0xF70F; | |
411 case DWT.F13: return 0xF710; | |
412 case DWT.F14: return 0xF711; | |
413 case DWT.F15: return 0xF712; | |
414 /* | |
415 * The following lines are intentionally commented. | |
416 */ | |
417 // case DWT.INSERT: return ??; | |
418 } | |
419 return 0; | |
420 } | |
421 | |
422 | |
423 void register () { | |
424 super.register (); | |
425 display.addWidget (nsItem, this); | |
426 } | |
423 | 427 |
424 void releaseHandle () { | 428 void releaseHandle () { |
425 super.releaseHandle (); | 429 super.releaseHandle (); |
426 if (nsItem !is null) nsItem.release(); | 430 if (nsItem !is null) nsItem.release(); |
427 nsItem = null; | 431 nsItem = null; |
537 selectRadio (); | 541 selectRadio (); |
538 } | 542 } |
539 } | 543 } |
540 } | 544 } |
541 Event event = new Event (); | 545 Event event = new Event (); |
542 //TODO state mask | 546 NSEvent nsEvent = NSApplication.sharedApplication ().currentEvent (); |
543 // setInputState (event, cast(short) 0, OS.GetCurrentEventButtonState (), modifiers [0]); | 547 if (nsEvent !is null) setInputState (event, nsEvent, 0); |
544 postEvent (DWT.Selection, event); | 548 postEvent (DWT.Selection, event); |
545 } | 549 } |
546 | 550 |
547 /** | 551 /** |
548 * Sets the widget accelerator. An accelerator is the bit-wise | 552 * Sets the widget accelerator. An accelerator is the bit-wise |
560 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | 564 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
561 * </ul> | 565 * </ul> |
562 */ | 566 */ |
563 public void setAccelerator (int accelerator) { | 567 public void setAccelerator (int accelerator) { |
564 checkWidget (); | 568 checkWidget (); |
569 if (this.accelerator is accelerator) return; | |
565 this.accelerator = accelerator; | 570 this.accelerator = accelerator; |
566 int key = accelerator & DWT.KEY_MASK; | 571 int key = accelerator & DWT.KEY_MASK; |
567 int virtualKey = Display.untranslateKey (key); | 572 int virtualKey = keyChar (key); |
568 NSString str = null; | 573 NSString str = null; |
569 if (virtualKey !is 0) { | 574 if (virtualKey !is 0) { |
570 str = NSString.stringWith (Integer.toString(virtualKey)); | 575 str = NSString.stringWith (Integer.toString(virtualKey)); |
571 } else { | 576 } else { |
572 str = NSString.stringWith (Integer.toString(key)).lowercaseString(); | 577 str = NSString.stringWith (Integer.toString(key)); |
573 } | 578 } |
574 nsItem.setKeyEquivalent (str); | 579 nsItem.setKeyEquivalent (str.lowercaseString()); |
575 int mask = 0; | 580 int mask = 0; |
576 if ((accelerator & DWT.SHIFT) !is 0) mask |= OS.NSShiftKeyMask; | 581 if ((accelerator & DWT.SHIFT) !is 0) mask |= OS.NSShiftKeyMask; |
577 if ((accelerator & DWT.CONTROL) !is 0) mask |= OS.NSControlKeyMask; | 582 if ((accelerator & DWT.CONTROL) !is 0) mask |= OS.NSControlKeyMask; |
578 // if ((accelerator & DWT.COMMAND) !is 0) mask &= ~OS.kMenuNoCommandModifier; | |
579 if ((accelerator & DWT.COMMAND) !is 0) mask |= OS.NSCommandKeyMask; | 583 if ((accelerator & DWT.COMMAND) !is 0) mask |= OS.NSCommandKeyMask; |
580 if ((accelerator & DWT.ALT) !is 0) mask |= OS.NSAlternateKeyMask; | 584 if ((accelerator & DWT.ALT) !is 0) mask |= OS.NSAlternateKeyMask; |
581 nsItem.setKeyEquivalentModifierMask (cast(NSUInteger) mask); | 585 nsItem.setKeyEquivalentModifierMask (cast(NSUInteger) mask); |
586 nsItem.setHidden (false); | |
582 if ((this.accelerator is 0 && accelerator !is 0) || (this.accelerator !is 0 && accelerator is 0)) { | 587 if ((this.accelerator is 0 && accelerator !is 0) || (this.accelerator !is 0 && accelerator is 0)) { |
583 updateText (); | 588 updateText (); |
584 } | 589 } |
585 } | 590 } |
586 | 591 |
597 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | 602 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
598 * </ul> | 603 * </ul> |
599 */ | 604 */ |
600 public void setEnabled (bool enabled) { | 605 public void setEnabled (bool enabled) { |
601 checkWidget (); | 606 checkWidget (); |
602 (cast(NSMenuItem)nsItem).setEnabled(enabled); | 607 if (enabled) { |
608 state &= ~DISABLED; | |
609 } else { | |
610 state |= DISABLED; | |
611 } | |
612 nsItem.setEnabled(enabled); | |
603 } | 613 } |
604 | 614 |
605 /** | 615 /** |
606 * Sets the image the receiver will display to the argument. | 616 * Sets the image the receiver will display to the argument. |
607 * <p> | 617 * <p> |
618 */ | 628 */ |
619 public void setImage (Image image) { | 629 public void setImage (Image image) { |
620 checkWidget (); | 630 checkWidget (); |
621 if ((style & DWT.SEPARATOR) !is 0) return; | 631 if ((style & DWT.SEPARATOR) !is 0) return; |
622 super.setImage (image); | 632 super.setImage (image); |
623 (cast(NSMenuItem)nsItem).setImage(image !is null? image.handle : null); | 633 nsItem.setImage(image !is null? image.handle : null); |
624 } | 634 } |
625 | 635 |
626 /** | 636 /** |
627 * Sets the receiver's pull down menu to the argument. | 637 * Sets the receiver's pull down menu to the argument. |
628 * Only <code>CASCADE</code> menu items can have a | 638 * Only <code>CASCADE</code> menu items can have a |
707 * </ul> | 717 * </ul> |
708 */ | 718 */ |
709 public void setSelection (bool selected) { | 719 public void setSelection (bool selected) { |
710 checkWidget (); | 720 checkWidget (); |
711 if ((style & (DWT.CHECK | DWT.RADIO)) is 0) return; | 721 if ((style & (DWT.CHECK | DWT.RADIO)) is 0) return; |
712 (cast(NSMenuItem)nsItem).setState(selected ? OS.NSOnState : OS.NSOffState); | 722 nsItem.setState(selected ? OS.NSOnState : OS.NSOffState); |
713 } | 723 } |
714 | 724 |
715 /** | 725 /** |
716 * Sets the receiver's text. The string may include | 726 * Sets the receiver's text. The string may include |
717 * the mnemonic character and accelerator text. | 727 * the mnemonic character and accelerator text. |
776 if(submenu !is null && (parent.getStyle () & DWT.BAR) !is 0) { | 786 if(submenu !is null && (parent.getStyle () & DWT.BAR) !is 0) { |
777 submenu.setTitle (label); | 787 submenu.setTitle (label); |
778 } else { | 788 } else { |
779 nsItem.setTitle (label); | 789 nsItem.setTitle (label); |
780 } | 790 } |
781 } | 791 if (accelerator is 0) { |
782 | 792 int mask = 0, key = 0; |
783 } | 793 if (i < buffer.length && buffer [i] is '\t') { |
784 | 794 for (j = i + 1; j < buffer.length; j++) { |
795 switch (buffer [j]) { | |
796 case '\u2303': mask |= OS.NSControlKeyMask; i++; break; | |
797 case '\u2325': mask |= OS.NSAlternateKeyMask; i++; break; | |
798 case '\u21E7': mask |= OS.NSShiftKeyMask; i++; break; | |
799 case '\u2318': mask |= OS.NSCommandKeyMask; i++; break; | |
800 default: | |
801 j = buffer.length; | |
802 break; | |
803 } | |
804 } | |
805 switch (buffer.length - i - 1) { | |
806 case 1: | |
807 key = buffer [i + 1]; | |
808 if (key is 0x2423) key = ' '; | |
809 break; | |
810 case 2: | |
811 if (buffer [i + 1] is 'F') { | |
812 switch (buffer [i + 2]) { | |
813 case '1': key = 0xF704; break; | |
814 case '2': key = 0xF705; break; | |
815 case '3': key = 0xF706; break; | |
816 case '4': key = 0xF707; break; | |
817 case '5': key = 0xF708; break; | |
818 case '6': key = 0xF709; break; | |
819 case '7': key = 0xF70A; break; | |
820 case '8': key = 0xF70B; break; | |
821 case '9': key = 0xF70C; break; | |
822 } | |
823 } | |
824 break; | |
825 case 3: | |
826 if (buffer [i + 1] is 'F' && buffer [i + 2] is '1') { | |
827 switch (buffer [i + 3]) { | |
828 case '0': key = 0xF70D; break; | |
829 case '1': key = 0xF70E; break; | |
830 case '2': key = 0xF70F; break; | |
831 case '3': key = 0xF710; break; | |
832 case '4': key = 0xF711; break; | |
833 case '5': key = 0xF712; break; | |
834 } | |
835 } | |
836 break; | |
837 } | |
838 } | |
839 NSString string = NSString.stringWith (key is 0 ? "" : (char)key + ""); | |
840 nsItem.setKeyEquivalentModifierMask (mask); | |
841 nsItem.setKeyEquivalent (string.lowercaseString ()); | |
842 //TODO - only hide when key !is 0 (fix all places) | |
843 nsItem.setHidden (key !is 0 || mask !is 0); | |
844 } | |
845 } | |
846 | |
847 } | |
848 |