changeset 73:6f2525e170f2

Cairo/OpenGL checkpoint
author "David Bryant <bagnose@gmail.com>"
date Sun, 15 Aug 2010 01:02:15 +0930
parents 5cc2de64f6d0
children c03ed75c0f8e
files doodle/cairo/routines.d doodle/dia/grid_layer.d doodle/dia/page_layer.d doodle/dia/tool_layer.d doodle/fig/diagram_elements.d doodle/fig/select_tool.d doodle/gtk/cairo.d doodle/gtk/canvas.d doodle/gtk/events.d doodle/gtk/opengl.d doodle/tk/cairo.d doodle/tk/drawing.d
diffstat 12 files changed, 303 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/doodle/cairo/routines.d	Sun Aug 15 00:30:03 2010 +0930
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-module doodle.cairo.routines;
-
-public {
-    import doodle.tk.geometry;
-    import cairo.Context;
-}
-
-void rectangle(scope Context cr, in Rectangle rectangle) {
-    cr.rectangle(rectangle.position.x, rectangle.position.y,
-                 rectangle.size.x, rectangle.size.y);
-}
-
-void line(scope Context cr, in double x0, in double y0, in double x1, in double y1) {
-    cr.moveTo(x0, y0);
-    cr.lineTo(x1, y1);
-}
-
-// Horizontal line
-void hline(scope Context cr, in double y, double x0, double x1) {
-    cr.moveTo(x0, y);
-    cr.lineTo(x1, y);
-}
-
-// Vertical line
-void vline(scope Context cr, in double x, double y0, double y1) {
-    cr.moveTo(x, y0);
-    cr.lineTo(x, y1);
-}
--- a/doodle/dia/grid_layer.d	Sun Aug 15 00:30:03 2010 +0930
+++ b/doodle/dia/grid_layer.d	Sun Aug 15 01:02:15 2010 +0930
@@ -5,7 +5,7 @@
 }
 
 private {
-    import doodle.cairo.routines;
+    import doodle.tk.cairo;
     import std.math;
     import std.stdio;
 }
--- a/doodle/dia/page_layer.d	Sun Aug 15 00:30:03 2010 +0930
+++ b/doodle/dia/page_layer.d	Sun Aug 15 01:02:15 2010 +0930
@@ -5,7 +5,7 @@
 }
 
 private {
-    import doodle.cairo.routines;
+    import doodle.tk.cairo;
 }
 
 class PageLayer : Layer, IPage {
--- a/doodle/dia/tool_layer.d	Sun Aug 15 00:30:03 2010 +0930
+++ b/doodle/dia/tool_layer.d	Sun Aug 15 01:02:15 2010 +0930
@@ -5,7 +5,7 @@
 }
 
 private {
-    import doodle.cairo.routines;
+    import doodle.tk.cairo;
     import doodle.core.logging;
 }
 
