changeset 7:936feb16eed4

Checkpoint
author "David Bryant <bagnose@gmail.com>"
date Sat, 11 Jul 2009 21:29:03 +0930
parents a27d2093991c
children bf7903435f58
files build.sh canvas.d gui.d icanvas.d standard_tools.d tk/events.d tk/gtk_support.d tk/types.d tool.d tool_stack.d
diffstat 10 files changed, 152 insertions(+), 121 deletions(-) [+]
line wrap: on
line diff
--- a/build.sh	Sat Jul 11 20:44:14 2009 +0930
+++ b/build.sh	Sat Jul 11 21:29:03 2009 +0930
@@ -4,7 +4,7 @@
         -ofgui \
         gui.d tool_stack.d tool.d icanvas.d canvas.d \
         tk/geometry.d tk/gtk_support.d tk/misc.d tk/types.d tk/events.d \
-        cairo_support.d \
+        cairo_support.d standard_tools.d \
         -od.obj \
         -I"${DMD_BASE}/include/d" \
         -L-lgtkd -L-ldl
--- a/canvas.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/canvas.d	Sat Jul 11 21:29:03 2009 +0930
@@ -203,8 +203,8 @@
             Point screen_point = Point(event.x + 0.5, event.y + 0.5);
             Point model_point = screen_to_model(screen_point);
 
