changeset 92:a98116479793

Removed GL support. Improved grid.
author daveb
date Fri, 20 Aug 2010 18:34:32 +0930
parents 42766e14534e
children 069ceb9446ad
files doodle/dia/grid_layer.d doodle/dia/icanvas.d doodle/dia/layer_stack.d doodle/dia/standard_tools.d doodle/dia/tool.d doodle/dia/tool_layer.d doodle/fig/diagram_layer.d doodle/gtk/cairo_canvas.d doodle/gtk/opengl_canvas.d doodle/gtk/opengl_renderer.d doodle/main/prog/doodler.d options.template
diffstat 12 files changed, 58 insertions(+), 720 deletions(-) [+]
line wrap: on
line diff
--- a/doodle/dia/grid_layer.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/dia/grid_layer.d	Fri Aug 20 18:34:32 2010 +0930
@@ -7,21 +7,20 @@
 private {
     import std.math;
     import std.stdio;
+    import std.array;
+
+    import doodle.core.logging;
 }
 
-private {
-    double start(in double value, in double spacing) {
-        real r = floor(value / spacing);
-        return r * spacing;
-    }
-}
+// Draw a grid.
+// zoom -> pixels / millimetre
+// Grid lines must have a maximum density
+// 
 
 class GridLayer : Layer, IGrid {
-    immutable double MIN_SPACING = 5.0;      // pixels
-
     this(in string name = "Grid") {
         super(name);
-        _zoomValid = false;
+        _spacingValid = false;
     }
 
     // Layer overrides:
@@ -34,15 +33,16 @@
     override void draw(in Rectangle screenDamage, scope Renderer screenRenderer,
                        in Rectangle modelDamage, scope Renderer modelRenderer,
                        in ScreenModel screenModel) const {
-        assert(_zoomValid);
+        assert(_spacingValid);
 
-        auto z = screenModel.zoom;
+        const z = screenModel.zoom;
+        const lineWidthModel = LINE_WIDTH_SCREEN / z;
 
         modelRenderer.pushState; {
-            modelRenderer.setColor(Color(0.0, 0.0, 0.0, 0.3));
-            modelRenderer.setLineWidth(1 / z);
+            modelRenderer.setColor(doodle.tk.color.Color(0.0, 0.0, 0.7, 1.0));
+            modelRenderer.setLineWidth(lineWidthModel);
 
-            auto x = start(modelDamage.corner0.x, _spacing);
+            auto x = roundDownSpacing(modelDamage.corner0.x);
 
             for (;;) {
                 modelRenderer.drawVLine(x, modelDamage.corner0.y, modelDamage.corner1.y);
@@ -50,7 +50,7 @@
                 if (x > modelDamage.corner1.x) break;
             }
 
-            auto y = start(modelDamage.corner0.y, _spacing);
+            auto y = roundDownSpacing(modelDamage.corner0.y);
 
             for (;;) {
                 modelRenderer.drawHLine(y, modelDamage.corner0.x, modelDamage.corner1.x);
@@ -62,24 +62,31 @@
 
     // IGrid overrides:
 
-    override void zoomChanged(double zoom) {
-        _zoom = zoom;
-        _zoomValid = true;
-
-        // FIXME compute spacing properly
-        _spacing = 20.0 / _zoom;        // mm
-    }
-
-    // FIXME use inout parameter?
-    override bool snap(in Point a, out Point b) const {
-        b = a;
-        return false;
+    override void zoomChanged(in double zoom) {
+        foreach (s; SPACINGS) {
+            _spacing = s;
+            double pixels = zoom * _spacing;
+            if (pixels > MIN_SPACING) { break; }
+        }
+        _spacingValid = true;
     }
 
     private {
-        bool _zoomValid;
-        double _zoom;           // pixels per millimetre
+        double roundDownSpacing(in double value) const {
+            return _spacing * floor(value / _spacing);
+        }
+
+        bool _spacingValid;
+        double _spacing;        // model spacing
 
-        double _spacing;        // model spacing
+        immutable double LINE_WIDTH_SCREEN = 0.25;
+        immutable double MIN_SPACING = 40.0;      // pixels
+        immutable double[] SPACINGS =    // millimetres
+            [
+            5.0,
+            10.0,
+            20.0,
+            50.0
+            ];
     }
 }
--- a/doodle/dia/icanvas.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/dia/icanvas.d	Fri Aug 20 18:34:32 2010 +0930
@@ -20,7 +20,7 @@
 }
 
 interface IViewport : IViewport2 {
-    void zoomRelative(in Point screenDatum, in double factor);      // FIXME reorder arguments
+    void zoomRelative(in double factor, in Point screenDatum);
     void panRelative(in Vector screenDisplacement);
     void setCursor(in Cursor cursor);
 }
@@ -38,8 +38,8 @@
     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, in CrossingEvent event);
+    bool handleLeave(scope IViewport viewport, in CrossingEvent event);
     bool handleKeyPress(scope IViewport viewport, in KeyEvent event);
     bool handleKeyRelease(scope IViewport viewport, in KeyEvent event);
 
@@ -49,14 +49,11 @@
 }
 
 interface IGrid {
-    void zoomChanged(double zoom);
+    void zoomChanged(in double zoom);
 
-    // TODO  inout?
-    bool snap(in Point a, out Point b) const;               // XXX remove this and add it to Layer
 }
 
 interface IPage {
-    // TODO
 }
 
 abstract class Layer {
@@ -68,6 +65,8 @@
 
     Rectangle bounds() const;
 
+    //bool snap(in Point a, out Point b) const;
+
     void draw(in Rectangle screenDamage, scope Renderer screenRenderer,
               in Rectangle modelDamage, scope Renderer modelRenderer,
               in ScreenModel screenModel) const;
--- a/doodle/dia/layer_stack.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/dia/layer_stack.d	Fri Aug 20 18:34:32 2010 +0930
@@ -13,7 +13,6 @@
         // Take the union of all layer bounds
         Rectangle bounds = Rectangle.DEFAULT;
         foreach (layer; _layers) { bounds = bounds | layer.bounds; }
-        //assert(bounds.valid);
         return bounds;
     }
 
--- a/doodle/dia/standard_tools.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/dia/standard_tools.d	Fri Aug 20 18:34:32 2010 +0930
@@ -106,11 +106,11 @@
     override bool handleScroll(scope IViewport viewport, in ScrollEvent event) {
         if (event.mask.isSet(Modifier.CONTROL)) {
             if (event.scrollDirection == ScrollDirection.DOWN) {
-                viewport.zoomRelative(event.screenPoint, 1.0 / ZOOM);
+                viewport.zoomRelative(1.0 / ZOOM_FACTOR, event.screenPoint);
                 return true;
             }
             else if (event.scrollDirection == ScrollDirection.UP) {
-                viewport.zoomRelative(event.screenPoint, ZOOM);
+                viewport.zoomRelative(ZOOM_FACTOR, event.screenPoint);
                 return true;
             }
             else {
@@ -123,6 +123,6 @@
     }
 
     private {
-        static immutable ZOOM = 2^^0.5;
+        static immutable ZOOM_FACTOR = 2^^0.5;
     }
 }
--- a/doodle/dia/tool.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/dia/tool.d	Fri Aug 20 18:34:32 2010 +0930
@@ -17,8 +17,8 @@
     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 IViewport viewport, CrossingEvent event) { return false; }
-    bool handleLeave(scope IViewport viewport, CrossingEvent event) { return false; }
+    bool handleEnter(scope IViewport viewport, in CrossingEvent event) { return false; }
+    bool handleLeave(scope IViewport viewport, in 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; }
--- a/doodle/dia/tool_layer.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/dia/tool_layer.d	Fri Aug 20 18:34:32 2010 +0930
@@ -116,7 +116,7 @@
         return true;
     }
 
