Mercurial > projects > dwt-mac
comparison dwt/widgets/Tracker.d @ 86:102ff2adce19
Ported dwt.widgets.Tracker
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Sun, 28 Dec 2008 20:07:20 +0100 |
parents | cfa563df4fdd |
children | c7f7f4d7091a |
comparison
equal
deleted
inserted
replaced
85:844f65808a36 | 86:102ff2adce19 |
---|---|
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 * | |
11 * Port to the D programming language: | |
12 * Jacob Carlborg <doob@me.com> | |
10 *******************************************************************************/ | 13 *******************************************************************************/ |
11 module dwt.widgets.Tracker; | 14 module dwt.widgets.Tracker; |
12 | 15 |
13 import dwt.dwthelper.utils; | 16 import dwt.dwthelper.utils; |
14 | 17 |
32 import dwt.internal.cocoa.NSRect; | 35 import dwt.internal.cocoa.NSRect; |
33 import dwt.internal.cocoa.NSScreen; | 36 import dwt.internal.cocoa.NSScreen; |
34 import dwt.internal.cocoa.NSWindow; | 37 import dwt.internal.cocoa.NSWindow; |
35 import dwt.internal.cocoa.OS; | 38 import dwt.internal.cocoa.OS; |
36 | 39 |
40 import dwt.internal.c.Carbon; | |
41 import dwt.internal.objc.cocoa.Cocoa; | |
42 import dwt.widgets.Composite; | |
43 import dwt.widgets.Control; | |
44 import dwt.widgets.Display; | |
45 import dwt.widgets.Event; | |
46 import dwt.widgets.TypedListener; | |
47 import dwt.widgets.Widget; | |
48 | |
37 /** | 49 /** |
38 * Instances of this class implement rubber banding rectangles that are | 50 * Instances of this class implement rubber banding rectangles that are |
39 * drawn onto a parent <code>Composite</code> or <code>Display</code>. | 51 * drawn onto a parent <code>Composite</code> or <code>Display</code>. |
40 * These rectangles can be specified to respond to mouse and key events | 52 * These rectangles can be specified to respond to mouse and key events |
41 * by either moving or resizing themselves accordingly. Trackers are | 53 * by either moving or resizing themselves accordingly. Trackers are |
58 */ | 70 */ |
59 public class Tracker : Widget { | 71 public class Tracker : Widget { |
60 Control parent; | 72 Control parent; |
61 bool tracking, cancelled, stippled; | 73 bool tracking, cancelled, stippled; |
62 Cursor clientCursor, resizeCursor; | 74 Cursor clientCursor, resizeCursor; |
63 Rectangle [] rectangles = new Rectangle [0], proportions = rectangles; | 75 Rectangle [] rectangles; |
76 Rectangle [] proportions; | |
64 Rectangle bounds; | 77 Rectangle bounds; |
65 int cursorOrientation = DWT.NONE; | 78 int cursorOrientation = DWT.NONE; |
66 bool inEvent = false; | 79 bool inEvent = false; |
67 NSWindow window; | 80 NSWindow window; |
68 int oldX, oldY; | 81 int oldX, oldY; |
69 | 82 |
70 /* | 83 /* |
71 * The following values mirror step sizes on Windows | 84 * The following values mirror step sizes on Windows |
72 */ | 85 */ |
73 final static int STEPSIZE_SMALL = 1; | 86 const static int STEPSIZE_SMALL = 1; |
74 final static int STEPSIZE_LARGE = 9; | 87 const static int STEPSIZE_LARGE = 9; |
88 | |
89 static this () | |
90 { | |
91 rectangles = new Rectangle [0]; | |
92 proportions = rectangles; | |
93 } | |
75 | 94 |
76 /** | 95 /** |
77 * Constructs a new instance of this class given its parent | 96 * Constructs a new instance of this class given its parent |
78 * and a style value describing its behavior and appearance. | 97 * and a style value describing its behavior and appearance. |
79 * <p> | 98 * <p> |
385 frame.x = rect.x + parentOrigin.x; | 404 frame.x = rect.x + parentOrigin.x; |
386 frame.y = rect.y + parentOrigin.y; | 405 frame.y = rect.y + parentOrigin.y; |
387 frame.width = rect.width; | 406 frame.width = rect.width; |
388 frame.height = rect.height; | 407 frame.height = rect.height; |
389 if (erase) { | 408 if (erase) { |
390 frame.width++; | 409 frame.size.width++; |
391 frame.height++; | 410 frame.size.height++; |
392 NSBezierPath.fillRect(frame); | 411 NSBezierPath.fillRect(frame); |
393 } else { | 412 } else { |
394 frame.x += 0.5f; | 413 frame.origin.x += 0.5f; |
395 frame.y += 0.5f; | 414 frame.origin.y += 0.5f; |
396 NSBezierPath.strokeRect(frame); | 415 NSBezierPath.strokeRect(frame); |
397 } | 416 } |
398 } | 417 } |
399 context.flushGraphics(); | 418 context.flushGraphics(); |
400 context.restoreGraphicsState(); | 419 context.restoreGraphicsState(); |
546 drawRectangles (window, rectangles, false); | 565 drawRectangles (window, rectangles, false); |
547 } | 566 } |
548 } | 567 } |
549 oldX = newX; oldY = newY; | 568 oldX = newX; oldY = newY; |
550 } | 569 } |
551 switch ((int)/*64*/nsEvent.type()) { | 570 switch (cast(int)/*64*/nsEvent.type()) { |
552 case OS.NSLeftMouseUp: | 571 case OS.NSLeftMouseUp: |
553 case OS.NSRightMouseUp: | 572 case OS.NSRightMouseUp: |
554 case OS.NSOtherMouseUp: | 573 case OS.NSOtherMouseUp: |
555 tracking = false; | 574 tracking = false; |
575 default: | |
556 } | 576 } |
557 } | 577 } |
558 | 578 |
559 void key (NSEvent nsEvent) { | 579 void key (NSEvent nsEvent) { |
560 //TODO send event | 580 //TODO send event |
561 // if (!sendKeyEvent (DWT.KeyDown, theEvent)) return OS.noErr; | 581 // if (!sendKeyEvent (DWT.KeyDown, theEvent)) return OS.noErr; |
562 int /*long*/ modifierFlags = nsEvent.modifierFlags(); | 582 NSUInteger modifierFlags = nsEvent.modifierFlags(); |
563 int stepSize = (modifierFlags & OS.NSControlKeyMask) !is 0 ? STEPSIZE_SMALL : STEPSIZE_LARGE; | 583 int stepSize = (modifierFlags & OS.NSControlKeyMask) !is 0 ? STEPSIZE_SMALL : STEPSIZE_LARGE; |
564 int xChange = 0, yChange = 0; | 584 int xChange = 0, yChange = 0; |
565 switch (nsEvent.keyCode()) { | 585 switch (nsEvent.keyCode()) { |
566 case 53: /* Esc */ | 586 case 53: /* Esc */ |
567 cancelled = true; | 587 cancelled = true; |
581 yChange = -stepSize; | 601 yChange = -stepSize; |
582 break; | 602 break; |
583 case 125: /* Down arrow */ | 603 case 125: /* Down arrow */ |
584 yChange = stepSize; | 604 yChange = stepSize; |
585 break; | 605 break; |
606 default: | |
586 } | 607 } |
587 if (xChange !is 0 || yChange !is 0) { | 608 if (xChange !is 0 || yChange !is 0) { |
588 Rectangle [] oldRectangles = rectangles; | 609 Rectangle [] oldRectangles = rectangles; |
589 Rectangle [] rectsToErase = new Rectangle [rectangles.length]; | 610 Rectangle [] rectsToErase = new Rectangle [rectangles.length]; |
590 for (int i = 0; i < rectangles.length; i++) { | 611 for (int i = 0; i < rectangles.length; i++) { |
717 */ | 738 */ |
718 public bool open () { | 739 public bool open () { |
719 checkWidget (); | 740 checkWidget (); |
720 cancelled = false; | 741 cancelled = false; |
721 tracking = true; | 742 tracking = true; |
722 window = cast(NSWindow)new NSWindow().alloc(); | 743 window = cast(NSWindow)(new NSWindow()).alloc(); |
723 NSArray screens = NSScreen.screens(); | 744 NSArray screens = NSScreen.screens(); |
724 float /*double*/ minX = Float.MAX_VALUE, maxX = Float.MIN_VALUE; | 745 CGFloat minX = Float.MAX_VALUE, maxX = Float.MIN_VALUE; |
725 float /*double*/ minY = Float.MAX_VALUE, maxY = Float.MIN_VALUE; | 746 CGFloat minY = Float.MAX_VALUE, maxY = Float.MIN_VALUE; |
726 int count = (int)/*64*/screens.count(); | 747 int count = cast(int)/*64*/screens.count(); |
727 for (int i = 0; i < count; i++) { | 748 for (int i = 0; i < count; i++) { |
728 NSScreen screen = new NSScreen(screens.objectAtIndex(i)); | 749 NSScreen screen = new NSScreen(screens.objectAtIndex(i)); |
729 NSRect frame = screen.frame(); | 750 NSRect frame = screen.frame(); |
730 float /*double*/ x1 = frame.x, x2 = frame.x + frame.width; | 751 CGFloat x1 = frame.x, x2 = frame.x + frame.width; |
731 float /*double*/ y1 = frame.y, y2 = frame.y + frame.height; | 752 CGFloat y1 = frame.y, y2 = frame.y + frame.height; |
732 if (x1 < minX) minX = x1; | 753 if (x1 < minX) minX = x1; |
733 if (x2 < minX) minX = x2; | 754 if (x2 < minX) minX = x2; |
734 if (x1 > maxX) maxX = x1; | 755 if (x1 > maxX) maxX = x1; |
735 if (x2 > maxX) maxX = x2; | 756 if (x2 > maxX) maxX = x2; |
736 if (y1 < minY) minY = y1; | 757 if (y1 < minY) minY = y1; |
770 | 791 |
771 Point cursorPos; | 792 Point cursorPos; |
772 bool down = false; | 793 bool down = false; |
773 NSApplication application = NSApplication.sharedApplication(); | 794 NSApplication application = NSApplication.sharedApplication(); |
774 NSEvent currentEvent = application.currentEvent(); | 795 NSEvent currentEvent = application.currentEvent(); |
775 switch ((int)/*64*/currentEvent.type()) { | 796 switch (currentEvent.type()) { |
776 case OS.NSLeftMouseDown: | 797 case OS.NSLeftMouseDown: |
777 case OS.NSRightMouseDown: | 798 case OS.NSRightMouseDown: |
778 case OS.NSOtherMouseDown: | 799 case OS.NSOtherMouseDown: |
779 down = true; | 800 down = true; |
801 default: | |
780 } | 802 } |
781 if (down) { | 803 if (down) { |
782 cursorPos = display.getCursorLocation(); | 804 cursorPos = display.getCursorLocation(); |
783 } else { | 805 } else { |
784 if ((style & DWT.RESIZE) !is 0) { | 806 if ((style & DWT.RESIZE) !is 0) { |
792 oldY = cursorPos.y; | 814 oldY = cursorPos.y; |
793 } | 815 } |
794 | 816 |
795 /* Tracker behaves like a Dialog with its own OS event loop. */ | 817 /* Tracker behaves like a Dialog with its own OS event loop. */ |
796 while (tracking && !cancelled) { | 818 while (tracking && !cancelled) { |
797 NSAutoreleasePool pool = cast(NSAutoreleasePool)new NSAutoreleasePool().alloc().init(); | 819 NSAutoreleasePool pool = cast(NSAutoreleasePool)(new NSAutoreleasePool()).alloc().init(); |
798 NSEvent event = application.nextEventMatchingMask(0, NSDate.distantFuture(), OS.NSDefaultRunLoopMode, true); | 820 NSEvent event = application.nextEventMatchingMask(0, NSDate.distantFuture(), OS.NSDefaultRunLoopMode, true); |
799 if (event is null) continue; | 821 if (event is null) continue; |
800 int type = (int)/*64*/event.type(); | 822 NSEventType type = event.type(); |
801 switch (type) { | 823 switch (type) { |
802 case OS.NSLeftMouseUp: | 824 case OS.NSLeftMouseUp: |
803 case OS.NSRightMouseUp: | 825 case OS.NSRightMouseUp: |
804 case OS.NSOtherMouseUp: | 826 case OS.NSOtherMouseUp: |
805 case OS.NSMouseMoved: | 827 case OS.NSMouseMoved: |
811 case OS.NSKeyDown: | 833 case OS.NSKeyDown: |
812 // case OS.NSKeyUp: | 834 // case OS.NSKeyUp: |
813 case OS.NSFlagsChanged: | 835 case OS.NSFlagsChanged: |
814 key(event); | 836 key(event); |
815 break; | 837 break; |
838 default: | |
816 } | 839 } |
817 /* | 840 /* |
818 * Don't dispatch mouse and key events in general, EXCEPT once this | 841 * Don't dispatch mouse and key events in general, EXCEPT once this |
819 * tracker has finished its work. | 842 * tracker has finished its work. |
820 */ | 843 */ |
835 case OS.NSMouseExited: | 858 case OS.NSMouseExited: |
836 case OS.NSKeyDown: | 859 case OS.NSKeyDown: |
837 case OS.NSKeyUp: | 860 case OS.NSKeyUp: |
838 case OS.NSFlagsChanged: | 861 case OS.NSFlagsChanged: |
839 dispatch = false; | 862 dispatch = false; |
863 default: | |
840 } | 864 } |
841 } | 865 } |
842 if (dispatch) application.sendEvent(event); | 866 if (dispatch) application.sendEvent(event); |
843 if (clientCursor !is null && resizeCursor is null) { | 867 if (clientCursor !is null && resizeCursor is null) { |
844 clientCursor.handle.set(); | 868 clientCursor.handle.set(); |
1075 * </ul> | 1099 * </ul> |
1076 */ | 1100 */ |
1077 public void setRectangles (Rectangle [] rectangles) { | 1101 public void setRectangles (Rectangle [] rectangles) { |
1078 checkWidget (); | 1102 checkWidget (); |
1079 if (rectangles is null) error (DWT.ERROR_NULL_ARGUMENT); | 1103 if (rectangles is null) error (DWT.ERROR_NULL_ARGUMENT); |
1080 int length = rectangles.length; | 1104 size_t length_ = rectangles.length; |
1081 this.rectangles = new Rectangle [length]; | 1105 this.rectangles = new Rectangle [length_]; |
1082 for (int i = 0; i < length; i++) { | 1106 for (size_t i = 0; i < length_; i++) { |
1083 Rectangle current = rectangles [i]; | 1107 Rectangle current = rectangles [i]; |
1084 if (current is null) error (DWT.ERROR_NULL_ARGUMENT); | 1108 if (current is null) error (DWT.ERROR_NULL_ARGUMENT); |
1085 this.rectangles [i] = new Rectangle (current.x, current.y, current.width, current.height); | 1109 this.rectangles [i] = new Rectangle (current.x, current.y, current.width, current.height); |
1086 } | 1110 } |
1087 proportions = computeProportions (rectangles); | 1111 proportions = computeProportions (rectangles); |