--- a/doodle/fig/diagram_elements.d	Sun Aug 15 00:30:03 2010 +0930
+++ b/doodle/fig/diagram_elements.d	Sun Aug 15 01:02:15 2010 +0930
@@ -2,7 +2,7 @@
 
 private {
     import doodle.tk.geometry;
-    import doodle.cairo.routines;
+    import doodle.tk.cairo;
 }
 
 interface IDiagram {
--- a/doodle/fig/select_tool.d	Sun Aug 15 00:30:03 2010 +0930
+++ b/doodle/fig/select_tool.d	Sun Aug 15 01:02:15 2010 +0930
@@ -5,7 +5,7 @@
 }
 
 private {
-    import doodle.cairo.routines;
+    import doodle.tk.cairo;
 }
 
 final class SelectTool : Tool {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/gtk/cairo.d	Sun Aug 15 01:02:15 2010 +0930
@@ -0,0 +1,28 @@
+module doodle.gtk.cairo;
+
+public {
+    import doodle.tk.drawing;
+}
+
+/*
+final class CairoDrawing : Drawing {
+    this(Context cr) {
+        assert(cr);
+        _cr = cr;
+    }
+
+    // Drawing overrides:
+
+    void pushState() {
+        _cr.save;
+    }
+
+    void popState() {
+        _cr.restore;
+    }
+
+    private {
+        Context _cr;
+    }
+}
+*/
--- a/doodle/gtk/canvas.d	Sun Aug 15 00:30:03 2010 +0930
+++ b/doodle/gtk/canvas.d	Sun Aug 15 01:02:15 2010 +0930
@@ -8,7 +8,7 @@
 private {
     import doodle.core.misc;
     import doodle.core.logging;
-    import doodle.cairo.routines;
+    import doodle.tk.cairo;
     import doodle.gtk.conversions;
     import doodle.tk.pixel_model;
 
@@ -35,11 +35,17 @@
     import std.stdio;
 }
 
+//
+// TODO
+// Pass out a scope Drawing reference to the layers for drawing on instead of cairo context.
+// Create a class called LayerStack so we don't have to provide that non-gtk behaviour here.
+//
+
 final class Canvas : Table, private IViewport {
     this(in Layer[] layers, IEventHandler eventHandler, IGrid grid, in double pixelsPerMillimetre) {
         super(3, 3, 0);
 
-        _damage = Rectangle.DEFAULT;
+        _damageScreen = Rectangle.DEFAULT;
 
         _layers = layers.dup;
         _eventHandler = eventHandler;
@@ -181,11 +187,11 @@
         }
 
         void damageModel(in Rectangle area) {
-            _damage = _damage | _pixelModel.modelToPixel(area);
+            _damageScreen = _damageScreen | _pixelModel.modelToPixel(area);
         }
 
         void damagePixel(in Rectangle area) {
-            _damage = _damage | area;
+            _damageScreen = _damageScreen | area;
         }
     }
 
@@ -335,124 +341,49 @@
         bool onKeyReleaseEvent(GdkEventKey * event, Widget widget) {
             assert(widget is _drawingArea);
 
-            auto keyEvent = new KeyEvent(event.string[0..strlen(event.string)].idup,
-                                         event.keyval,
-                                         gtk2tkMask(event.state));
-            //message("Got key release %s", keyEvent);
-            _eventHandler.handleKeyRelease(this, keyEvent);
-
+            _eventHandler.handleKeyRelease(this, makeKeyEvent(event, _pixelModel));
             fixDamage;
-
             return true;
         }
 
         bool onMotionNotify(GdkEventMotion * event, Widget widget) {
             assert(widget is _drawingArea);
-            // Pass the events on to the rulers
-            gtk_widget_event(_hRuler.getWidgetStruct(), cast(GdkEvent *)event);
-            gtk_widget_event(_vRuler.getWidgetStruct(), cast(GdkEvent *)event);
+
+            {
+                // Pass the events on to the rulers so that they update
+                gtk_widget_event(_hRuler.getWidgetStruct(), cast(GdkEvent *)event);
+                gtk_widget_event(_vRuler.getWidgetStruct(), cast(GdkEvent *)event);
+            }
 
             _eventHandler.handleMotion(this, makeMotionEvent(event, _pixelModel));
-
             fixDamage;
-
             return true;
         }
 
         bool onScroll(GdkEventScroll * event, Widget widget) {
             assert(widget is _drawingArea);
-            //writefln("Got scroll\n");
 
-            Point pixelPoint = Point(event.x + 0.5, _pixelModel.viewBounds.h - (event.y + 0.5));
-            Point modelPoint = _pixelModel.pixelToModel(pixelPoint);
-
-            auto scrollEvent = new ScrollEvent(gtk2tkDirection(event.direction),
-                                               pixelPoint,
-                                               modelPoint,
-                                               gtk2tkMask(event.state));
-
-            _eventHandler.handleScroll(this, scrollEvent);
-
+            _eventHandler.handleScroll(this, makeScrollEvent(event, _pixelModel));
             fixDamage;
-
             return true;
         }
 
-        /*
-           public enum GdkCrossingMode {       
-           NORMAL,
-           GRAB,
-           UNGRAB,
-           GTK_GRAB,
-           GTK_UNGRAB,
-           STATE_CHANGED
-           }
-
-           public struct GdkEventCrossing {
-           GdkEventType type;
-           GdkWindow *window;
-           byte sendEvent;
-           GdkWindow *subwindow;
-           uint time;
-           double x;
-           double y;
-           double xRoot;
-           double yRoot;
-           GdkCrossingMode mode;
-           GdkNotifyType detail;
-           int focus;
-           uint state;
-           }
-         */
-
         bool onEnterNotify(GdkEventCrossing * event, Widget widget) {
             assert(widget is _drawingArea);
 
-            Point pixelPoint = Point(event.x + 0.5, _pixelModel.viewBounds.h - (event.y + 0.5));
-            Point modelPoint = _pixelModel.pixelToModel(pixelPoint);
-
-            auto crossingEvent = new CrossingEvent(gtk2tkCrossingMode(event.mode),
-                                                   pixelPoint,
-                                                   modelPoint,
-                                                   gtk2tkMask(event.state));
-
-            _eventHandler.handleEnter(this, crossingEvent);
-
+            _eventHandler.handleEnter(this, makeCrossingEvent(event, _pixelModel));
             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);
 
-            Point pixelPoint = Point(event.x + 0.5, _pixelModel.viewBounds.h - (event.y + 0.5));
-            Point modelPoint = _pixelModel.pixelToModel(pixelPoint);
-
-            auto crossingEvent = new CrossingEvent(gtk2tkCrossingMode(event.mode),
-                                                   pixelPoint,
-                                                   modelPoint,
-                                                   gtk2tkMask(event.state));
-
-            _eventHandler.handleLeave(this, crossingEvent);
-
+            _eventHandler.handleLeave(this, makeCrossingEvent(event, _pixelModel));
             fixDamage;
-
-            //message("Leave %d %d %d", cast(int)event.mode, event.focus, event.state);
-
             return true;
         }
 
