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);