-    bool handleEnter(scope IViewport viewport, CrossingEvent event) {
+    bool handleEnter(scope IViewport viewport, in CrossingEvent event) {
         trace("Enter %s", event);
 
         if (_grabbedTool is null) {
@@ -133,7 +133,7 @@
         return true;
     }
 
-    bool handleLeave(scope IViewport viewport, CrossingEvent event) {
+    bool handleLeave(scope IViewport viewport, in CrossingEvent event) {
         trace("Leave %s", event);
 
         if (_grabbedTool is null) {
--- a/doodle/fig/diagram_layer.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/fig/diagram_layer.d	Fri Aug 20 18:34:32 2010 +0930
@@ -20,6 +20,9 @@
     // Layer overrides:
 
     override Rectangle bounds() const {
+        // Take the union of all diagram element bounds
+        Rectangle bounds = Rectangle.DEFAULT;
+        foreach (element; _elements) { bounds = bounds | element.bounds; }
         return Rectangle.DEFAULT;
     }
 
@@ -27,7 +30,7 @@
                        in Rectangle modelDamage, scope Renderer modelRenderer,
                        in ScreenModel screenModel) const {
         foreach (e; _elements) {
-            if ((e.bounds & modelDamage).valid) {
+            if ((e.bounds & modelDamage).valid) {       // FIXME if (intersects(e.bounds, modelDamage))
                 e.draw(modelDamage, modelRenderer);
             }
         }
--- a/doodle/gtk/cairo_canvas.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/gtk/cairo_canvas.d	Fri Aug 20 18:34:32 2010 +0930
@@ -144,7 +144,7 @@
 
         // IViewport overrides:
 
-        void zoomRelative(in Point screenDatum, in double factor) {
+        void zoomRelative(in double factor, in Point screenDatum) {
             _screenModel.zoomRelative(factor, screenDatum);
             consolidateBounds;
             updateAdjustments;
--- a/doodle/gtk/opengl_canvas.d	Thu Aug 19 18:28:18 2010 +0930
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +0,0 @@
-module doodle.gtk.opengl_canvas;
-
-public {
-    import doodle.dia.icanvas;
-    import doodle.gtk.events;
-}
-
-private {
-    import doodle.core.logging;
-    import doodle.tk.screen_model;
-    import doodle.dia.layer_stack;
-    import doodle.gtk.cairo_renderer;
-
-    import cairo.Surface;
-    import cairo.Context;
-
-    import gtk.Widget;
-    import gtk.Toolbar;
-    import gtk.Table;
-    import gtk.HRuler;
-    import gtk.VRuler;
-    import gtk.Range;
-    import gtk.HScrollbar;
-    import gtk.VScrollbar;
-    import gtk.DrawingArea;
-    import gtk.Adjustment;
-
-    import gdk.Drawable;
-
-    import gtkc.gtk;
-    import gtkc.gtktypes;
-    //import gtkc.gdktypes;
-
-    import std.math;
-    import std.stdio;
-}
-
-private {
-    import gtk.DrawingArea;
-    import glgtk.GLCapability;
-    import glgdk.GLDrawable;
-    import glgdk.GLConfig;
-    import glgdk.GLContext;
-    import gtkglc.glgdktypes;
-
-    import gtkglc.gl;
-    import gtkglc.glu;
-
-    import gdk.Event;
-
-    import gtk.Widget;
-
-    import gtk.Main;
-    import gtk.MainWindow;
-}
-
-
-final class OpenGLCanvas : Table, private IViewport {
-    this(in Layer[] layers, IEventHandler eventHandler, IGrid grid, in double pixelsPerMillimetre) {
-        super(3, 3, 0);
-
-        _damageScreen = Rectangle.DEFAULT;
-
-        _eventHandler = eventHandler;
-        _grid = grid;
-        _pixelsPerMillimetre = pixelsPerMillimetre;
-
-        _layerStack = new LayerStack(layers);
-
-        // Create our child widgets and register callbacks
-
-        _hRuler = new HRuler;
-        attach(_hRuler,
-               1, 2,
-               0, 1,
-               AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK,
-               0, 0);
-        _hRuler.setMetric(MetricType.PIXELS);
-
-        _vRuler = new VRuler;
-        attach(_vRuler,
-               0, 1,
-               1, 2,
-               AttachOptions.SHRINK, AttachOptions.FILL | AttachOptions.EXPAND,
-               0, 0);
-        _vRuler.setMetric(MetricType.PIXELS);
-
-        _drawingArea = new GLDrawingArea;
-        _drawingArea.addOnRealize(&onRealize);
-        _drawingArea.addOnConfigure(&onConfigure);
-        _drawingArea.addOnExpose(&onExpose);
-        _drawingArea.addOnButtonPress(&onButtonPress);
-        _drawingArea.addOnButtonRelease(&onButtonRelease);
-        _drawingArea.addOnKeyPress(&onKeyPressEvent);
-        _drawingArea.addOnKeyRelease(&onKeyReleaseEvent);
-        _drawingArea.addOnMotionNotify(&onMotionNotify);
-        _drawingArea.addOnScroll(&onScroll);
-        _drawingArea.addOnEnterNotify(&onEnterNotify);
-        _drawingArea.addOnLeaveNotify(&onLeaveNotify);
-
-        _drawingArea.addOnFocusIn(&onFocusIn);
-        _drawingArea.addOnFocusOut(&onFocusOut);
-        _drawingArea.addOnMoveFocus(&onMoveFocus);
-        _drawingArea.addOnGrabBroken(&onGrabBroken);
-        _drawingArea.addOnGrabFocus(&onGrabFocus);
-        _drawingArea.addOnGrabNotify(&onGrabNotify);
-        // addOnPopupMenu
-        // addOnQueryTooltip
-        // addOnSelection*
-        _drawingArea.setEvents(EventMask.EXPOSURE_MASK |
-                               EventMask.POINTER_MOTION_MASK |
-                               EventMask.POINTER_MOTION_HINT_MASK |
-                               EventMask.BUTTON_MOTION_MASK |
-                               EventMask.BUTTON_PRESS_MASK |
-                               EventMask.BUTTON_RELEASE_MASK |
-                               EventMask.KEY_PRESS_MASK |
-                               EventMask.KEY_RELEASE_MASK |
-                               EventMask.ENTER_NOTIFY_MASK |
-                               EventMask.LEAVE_NOTIFY_MASK |
-                               EventMask.FOCUS_CHANGE_MASK |
-                               EventMask.SCROLL_MASK);
-
-        _drawingArea.setCanFocus(true);
-
-        attach(_drawingArea,
-               1, 2,
-               1, 2, 
-               AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL | AttachOptions.EXPAND,
-               0, 0);
-
-        // value, lower, upper, step-inc, page-inc, page-size
-        // Give the adjustments dummy values until we receive a configure
-        _hAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5);
-        _hAdjustment.addOnValueChanged(&onAdjustmentValueChanged);
-        _hScrollbar = new HScrollbar(_hAdjustment);
-        _hScrollbar.setInverted(false);
-        attach(_hScrollbar,
-               1, 2,
-               2, 3,
-               AttachOptions.FILL | AttachOptions.EXPAND,
-               AttachOptions.SHRINK,
-               0, 0);
-
-        _vAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5);
-        _vAdjustment.addOnValueChanged(&onAdjustmentValueChanged);
-        _vScrollbar = new VScrollbar(_vAdjustment);
-        _vScrollbar.setInverted(true);
-        attach(_vScrollbar,
-               2, 3,
-               1, 2,
-               AttachOptions.SHRINK,
-               AttachOptions.FILL | AttachOptions.EXPAND,
-               0, 0);
-
-        _cursors = [
-            Cursor.DEFAULT   : CursorType.ARROW,
-            Cursor.HAND      : CursorType.HAND1,
-            Cursor.CROSSHAIR : CursorType.CROSSHAIR,
-            Cursor.PENCIL    : CursorType.PENCIL
-                ];
-    }
-
-    protected {         // XXX the compiler complains about unimplemented methods if this is private
-
-        // IViewport overrides:
-
-        void zoomRelative(in Point screenDatum, in double factor) {
-            _screenModel.zoomRelative(factor, screenDatum);
-            consolidateBounds;
-            updateAdjustments;
-            updateRulers;
-            _grid.zoomChanged(_screenModel.zoom);
-            queueDraw;
-        }
-
-        void panRelative(in Vector screenDisplacement) {
-            _screenModel.panRelativeScreen(screenDisplacement);
-            consolidateBounds;
-            updateAdjustments;
-            updateRulers;
-            queueDraw;
-        }
-
-        void setCursor(in Cursor cursor) {
-            _drawingArea.setCursor(new gdk.Cursor.Cursor(_cursors[cursor]));
-        }
-
-        void damageModel(in Rectangle area) {
-            _damageScreen = _damageScreen | _screenModel.modelToScreen(area);
-        }
-
-        void damageScreen(in Rectangle area) {
-            _damageScreen = _damageScreen | area;
-        }
-    }
-
-    private {
-
-        void initialiseBounds(in Rectangle viewBoundsScreen) {
-            Rectangle layerBounds = _layerStack.bounds;
-            Rectangle paddedLayerBounds = growCentre(layerBounds, 2 * layerBounds.size);
-            _screenModel = new ScreenModel(0.25 * _pixelsPerMillimetre, paddedLayerBounds, viewBoundsScreen);
-            _grid.zoomChanged(_screenModel.zoom);
-
-            updateAdjustments;
-            updateRulers;
-        }
-
-        void consolidateBounds() {
-            Rectangle layerBounds = _layerStack.bounds;
-            Rectangle paddedLayerBounds = growCentre(layerBounds, 2 * layerBounds.size);
-            _screenModel.consolidateCanvasBounds(paddedLayerBounds);
-
-            updateAdjustments;
-            updateRulers;
-        }
-
-        bool onConfigure(GdkEventConfigure * event, Widget widget) {
-            assert(widget is _drawingArea);
-            assert(event);
-
-            trace("onConfigure %sx%s", event.width, event.height);
-
-            Rectangle viewBoundsScreen = Rectangle(Point(0.0, 0.0), Vector(cast(double)event.width, cast(double)event.height));
-            if (_screenModel is null) { initialiseBounds(viewBoundsScreen); }
-            else { consolidateBounds; }
-
-            return true;
-        }
-
-        bool onExpose(GdkEventExpose * event, Widget widget) {
-            assert(widget is _drawingArea);
-            assert(event);
-
-            trace("onExpose %sx%s", event.area.width, event.area.height);
-
-            /+
-                Drawable dr = _drawingArea.getWindow;
-
-            int width, height;
-            dr.getSize(width, height);
-            //trace("Got expose %dx%d\n", width, height);
-
-            scope modelCr = new Context(dr);
-            scope screenCr = new Context(dr);
-
-            Rectangle screenDamage =
-                event is null ? _screenModel.viewBoundsScreen :
-                Rectangle(_screenModel.viewBoundsScreen.position + Vector(cast(double)event.area.x, _screenModel.viewBoundsScreen.h - cast(double)(event.area.y + event.area.height)),
-                          Vector(cast(double)event.area.width, cast(double)event.area.height));
-
-            Rectangle modelDamage = _screenModel.screenToModel(screenDamage);
-
-            modelCr.save; screenCr.save; {
-                {
-                    // Setup model context and clip
-                    modelCr.translate(0.0, _screenModel.viewBoundsScreen.h);
-                    modelCr.scale(_screenModel.zoom, -_screenModel.zoom);
-
-                    immutable Point viewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
-                    modelCr.translate(-viewLeftBottom.x, -viewLeftBottom.y);
-
-                    modelCr.rectangle(modelDamage.x0, modelDamage.y0, modelDamage.w, modelDamage.h);
-                    modelCr.clip;
-                }
-
-                {
-                    // Setup screen context and clip
-                    screenCr.translate(0.0, _screenModel.viewBoundsScreen.h);
-                    screenCr.scale(1.0, -1.0);
-
-                    screenCr.rectangle(screenDamage.x0, screenDamage.y0, screenDamage.w, screenDamage.h);
-                    screenCr.clip;
-                }
-
-                screenCr.save; {
-                    // Fill the background with light grey
-                    screenCr.setSourceRgba(0.9, 0.9, 0.9, 1.0);
-                    screenCr.rectangle(screenDamage.x0, screenDamage.y0, screenDamage.w, screenDamage.h);
-                    screenCr.fill;
-                } screenCr.restore;
-
-                _layerStack.draw(screenDamage, new CairoRenderer(screenCr),
-                                 modelDamage, new CairoRenderer(modelCr));
-            } screenCr.restore; modelCr.restore;
-
-            return true;
-            +/
-
-                return false;
-        }
-
-        bool onButtonPress(GdkEventButton * event, Widget widget) {
-            assert(widget is _drawingArea);
-            _eventHandler.handleButtonPress(this, makeButtonEvent(event, _screenModel));
-            fixDamage;
-            return true;
-        }
-
-        bool onButtonRelease(GdkEventButton * event, Widget widget) {
-            assert(widget is _drawingArea);
-            _eventHandler.handleButtonRelease(this, makeButtonEvent(event, _screenModel));
-            fixDamage;
-            return true;
-        }
-
-        bool onKeyPressEvent(GdkEventKey * event, Widget widget) {
-            assert(widget is _drawingArea);
-            _eventHandler.handleKeyPress(this, makeKeyEvent(event, _screenModel));
-            fixDamage;
-            return true;
-        }
-
-        bool onKeyReleaseEvent(GdkEventKey * event, Widget widget) {
-            assert(widget is _drawingArea);
-            _eventHandler.handleKeyRelease(this, makeKeyEvent(event, _screenModel));
-            fixDamage;
-            return true;
-        }
-
-        bool onMotionNotify(GdkEventMotion * event, Widget widget) {
-            assert(widget is _drawingArea);
-
-            // 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, _screenModel));
-            fixDamage;
-            return true;
-        }
-
-        bool onScroll(GdkEventScroll * event, Widget widget) {
-            assert(widget is _drawingArea);
-            _eventHandler.handleScroll(this, makeScrollEvent(event, _screenModel));
-            fixDamage;
-            return true;
-        }
-
-        bool onEnterNotify(GdkEventCrossing * event, Widget widget) {
-            trace("1");
-            assert(widget is _drawingArea);
-            trace("2");
-            _eventHandler.handleEnter(this, makeCrossingEvent(event, _screenModel));
-            trace("3");
-            fixDamage;
-            trace("4");
-            return true;
-        }
-
-        bool onLeaveNotify(GdkEventCrossing * event, Widget widget) {
-            assert(widget is _drawingArea);
-            _eventHandler.handleLeave(this, makeCrossingEvent(event, _screenModel));
-            fixDamage;
-            return true;
-        }
-
-        bool onFocusIn(GdkEventFocus * event, Widget widget) {
-            trace("onFocusIn");
-            return true;
-        }
-
-        bool onFocusOut(GdkEventFocus * event, Widget widget) {
-            trace("onFocusOut");
-            return true;
-        }
-
-        void onMoveFocus(GtkDirectionType direction, Widget widget) {
-            trace("onMoveFocus");
-        }
-
-        bool onGrabBroken(gdk.Event.Event event, Widget widget) {
-            trace("onGrabBroken");
-            return true;
-        }
-
-        void onGrabFocus(Widget widget) {
-            //trace("onGrabFocus");
-        }
-
-        void onGrabNotify(gboolean what, Widget widget){
-            trace("onGrabNotify");
-        }
-
-        void onAdjustmentValueChanged(Adjustment adjustment) {
-            GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct;
-            GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct;
-
-            Point oldViewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
-            Point newViewLeftBottom = Point(gtk_adjustment_get_value(hGtkAdjustment),
-                                            gtk_adjustment_get_value(vGtkAdjustment));
-
-            _screenModel.panRelativeModel(newViewLeftBottom - oldViewLeftBottom);
-
-            updateRulers;
-            queueDraw;
-        }
-
-        void updateRulers() {
-            immutable Point viewLeftBottom = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner0);
-            immutable Point viewRightTop = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner1);
-
-            // Define these just to obtain the position
-            // below so we can preserve it
-            double lower, upper, position, maxSize;
-
-            _hRuler.getRange(lower, upper, position, maxSize);
-            _hRuler.setRange(viewLeftBottom.x,
-                             viewRightTop.x,
-                             position,
-                             _screenModel.zoom * 50.0);
-
-            _vRuler.getRange(lower, upper, position, maxSize);
-            _vRuler.setRange(viewRightTop.y,
-                             viewLeftBottom.y,
-                             position,
-                             _screenModel.zoom * 50.0);
-        }
-
-        void updateAdjustments() {
-            immutable Point viewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
-            immutable Point viewRightTop = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner1);
-
-            // Adjust the canvas size if necessary
-            _screenModel.canvasAccommodate(Rectangle(viewLeftBottom, viewRightTop));
-
-            Rectangle viewBoundsModel = _screenModel.viewBoundsModel;
-
-            // Update the adjustments
-
-            GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct;
-            GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct;
-
-            gtk_adjustment_set_lower(hGtkAdjustment, _screenModel.canvasBoundsModel.x0);
-            gtk_adjustment_set_upper(hGtkAdjustment, _screenModel.canvasBoundsModel.x1);
-            gtk_adjustment_set_value(hGtkAdjustment, viewLeftBottom.x);
-            gtk_adjustment_set_step_increment(hGtkAdjustment, _screenModel.canvasBoundsModel.w / 16.0);
-            gtk_adjustment_set_page_increment(hGtkAdjustment, _screenModel.canvasBoundsModel.w / 4.0);
-            gtk_adjustment_set_page_size(hGtkAdjustment, viewBoundsModel.w);
-
-            gtk_adjustment_set_lower(vGtkAdjustment, _screenModel.canvasBoundsModel.y0);
-            gtk_adjustment_set_upper(vGtkAdjustment, _screenModel.canvasBoundsModel.y1);
-            gtk_adjustment_set_value(vGtkAdjustment, viewLeftBottom.y);
-            gtk_adjustment_set_step_increment(vGtkAdjustment, _screenModel.canvasBoundsModel.h / 16.0);
-            gtk_adjustment_set_page_increment(vGtkAdjustment, _screenModel.canvasBoundsModel.h / 4.0);
-            gtk_adjustment_set_page_size(vGtkAdjustment, viewBoundsModel.h);
-
-            _hAdjustment.changed;
-            _hAdjustment.valueChanged;
-            _vAdjustment.changed;
-            _vAdjustment.valueChanged;
-        }
-
-        void fixDamage() {
-            if (_damageScreen.valid) {
-                int x, y, w, h;
-                _damageScreen.getQuantised(x, y, w, h);
-                _drawingArea.queueDrawArea(x, cast(int)_screenModel.viewBoundsScreen.h - (y + h), w, h);
-                _damageScreen = Rectangle.DEFAULT;
-            }
-        }
-
-        void onRealize(Widget widget) {
-            assert(widget is _drawingArea);
-            _drawingArea.grabFocus();
-        }
-
-        IEventHandler _eventHandler;
-        IGrid         _grid;
-        double        _pixelsPerMillimetre;
-        LayerStack    _layerStack;
-
-        // Child widgets:
-        HRuler        _hRuler;
-        VRuler        _vRuler;
-        DrawingArea   _drawingArea;
-        Adjustment    _hAdjustment;
-        HScrollbar    _hScrollbar;
-        Adjustment    _vAdjustment;
-        VScrollbar    _vScrollbar;
-
-        Rectangle     _damageScreen;
-        ScreenModel   _screenModel;
-
-        immutable CursorType[Cursor] _cursors;
-    }
-
-    private {
-        class GLDrawingArea : DrawingArea {
-            GLfloat width;
-            GLfloat height;
-
-            /** need to include the mixin to add GL capabilities to this widget */
-            mixin GLCapability;
-
-            /**
-             * Construct a simple DrawingArea and sets the GLCapabilities
-             */
-            this() {
-                setGLCapability();	// set the GL capabilities for this widget
-            }
-
-            /**
-             * put any gl initializations here
-             * returns true to consume the event
-             */
-            bool initGL() {
-                trace("initGL");
-
-                //resizeGL(null);
-                return false;
-            }
-
-            /**
-             * This method is called every time the window must be paint or repaint
-             * This is where you put the OpenGL call to draw something.
-             * This method call be called directly by the application without an event object
-             * to force redrawing of the scene.
-             * returns true to consume the event
-             */
-            bool drawGL(GdkEventExpose* event = null) {
-                trace("drawGL");
-
-                glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-                glLoadIdentity ();
-
-                gluLookAt(0, 0, 10, 0, 0, 0, 0, 1,0); //Set the camera position
-
-                //Just Draw a tri-colored triangle
-                glBegin(GL_TRIANGLES);
-                glColor3f(1.0f,0.0f,0.0f);
-                glVertex3f( 0.0f, 1.0f, 0.0f);
-                glColor3f(0.0f,1.0f,0.0f);
-                glVertex3f(-1.0f,-1.0f, 0.0f);
-                glColor3f(0.0f,0.0f,1.0f);
-                glVertex3f( 1.0f,-1.0f, 0.0f);
-                glEnd();
-
-                return false;
-            }
-
-            /**
-             * This method is called when the window is resized
-             * returns true to consume the event
-             */
-            bool resizeGL(GdkEventConfigure* event = null) {
-                trace("resizeGL");
-                assert(event);
-
-                if (event == null) {
-                    width = getWidth();
-                    height = getHeight();
-                }
-                else {
-                    width = event.width;
-                    height = event.height;
-                }
-
-                trace("Size %sx%s", width, height);
-
-                glViewport(0, 0, cast(int)width, cast(int)height); //Adjust the viewport according to new window dimensions 
-
-                /*
-                 * Update the projection Matrix accoding to the new dimension
-                 * and reset the OpenGL state to MODELVIEW
-                 */
-                glMatrixMode(GL_PROJECTION);
-                glLoadIdentity();
-                gluPerspective(20, width/height, 0.1, 10);
-                glMatrixMode(GL_MODELVIEW);
-
-                return false;
-            }
-        }
-    }
-}
--- a/doodle/gtk/opengl_renderer.d	Thu Aug 19 18:28:18 2010 +0930
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-module doodle.gtk.opengl;
-
-public {
-    import doodle.tk.renderer;
-}
-
-private {
-    import gtkglc.gl;
-    import gtkglc.glu;
-}
-
-final class OpenGLRenderer : Renderer {
-    void setLineStyle(LineStyle style) {
-        GLint factor;
-        GLushort pattern;
-
-        switch (style) {
-        case LineStyle.SOLID:
-            factor = 1;
-            pattern = 0xffff;
-            break;
-        case LineStyle.DASHED:
-            factor = 1;
-            pattern = 0x0f0f;
-            break;
-        case LineStyle.DOTTED:
-            factor = 1;
-            pattern = 0xefef;
-            break;
-        default:
-            assert(0);
-        }
-        glLineStipple(factor, pattern);
-    }
-
-    void setLineWidth(in double width) {
-        glLineWidth(width);             // FIXME must take scale into account
-    }
-
-    void setColor(in Color color) {
-        glColor4d(color.r, color.g, color.b, color.a);
-    }
-
-    void translate(in Point p) {
-        glTranslated(p.x, p.y, 0.0);
-    }
-
-    void scale(in double s) {
-        glScaled(s, s, 1.0);
-    }
-
-    void pushState() {
-        glPushAttrib(0);
-    }
-
-    void popState() {
-        glPopAttrib();
-    }
-
-    void drawRectangle(in Rectangle rectangle, bool fill) {
-        glBegin(fill ? GL_QUADS : GL_LINE_LOOP);
-        glVertex2d(rectangle.x0, rectangle.y0);
-        glVertex2d(rectangle.x0, rectangle.y1);
-        glVertex2d(rectangle.x1, rectangle.y1);
-        glVertex2d(rectangle.x1, rectangle.y0);
-        glEnd();
-    }
-
-    void drawEllipse(in Rectangle rectangle, bool fill);
-    void drawSegment(in Segment segment);
-    void drawHLine(in double y, in double x0, in double x1);
-    void drawVLine(in double x, in double y0, in double y1);
-    void drawPoly(in Point[] points, bool fill);
-
-    void setFontFace(in FontFace face);
-    void setFontSize(in double size);
-    void drawText(in string text);
-
-    void measureText(in string text, out Rectangle logicalBounds, out Rectangle totalBounds) const;
-}
--- a/doodle/main/prog/doodler.d	Thu Aug 19 18:28:18 2010 +0930
+++ b/doodle/main/prog/doodler.d	Fri Aug 20 18:34:32 2010 +0930
@@ -1,7 +1,5 @@
 module main.prog.doodler;
 
-immutable useOpenGL = false;
-
 private {
     import doodle.core.backtrace;
     import doodle.core.logging;
@@ -19,13 +17,7 @@
 
     import doodle.gtk.palette;
 
-    static if (useOpenGL) {
-        import doodle.gtk.opengl_canvas;
-        import glgdk.GLdInit;
-    }
-    else {
-        import doodle.gtk.cairo_canvas;
-    }
+    import doodle.gtk.cairo_canvas;
 
     import gtk.Main;
     import gtk.MainWindow;
@@ -37,7 +29,6 @@
 final class TopLevel : private IToolStackObserver {
     this(string[] args) {
         Main.init(args);
-        static if (useOpenGL) { GLdInit.init(args); }
         auto window = new MainWindow("Doodle");
         auto vbox = new VBox(false, 0);
 
@@ -61,17 +52,13 @@
         Layer[] layers;
         layers ~= new PageLayer;
         layers ~= gridLayer;
+        layers ~= diagramLayer;
         layers ~= toolLayer;
 
         // assume the screen has PPI of 120.0
         immutable millimetersPerInch = 25.4;
         immutable pixelsPerMillimetre = 120.0 / millimetersPerInch;
-        static if (useOpenGL) {
-            auto canvas = new OpenGLCanvas(layers, toolLayer, gridLayer, pixelsPerMillimetre);
-        }
-        else {
-            auto canvas = new CairoCanvas(layers, toolLayer, gridLayer, pixelsPerMillimetre);
-        }
+        auto canvas = new CairoCanvas(layers, toolLayer, gridLayer, pixelsPerMillimetre);
 
         vbox.packStart(canvas, true, true, 0);
 
--- a/options.template	Thu Aug 19 18:28:18 2010 +0930
+++ b/options.template	Fri Aug 20 18:34:32 2010 +0930
@@ -1,6 +1,5 @@
 -I~/source/d/dmd/include/d
 -L-lgtkd
--L-lgtkdgl -L-lGL -L-lGLU
 -L-ldl
 -w
 -wi