-        /*
-           public struct GdkEventFocus {
-           GdkEventType type;
-           GdkWindow *window;
-           byte sendEvent;
-           short inn;
-           }
-         */
         bool onFocusIn(GdkEventFocus * event, Widget widget) {
             trace("onFocusIn");
             return true;
@@ -551,11 +482,11 @@
         }
 
         void fixDamage() {
-            if (_damage.valid) {
+            if (_damageScreen.valid) {
                 int x, y, w, h;
-                _damage.getQuantised(x, y, w, h);
+                _damageScreen.getQuantised(x, y, w, h);
                 _drawingArea.queueDrawArea(x, cast(int)_pixelModel.viewBounds.h - (y + h), w, h);
-                _damage = Rectangle.DEFAULT;
+                _damageScreen = Rectangle.DEFAULT;
             }
         }
 
@@ -565,21 +496,21 @@
             _drawingArea.grabFocus();
         }
 
-        Rectangle _damage;          // pixels
-        PixelModel _pixelModel;
+        Layer[]       _layers;
+        IEventHandler _eventHandler;
+        IGrid         _grid;
+        double        _pixelsPerMillimetre;
 
         // Child widgets:
-        HRuler _hRuler;
-        VRuler _vRuler;
-        DrawingArea _drawingArea;
-        Adjustment _hAdjustment;
-        HScrollbar _hScrollbar;
-        Adjustment _vAdjustment;
-        VScrollbar _vScrollbar;
+        HRuler        _hRuler;
+        VRuler        _vRuler;
+        DrawingArea   _drawingArea;
+        Adjustment    _hAdjustment;
+        HScrollbar    _hScrollbar;
+        Adjustment    _vAdjustment;
+        VScrollbar    _vScrollbar;
 