-            auto button_event = new ButtonEvent(gtk2tk_click(event.type),
-                                                gtk2tk_button(event.button),
+            auto button_event = new ButtonEvent(gtk2tk_button_action(event.type),
+                                                gtk2tk_button_name(event.button),
                                                 screen_point,
                                                 model_point,
                                                 gtk2tk_mask(event.state));
@@ -221,8 +221,8 @@
             Point screen_point = Point(event.x + 0.5, event.y + 0.5);
             Point model_point = screen_to_model(screen_point);
 
-            auto button_event = new ButtonEvent(gtk2tk_click(event.type),
-                                                gtk2tk_button(event.button),
+            auto button_event = new ButtonEvent(gtk2tk_button_action(event.type),
+                                                gtk2tk_button_name(event.button),
                                                 screen_point,
                                                 model_point,
                                                 gtk2tk_mask(event.state));
--- a/gui.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/gui.d	Sat Jul 11 21:29:03 2009 +0930
@@ -2,6 +2,8 @@
 
 import canvas;
 import tool_stack;
+import tool;
+import standard_tools;
 
 import gtk.Main;
 import gtk.MainWindow;
@@ -16,7 +18,10 @@
 void main(string[] args) {
     Main.init(args);
     auto window = new MainWindow("Title");
-    auto event_handler = new ToolStack();
+    Tool[] tools;
+    tools ~= new PanTool;
+    tools ~= new ZoomTool;
+    auto event_handler = new ToolStack(tools);
     auto canvas = new Canvas(event_handler);
     window.add(canvas);
     window.showAll();
--- a/icanvas.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/icanvas.d	Sat Jul 11 21:29:03 2009 +0930
@@ -1,20 +1,16 @@
 module icanvas;
 
 import tk.geometry;
+import tk.events;
 
 interface ICanvas {
     void rel_zoom(Point screen_datum, double factor);
     void rel_pan(Vector screen_displacement);
-    //void damage();
 }
 
-import tk.events;
-
 interface ICanvasEventHandler {
     bool handle_button_press(ICanvas canvas, in ButtonEvent event);
     bool handle_button_release(ICanvas canvas, in ButtonEvent event);
-    bool handle_key_press(ICanvas canvas, in KeyEvent event);
-    bool handle_key_release(ICanvas canvas, in KeyEvent event);
     bool handle_motion(ICanvas canvas, in MotionEvent event);
     bool handle_scroll(ICanvas canvas, in ScrollEvent event);
     //bool handle_expose(ICanvas canvas, ExposeEvent event);
@@ -22,4 +18,6 @@
     //bool handle_leave(ICanvas, CrossingEvent event);
     //bool handle_focus_in(ICanvas, FocusEvent event);
     //bool handle_focus_out(ICanvas, FocusEvent event);
+    bool handle_key_press(ICanvas canvas, in KeyEvent event);
+    bool handle_key_release(ICanvas canvas, in KeyEvent event);
 }
--- a/standard_tools.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/standard_tools.d	Sat Jul 11 21:29:03 2009 +0930
@@ -1,17 +1,40 @@
 module standard_tools;
 
+import tool;
+import icanvas;
+import tk.types;
+import tk.events;
+import tk.geometry;
+
 final class PanTool : Tool {
-    override bool handle_scroll(ICanvas canvas, ScrollEvent event) {
+    bool handle_button_press(ICanvas canvas, in ButtonEvent event) {
+        if (event.button_name == ButtonName.MIDDLE) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    bool handle_button_release(ICanvas canvas, in ButtonEvent event) {
+        return false;
+    }
+
+    bool handle_motion(ICanvas canvas, in MotionEvent event) {
+        return false;
+    }
+
+    bool handle_scroll(ICanvas canvas, in ScrollEvent event) {
         const double AMOUNT = 30.0;
         Vector v;
 
-        if (event.mask.query(Modifier.SHIFT)) {
+        if (event.mask.is_set(Modifier.SHIFT)) {
             // left to right
-            v = new Vector(AMOUNT, 0.0);
+            v = Vector(AMOUNT, 0.0);
         }
         else {
             // down to up
-            v = new Vector(0.0, AMOUNT);
+            v = Vector(0.0, AMOUNT);
         }
 
         if (event.scroll_direction == ScrollDirection.UP) {
@@ -23,21 +46,32 @@
         return true;
     }
 
-    bool handle_button_press(ICanvas canvas, ButtonEvent event) {
+    bool handle_key_press(ICanvas canvas, in KeyEvent event) {
+        return false;
     }
 
-    bool handle_button_release(ICanvas canvas, ButtonEvent event) {
-    }
-
-    bool handle_motion(ICanvas canvas, MotionEvent event) {
+    bool handle_key_release(ICanvas canvas, in KeyEvent event) {
+        return false;
     }
 }
 
-final class ZoomTool {
+final class ZoomTool : Tool {
     static invariant double ZOOM = 1.44;
 
-    override bool handle_scroll(ICanvas canvas, ScrollEvent event) {
-        if (event.mask.query(Modifier.CONTROL)) {
+    bool handle_button_press(ICanvas canvas, in ButtonEvent event) {
+        return false;
+    }
+
+    bool handle_button_release(ICanvas canvas, in ButtonEvent event) {
+        return false;
+    }
+
+    bool handle_motion(ICanvas canvas, in MotionEvent event) {
+        return false;
+    }
+
+    bool handle_scroll(ICanvas canvas, in ScrollEvent event) {
+        if (event.mask.is_set(Modifier.CONTROL)) {
             // Zoom about the pointer
             double zoom = 1.44;
 
@@ -53,4 +87,12 @@
             return false;
         }
     }
+
+    bool handle_key_press(ICanvas canvas, in KeyEvent event) {
+        return false;
+    }
+
+    bool handle_key_release(ICanvas canvas, in KeyEvent event) {
+        return false;
+    }
 }
--- a/tk/events.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/tk/events.d	Sat Jul 11 21:29:03 2009 +0930
@@ -82,26 +82,26 @@
 }
 
 final class ButtonEvent : PointerEvent {
-    this(ButtonPress button_press,
-         ButtonNumber button_number,
+    this(ButtonAction button_action,
+         ButtonName button_name,
          Point screen_point,
          Point model_point,
          Mask mask) {   
         super(screen_point, model_point, mask);
-        mButtonPress = button_press;
-        mButtonNumber = button_number;
+        mButtonAction = button_action;
+        mButtonName = button_name;
     }
 
     override string toString() const {
-        return std.string.format("Button event: %s, %s, %s, %s, %s", mButtonPress, mButtonNumber, mScreenPoint, mModelPoint, mMask);
+        return std.string.format("Button event: %s, %s, %s, %s, %s", mButtonAction, mButtonName, mScreenPoint, mModelPoint, mMask);
     }
 
-    ButtonPress button_press() const { return mButtonPress; }
-    ButtonNumber button_number() const { return mButtonNumber; }
+    ButtonAction button_action() const { return mButtonAction; }
+    ButtonName button_name() const { return mButtonName; }
 
     private {
-        ButtonPress mButtonPress;
-        ButtonNumber mButtonNumber;
+        ButtonAction mButtonAction;
+        ButtonName mButtonName;
     }
 }
 
--- a/tk/gtk_support.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/tk/gtk_support.d	Sat Jul 11 21:29:03 2009 +0930
@@ -4,50 +4,38 @@
 
 static import gdk.Event;
 
-ButtonPress gtk2tk_click(gdk.Event.EventType event_type) {
+ButtonAction gtk2tk_button_action(gdk.Event.EventType event_type) {
     switch (event_type) {
     case gdk.Event.EventType.BUTTON_PRESS:
-        return ButtonPress.SINGLE;
+        return ButtonAction.PRESS_SINGLE;
     case gdk.Event.EventType.DOUBLE_BUTTON_PRESS:
-        return ButtonPress.DOUBLE;
+        return ButtonAction.PRESS_DOUBLE;
     case gdk.Event.EventType.TRIPLE_BUTTON_PRESS:
-        return ButtonPress.TRIPLE;
+        return ButtonAction.PRESS_TRIPLE;
     case gdk.Event.EventType.BUTTON_RELEASE:
-        return ButtonPress.RELEASE;
+        return ButtonAction.RELEASE;
     default:
         assert(false);
     }
 }
 
-ButtonNumber gtk2tk_button(gdk.Event.guint button) {
+ButtonName gtk2tk_button_name(gdk.Event.guint button) {
     switch (button) {
     case 1:
-        return ButtonNumber.BUTTON_1;
+        return ButtonName.LEFT;
     case 2:
-        return ButtonNumber.BUTTON_2;
+        return ButtonName.MIDDLE;
     case 3:
-        return ButtonNumber.BUTTON_3;
+        return ButtonName.RIGHT;
+    case 4:
+        return ButtonName.FOUR;
+    case 5:
+        return ButtonName.FIVE;
     default:
         assert(false);
     }
 }
 
-/*
-Mask gtk2tk_mask(gdk.Event.guint state) {
-    auto mask = new Mask();
-
-    if (state & gdk.Event.GdkModifierType.SHIFT_MASK)   mask.add(Modifier.SHIFT);
-    if (state & gdk.Event.GdkModifierType.CONTROL_MASK) mask.add(Modifier.CONTROL);
-    if (state & gdk.Event.GdkModifierType.MOD1_MASK)    mask.add(Modifier.ALT);
-    if (state & gdk.Event.GdkModifierType.MOD2_MASK)    mask.add(Modifier.META);
-    if (state & gdk.Event.GdkModifierType.BUTTON1_MASK) mask.add(Modifier.BUTTON_1);
-    if (state & gdk.Event.GdkModifierType.BUTTON2_MASK) mask.add(Modifier.BUTTON_2);
-    if (state & gdk.Event.GdkModifierType.BUTTON3_MASK) mask.add(Modifier.BUTTON_3);
-
-    return mask;
-}
-*/
-
 Mask gtk2tk_mask(gdk.Event.guint state) {
     Modifier[] modifiers;
 
@@ -55,9 +43,11 @@
     if (state & gdk.Event.GdkModifierType.CONTROL_MASK) modifiers ~= Modifier.CONTROL;
     if (state & gdk.Event.GdkModifierType.MOD1_MASK)    modifiers ~= Modifier.ALT;
     if (state & gdk.Event.GdkModifierType.MOD2_MASK)    modifiers ~= Modifier.META;
-    if (state & gdk.Event.GdkModifierType.BUTTON1_MASK) modifiers ~= Modifier.BUTTON_1;
-    if (state & gdk.Event.GdkModifierType.BUTTON2_MASK) modifiers ~= Modifier.BUTTON_2;
-    if (state & gdk.Event.GdkModifierType.BUTTON3_MASK) modifiers ~= Modifier.BUTTON_3;
+    if (state & gdk.Event.GdkModifierType.BUTTON1_MASK) modifiers ~= Modifier.BUTTON_LEFT;
+    if (state & gdk.Event.GdkModifierType.BUTTON2_MASK) modifiers ~= Modifier.BUTTON_MIDDLE;
+    if (state & gdk.Event.GdkModifierType.BUTTON3_MASK) modifiers ~= Modifier.BUTTON_RIGHT;
+    if (state & gdk.Event.GdkModifierType.BUTTON4_MASK) modifiers ~= Modifier.BUTTON_FOUR;
+    if (state & gdk.Event.GdkModifierType.BUTTON5_MASK) modifiers ~= Modifier.BUTTON_FIVE;
 
     return new Mask(modifiers);
 }
--- a/tk/types.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/tk/types.d	Sat Jul 11 21:29:03 2009 +0930
@@ -4,15 +4,15 @@
 private import std.typecons;
 private import std.algorithm;
 
-mixin(defineEnum!("ButtonPress",
-                  "SINGLE", "DOUBLE", "TRIPLE", "RELEASE"));
-mixin(defineEnum!("ButtonNumber",
-                  "BUTTON_1", "BUTTON_2", "BUTTON_3", "BUTTON_4", "BUTTON_5"));
+mixin(defineEnum!("ButtonAction",
+                  "PRESS_SINGLE", "PRESS_DOUBLE", "PRESS_TRIPLE", "RELEASE"));
+mixin(defineEnum!("ButtonName",
+                  "LEFT", "MIDDLE", "RIGHT", "FOUR", "FIVE"));
 mixin(defineEnum!("ScrollDirection",
                   "UP", "DOWN", "LEFT", "RIGHT"));
 mixin(defineEnum!("Modifier",
                   "SHIFT", "CAPS_LOCK", "CONTROL", "ALT", "NUM_LOCK", "META",
-                  "SCROLL_LOCK", "BUTTON_1", "BUTTON_2", "BUTTON_3", "BUTTON_4", "BUTTON_5"));
+                  "SCROLL_LOCK", "BUTTON_LEFT", "BUTTON_MIDDLE", "BUTTON_RIGHT", "BUTTON_FOUR", "BUTTON_FIVE"));
 
 class Mask {
     this(in Modifier[] modifiers) {
@@ -48,28 +48,3 @@
         Modifier[] _modifiers;
     }
 }
-
-/*
-class Mask {
-    this() {
-    }
-
-    this(in Mask other) {
-        mBits = other.mBits;
-    }
-
-    void add(Modifier modifier) { mBits |= to_bit(modifier); }
-    void remove(Modifier modifier) { mBits &= ~to_bit(modifier); }
-    bool query(Modifier modifier) const { return cast(bool)(mBits & to_bit(modifier)); }
-
-    override string toString() const {
-        Modifier m = Modifier.SHIFT;
-        return enumToString(m);
-    }
-
-    private {
-        static int to_bit(Modifier modifier) { return 1 << cast(int)modifier; }
-        int mBits;
-    }
-}
-*/
--- a/tool.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/tool.d	Sat Jul 11 21:29:03 2009 +0930
@@ -2,11 +2,13 @@
 
 import icanvas;
 
+/*
 interface IToolStack {
     void push(Tool tool);
     void pop();
     void replace(Tool tool);
 }
+*/
 
 abstract class Tool : ICanvasEventHandler {
     /*
@@ -14,7 +16,9 @@
     abstract bool is_replaceable();
     */
 
+    /*
     abstract void start(IToolStack tool_stack);
     abstract void stop(IToolStack tool_stack);
+    */
 }
 
--- a/tool_stack.d	Sat Jul 11 20:44:14 2009 +0930
+++ b/tool_stack.d	Sat Jul 11 21:29:03 2009 +0930
@@ -8,16 +8,41 @@
 private import tk.geometry;
 private import tk.events;
 
-//IToolStack
+class ToolStack : ICanvasEventHandler {
+    this(in Tool[] tools) {
+        mTools = tools.dup;
+    }
 
-class ToolStack : ICanvasEventHandler {
     override bool handle_button_press(ICanvas canvas, in ButtonEvent event) {
         writefln("%s", event);
+
+        if (mGrabbedTool is null) {
+            foreach_reverse(ref tool; mTools) {
+                if (tool.handle_button_press(canvas, event)) {
+                    mGrabbedTool = &tool;
+                    mGrabbedButton = event.button_name;
+                    break;
+                }
+            }
+        }
+        else {
+            mGrabbedTool.handle_button_press(canvas, event);
+        }
+
         return true;
     }
 
     override bool handle_button_release(ICanvas canvas, in ButtonEvent event) {
         writefln("%s", event);
+
+        if (mGrabbedTool !is null) {
+            mGrabbedTool.handle_button_release(canvas, event);
+
+            if (mGrabbedButton == event.button_name) {
+                mGrabbedTool = null;
+            }
+        }
+
         return true;
     }
 
@@ -33,42 +58,33 @@
 
     override bool handle_motion(ICanvas canvas, in MotionEvent event) {
         writefln("%s", event);
+
+        if (mGrabbedTool is null) {
+            foreach_reverse(ref tool; mTools) {
+                if (tool.handle_motion(canvas, event)) {
+                    break;
+                }
+            }
+        }
+        else {
+            mGrabbedTool.handle_motion(canvas, event);
+        }
+
         return true;
     }
 
     override bool handle_scroll(ICanvas canvas, in ScrollEvent event) {
         writefln("%s", event);
 
-        if (event.mask.is_set(Modifier.CONTROL)) {
-            // Zoom about the pointer
-            double zoom = 1.44;
-
-            if (event.scroll_direction == ScrollDirection.DOWN) {
-                zoom = 1.0 / zoom;
+        if (mGrabbedTool is null) {
+            foreach_reverse(ref tool; mTools) {
+                if (tool.handle_scroll(canvas, event)) {
+                    break;
+                }
             }
-
-            canvas.rel_zoom(event.screen_point(), zoom);
         }
         else {
-            // Scroll
-
-            const double AMOUNT = 30.0;
-            Vector v;
-
-            if (event.mask.is_set(Modifier.SHIFT)) {
-                // left to right
-                v = Vector(AMOUNT, 0.0);
-            }
-            else {
-                // down to up
-                v = Vector(0.0, AMOUNT);
-            }
-
-            if (event.scroll_direction == ScrollDirection.UP) {
-                v = -v;
-            }
-
-            canvas.rel_pan(v);
+            mGrabbedTool.handle_scroll(canvas, event);
         }
 
         return true;
@@ -83,10 +99,11 @@
 
     override void replace(Tool tool) {
     }
+    */
 
     private {
         Tool[] mTools;
-        int mGrabbedToolIndex;  // -1 for none
+        Tool * mGrabbedTool;
+        ButtonName mGrabbedButton;
     }
-    */
 }