changeset 64:eb5436b47d13

Implemented crossing events
author "David Bryant <bagnose@gmail.com>"
date Thu, 12 Aug 2010 22:21:12 +0930
parents 20d6327c4a75
children b4676efb884a
files doodle/dia/icanvas.d doodle/dia/standard_tools.d doodle/dia/tool.d doodle/dia/tool_layer.d doodle/gtk/canvas.d doodle/gtk/conversions.d doodle/tk/events.d doodle/tk/types.d
diffstat 8 files changed, 146 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/doodle/dia/icanvas.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/dia/icanvas.d	Thu Aug 12 22:21:12 2010 +0930
@@ -41,12 +41,14 @@
     bool handleButtonRelease(scope IViewport viewport, in ButtonEvent event);
     bool handleMotion(scope IViewport viewport, in MotionEvent event);
     bool handleScroll(scope IViewport viewport, in ScrollEvent event);
-    //bool handleEnter(scope IViewport viewport, CrossingEvent event);
-    //bool handleLeave(scope IViewport viewport, CrossingEvent event);
+    bool handleEnter(scope IViewport viewport, CrossingEvent event);
+    bool handleLeave(scope IViewport viewport, CrossingEvent event);
+    bool handleKeyPress(scope IViewport viewport, in KeyEvent event);
+    bool handleKeyRelease(scope IViewport viewport, in KeyEvent event);
+
+    // XXX Still not sure about these:
     //bool handleFocusIn(scope IViewport viewport, FocusEvent event);
     //bool handleFocusOut(scope IViewport viewport, FocusEvent event);
-    bool handleKeyPress(scope IViewport viewport, in KeyEvent event);
-    bool handleKeyRelease(scope IViewport viewport, in KeyEvent event);
 }
 
 interface IGrid {
--- a/doodle/dia/standard_tools.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/dia/standard_tools.d	Thu Aug 12 22:21:12 2010 +0930
@@ -123,6 +123,6 @@
     }
 
     private {
-        static immutable double ZOOM = 2^^0.5;
+        static immutable ZOOM = 2^^0.5;
     }
 }
--- a/doodle/dia/tool.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/dia/tool.d	Thu Aug 12 22:21:12 2010 +0930
@@ -17,15 +17,14 @@
     bool handleButtonRelease(scope IViewport viewport, in ButtonEvent event) { return false; }
     bool handleMotion(scope IViewport viewport, in MotionEvent event) { return false; }
     bool handleScroll(scope IViewport viewport, in ScrollEvent event) { return false; }
-    //bool handleEnter(scope viewport, CrossingEvent event) { return false; }
-    //bool handleLeave(scope viewport, CrossingEvent event) { return false; }
-    //bool handleFocusIn(scope viewport, FocusEvent event) { return false; }
-    //bool handleFocusOut(scope viewport, FocusEvent event) { return false; }
+    bool handleEnter(scope IViewport viewport, CrossingEvent event) { return false; }
+    bool handleLeave(scope IViewport viewport, CrossingEvent event) { return false; }
     bool handleKeyPress(scope IViewport viewport, in KeyEvent event) { return false; }
     bool handleKeyRelease(scope IViewport viewport, in KeyEvent event) { return false; }
+    //bool handleFocusIn(scope IViewport viewport, FocusEvent event) { return false; }
+    //bool handleFocusOut(scope IViewport viewport, FocusEvent event) { return false; }
 
-    void draw(in IViewport viewport,
-              in Rectangle pixelDamage, scope Context pixelCr) const { }
+    void draw(in IViewport viewport, in Rectangle pixelDamage, scope Context pixelCr) const { }
 
     private {
         immutable string _name;
--- a/doodle/dia/tool_layer.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/dia/tool_layer.d	Thu Aug 12 22:21:12 2010 +0930
@@ -83,32 +83,6 @@
         return true;
     }
 
-    bool handleKeyPress(scope IViewport viewport, in KeyEvent event) {
-        // writefln("%s", event);
-
-        // FIXME not sure how these should work
-        foreach_reverse(ref tool; _staticTools) {
-            if (tool.handleKeyPress(viewport, event)) {
-                break;
-            }
-        }
-
-        return true;
-    }
-
-    bool handleKeyRelease(scope IViewport viewport, in KeyEvent event) {
-        // writefln("%s", event);
-
-        // FIXME not sure how these should work
-        foreach_reverse(ref tool; _staticTools) {
-            if (tool.handleKeyRelease(viewport, event)) {
-                break;
-            }
-        }
-
-        return true;
-    }
-
     bool handleMotion(scope IViewport viewport, in MotionEvent event) {
         //writefln("%s", event);
 
@@ -143,6 +117,66 @@
         return true;
     }
 