-        Layer[] _layers;
-        IEventHandler _eventHandler;
-        IGrid _grid;
-        double _pixelsPerMillimetre;
+        Rectangle     _damageScreen;          // in pixels
+        PixelModel    _pixelModel;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/gtk/events.d	Sun Aug 15 01:02:15 2010 +0930
@@ -0,0 +1,155 @@
+module doodle.gtk.events;
+
+public {
+    import doodle.tk.events;
+}
+
+private {
+    import doodle.gtk.conversions;
+
+    import core.stdc.string : strlen;
+}
+
+
+// Functions for creating the events
+
+/*
+   public struct GdkEventButton {
+   GdkEventType type;
+   GdkWindow *window;
+   byte sendEvent;
+   uint time;
+   double x;
+   double y;
+   double *axes;
+   uint state;
+   uint button;
+   GdkDevice *device;
+   double xRoot, yRoot;
+   }
+*/
+
+ButtonEvent makeButtonEvent(const GdkEventButton * event, in PixelModel pixelModel) {
+    Point pixelPoint = Point(event.x + 0.5, pixelModel.viewBounds.h - (event.y + 0.5));
+    Point modelPoint = pixelModel.pixelToModel(pixelPoint);
+    return new ButtonEvent(gtk2tkButtonAction(event.type),
+                           gtk2tkButtonName(event.button),
+                           pixelPoint, modelPoint, gtk2tkMask(event.state));
+}
+
+/*
+   public struct GdkEventMotion {
+   GdkEventType type;
+   GdkWindow *window;
+   byte sendEvent;
+   uint time;
+   double x;
+   double y;
+   double *axes;
+   uint state;
+   short isHint;
+   GdkDevice *device;
+   double xRoot, yRoot;
+   }
+ */
+
+MotionEvent makeMotionEvent(const GdkEventMotion * event, in PixelModel pixelModel) {
+    Point pixelPoint = Point(event.x + 0.5, pixelModel.viewBounds.h - (event.y + 0.5));
+    Point modelPoint = pixelModel.pixelToModel(pixelPoint);
+
+    return new MotionEvent(pixelPoint, modelPoint, gtk2tkMask(event.state));
+}
+
+/*
+   public struct GdkEventKey {
+   GdkEventType type;
+   GdkWindow *window;
+   byte sendEvent;
+   uint time;
+   uint state;
+   uint keyval;
+   int length;
+   char *string;
+   ushort hardwareKeycode;
+   ubyte group;
+   uint bitfield0;
+   uint isModifier : 1;
+   }
+ */
+
+KeyEvent makeKeyEvent(const GdkEventKey * event, in PixelModel pixelModel) {
+    return new KeyEvent(event.string[0..strlen(event.string)].idup,
+                        event.keyval,
+                        gtk2tkMask(event.state));
+}
+
+/*
+   public struct GdkEventScroll {
+   GdkEventType type;
+   GdkWindow *window;
+   byte sendEvent;
+   uint time;
+   double x;
+   double y;
+   uint state;
+   GdkScrollDirection direction;
+   GdkDevice *device;
+   double xRoot, yRoot;
+   }
+ */
+
+ScrollEvent makeScrollEvent(const GdkEventScroll * event, in PixelModel pixelModel) {
+    Point pixelPoint = Point(event.x + 0.5, pixelModel.viewBounds.h - (event.y + 0.5));
+    Point modelPoint = pixelModel.pixelToModel(pixelPoint);
+    return new ScrollEvent(gtk2tkDirection(event.direction),
+                           pixelPoint,
+                           modelPoint,
+                           gtk2tkMask(event.state));
+}
+
+/*
+   public enum GdkCrossingMode {       
+   NORMAL,
+   GRAB,
+   UNGRAB,
+   GTK_GRAB,
+   GTK_UNGRAB,
+   STATE_CHANGED
+   }
+
+   public struct GdkEventCrossing {
+   GdkEventType type;
+   GdkWindow *window;
+   byte sendEvent;
+   GdkWindow *subwindow;
+   uint time;
+   double x;
+   double y;
+   double xRoot;
+   double yRoot;
+   GdkCrossingMode mode;
+   GdkNotifyType detail;
+   int focus;
+   uint state;
+   }
+ */
+
+CrossingEvent makeCrossingEvent(const GdkEventCrossing * event, in PixelModel pixelModel) {
+    Point pixelPoint = Point(event.x + 0.5, pixelModel.viewBounds.h - (event.y + 0.5));
+    Point modelPoint = pixelModel.pixelToModel(pixelPoint);
+    return new CrossingEvent(gtk2tkCrossingMode(event.mode),
+                             pixelPoint,
+                             modelPoint,
+                             gtk2tkMask(event.state));
+}
+
+
+/*
+   public struct GdkEventFocus {
+   GdkEventType type;
+   GdkWindow *window;
+   byte sendEvent;
+   short inn;
+   }
+ */
+// In case we implement focus event...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/gtk/opengl.d	Sun Aug 15 01:02:15 2010 +0930
@@ -0,0 +1,10 @@
+module doodle.gtk.opengl;
+
+public {
+    import doodle.tk.drawing;
+}
+
+/*
+final class OpenGLDrawing : Drawing {
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/tk/cairo.d	Sun Aug 15 01:02:15 2010 +0930
@@ -0,0 +1,30 @@
+module doodle.tk.cairo;
+
+// THIS module is deprecated
+
+public {
+    import doodle.tk.geometry;
+    import cairo.Context;
+}
+
+void rectangle(scope Context cr, in Rectangle rectangle) {
+    cr.rectangle(rectangle.position.x, rectangle.position.y,
+                 rectangle.size.x, rectangle.size.y);
+}
+
+void line(scope Context cr, in double x0, in double y0, in double x1, in double y1) {
+    cr.moveTo(x0, y0);
+    cr.lineTo(x1, y1);
+}
+
+// Horizontal line
+void hline(scope Context cr, in double y, double x0, double x1) {
+    cr.moveTo(x0, y);
+    cr.lineTo(x1, y);
+}
+
+// Vertical line
+void vline(scope Context cr, in double x, double y0, double y1) {
+    cr.moveTo(x, y0);
+    cr.lineTo(x, y1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/tk/drawing.d	Sun Aug 15 01:02:15 2010 +0930
@@ -0,0 +1,39 @@
+module doodle.tk.drawing;
+
+public {
+    import doodle.tk.geometry;
+}
+
+interface Drawing {
+    enum LineStyle {
+        SOLID,
+        DASHED,
+        DOTTED
+    }
+
+    void setLineStyle(LineStyle style);
+    void setLineThickness(in double thickness);
+    //void setLineColor(in Color color);
+    //void setFillColor(in Color color);
+
+    void drawRectangle(in Rectangle rectangle, bool fill);
+    void drawEllipse(in Rectangle rectangle, bool fill);
+    void drawSegment(in Segment segment);
+    void drawHLine(in double y0, in double x0, in double x1);
+    void drawVLine(in double x0, in double y0, in double y1);
+    void drawPoly(in Point[] points, bool fill);
+
+    void pushState();           // Copies all of current state
+    void popState();            // Restores all of previous state
+
+    void translate(in Vector v);
+    void translate(in Point p);
+    void scale(in Vector v);
+    void zoom(in double z);
+
+    //void setFontFace;
+    //void setFontSize;
+    void drawText(in string text);
+
+    // How to fit fonts, metrics, etc in here?
+}