+    bool handleEnter(scope IViewport viewport, CrossingEvent event) {
+        trace("Enter %s", event);
+
+        if (_grabbedTool is null) {
+            foreach_reverse(ref tool; _staticTools) {
+                if (tool.handleEnter(viewport, event)) {
+                    break;
+                }
+            }
+        }
+        else {
+            _grabbedTool.handleEnter(viewport, event);
+        }
+
+        return true;
+    }
+
+    bool handleLeave(scope IViewport viewport, CrossingEvent event) {
+        trace("Leave %s", event);
+
+        if (_grabbedTool is null) {
+            foreach_reverse(ref tool; _staticTools) {
+                if (tool.handleLeave(viewport, event)) {
+                    break;
+                }
+            }
+        }
+        else {
+            _grabbedTool.handleLeave(viewport, event);
+        }
+
+        return true;
+    }
+
+    bool handleKeyPress(scope IViewport viewport, in KeyEvent event) {
+        // writefln("%s", event);
+
+        // FIXME not sure how these should work
+        foreach_reverse(ref tool; _staticTools) {
+            if (tool.handleKeyPress(viewport, event)) {
+                break;
+            }
+        }
+
+        return true;
+    }
+
+    bool handleKeyRelease(scope IViewport viewport, in KeyEvent event) {
+        // writefln("%s", event);
+
+        // FIXME not sure how these should work
+        foreach_reverse(ref tool; _staticTools) {
+            if (tool.handleKeyRelease(viewport, event)) {
+                break;
+            }
+        }
+
+        return true;
+    }
+
     private {
         Tool[] _staticTools;
         IToolStackObserver _observer;
--- a/doodle/gtk/canvas.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/gtk/canvas.d	Thu Aug 12 22:21:12 2010 +0930
@@ -101,9 +101,7 @@
         _drawingArea.addOnFocusIn(&onFocusIn);
         _drawingArea.addOnFocusOut(&onFocusOut);
         _drawingArea.addOnMoveFocus(&onMoveFocus);
-        /*
         _drawingArea.addOnGrabBroken(&onGrabBroken);
-        */
         _drawingArea.addOnGrabFocus(&onGrabFocus);
         _drawingArea.addOnGrabNotify(&onGrabNotify);
         // addOnPopupMenu
@@ -400,7 +398,6 @@
          */
         bool onKeyPressEvent(GdkEventKey * event, Widget widget) {
             assert(widget is _drawingArea);
-            message("Got key event");
 
             auto keyEvent = new KeyEvent(event.string[0..strlen(event.string)].idup,
                                          event.keyval,
@@ -419,7 +416,7 @@
             auto keyEvent = new KeyEvent(event.string[0..strlen(event.string)].idup,
                                          event.keyval,
                                          gtk2tkMask(event.state));
-            message("Got key release %s", keyEvent);
+            //message("Got key release %s", keyEvent);
             _eventHandler.handleKeyRelease(this, keyEvent);
 
             fixDamage;
@@ -437,8 +434,8 @@
             Point modelPoint = pixelToModel(pixelPoint);
 
             auto motionEvent = new MotionEvent(pixelPoint,
-                                                modelPoint,
-                                                gtk2tkMask(event.state));
+                                               modelPoint,
+                                               gtk2tkMask(event.state));
 
             _eventHandler.handleMotion(this, motionEvent);
 
@@ -455,9 +452,9 @@
             Point modelPoint = pixelToModel(pixelPoint);
 
             auto scrollEvent = new ScrollEvent(gtk2tkDirection(event.direction),
-                                                pixelPoint,
-                                                modelPoint,
-                                                gtk2tkMask(event.state));
+                                               pixelPoint,
+                                               modelPoint,
+                                               gtk2tkMask(event.state));
 
             _eventHandler.handleScroll(this, scrollEvent);
 
@@ -495,15 +492,41 @@
 
         bool onEnterNotify(GdkEventCrossing * event, Widget widget) {
             assert(widget is _drawingArea);
-            message("Enter %d %d %d", cast(int)event.mode, event.focus, event.state);
-            // TODO
+
+            Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5));
+            Point modelPoint = pixelToModel(pixelPoint);
+
+            auto crossingEvent = new CrossingEvent(gtk2tkCrossingMode(event.mode),
+                                                   pixelPoint,
+                                                   modelPoint,
+                                                   gtk2tkMask(event.state));
+
+            _eventHandler.handleEnter(this, crossingEvent);
+
+            fixDamage;
+
+            //message("Enter %d %d %d", cast(int)event.mode, event.focus, event.state);
+
             return true;
         }
 
         bool onLeaveNotify(GdkEventCrossing * event, Widget widget) {
             assert(widget is _drawingArea);
-            message("Leave %d %d %d", cast(int)event.mode, event.focus, event.state);
-            // TODO
+
+            Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5));
+            Point modelPoint = pixelToModel(pixelPoint);
+
+            auto crossingEvent = new CrossingEvent(gtk2tkCrossingMode(event.mode),
+                                                   pixelPoint,
+                                                   modelPoint,
+                                                   gtk2tkMask(event.state));
+
+            _eventHandler.handleLeave(this, crossingEvent);
+
+            fixDamage;
+
+            //message("Leave %d %d %d", cast(int)event.mode, event.focus, event.state);
+
             return true;
         }
 
@@ -529,15 +552,13 @@
             trace("onMoveFocus");
         }
 
-        /*
-        bool onGrabBroken(Event event, Widget widget) {
+        bool onGrabBroken(gdk.Event.Event event, Widget widget) {
             trace("onGrabBroken");
             return true;
         }
-        */
 
         void onGrabFocus(Widget widget) {
-            trace("onGrabFocus");
+            //trace("onGrabFocus");
         }
 
         void onGrabNotify(gboolean what, Widget widget){
--- a/doodle/gtk/conversions.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/gtk/conversions.d	Thu Aug 12 22:21:12 2010 +0930
@@ -72,3 +72,22 @@
         assert(false);
     }
 }
+
+CrossingMode gtk2tkCrossingMode(gdk.Event.CrossingMode crossingMode) {
+    switch (crossingMode) {
+    case crossingMode.NORMAL:
+        return CrossingMode.NORMAL;
+    case crossingMode.GRAB:
+        return CrossingMode.GRAB;
+    case crossingMode.UNGRAB:
+        return CrossingMode.UNGRAB;
+    case crossingMode.GTK_GRAB:
+        return CrossingMode.GRAB2;
+    case crossingMode.GTK_UNGRAB:
+        return CrossingMode.UNGRAB2;
+    case crossingMode.STATE_CHANGED:
+        return CrossingMode.STATE_CHANGED;
+    default:
+        assert(false);
+    }
+}
--- a/doodle/tk/events.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/tk/events.d	Thu Aug 12 22:21:12 2010 +0930
@@ -6,8 +6,7 @@
 }
 
 // FIXME
-// Do we need FocusEvent, Enter/LeaveEvent ?
-// Note, FocusEvent has no mask but Enter/Leave do.
+// Do we need FocusEvent. Note, it has no mask.
 // Hence would need to refactor hierarchy slightly, eg InputEvent
 
 abstract class Event {
@@ -58,16 +57,25 @@
     }
 }
 
-/*
 final class CrossingEvent : PointerEvent {
-    this(in Mask mask) {
-        super(mask);
+    this(in CrossingMode crossingMode,
+         in Point pixelPoint,
+         in Point modelPoint,
+         in Mask mask) {
+        super(pixelPoint, modelPoint, mask);
+        _crossingMode = crossingMode;
+    }
+
+    CrossingMode crossingMode() const { return _crossingMode; }
+
+    override string toString() const {
+        return std.string.format("Crossing event: %s, %s, %s, %s", enumToString(_crossingMode), pixelPoint, modelPoint, mask);
     }
 
     private {
+        CrossingMode _crossingMode;
     }
 }
-*/
 
 final class ButtonEvent : PointerEvent {
     this(in ButtonAction buttonAction,
--- a/doodle/tk/types.d	Thu Aug 12 16:35:24 2010 +0930
+++ b/doodle/tk/types.d	Thu Aug 12 22:21:12 2010 +0930
@@ -23,6 +23,9 @@
                   "SCROLL_LOCK", "LEFT_BUTTON", "MIDDLE_BUTTON", "RIGHT_BUTTON",
                   "UNUSED_BUTTON_1", "UNUSED_BUTTON_2"));
 
+mixin(defineEnum!("CrossingMode",           // FIXME what to do about GRAB2/UNGRAB2
+                  "NORMAL", "GRAB", "UNGRAB", "GRAB2", "UNGRAB2", "STATE_CHANGED"));
+
 struct Mask {
     this(in Modifier[] modifiers) {
         foreach (ref m; modifiers) {