changeset 35:3f6bb0bb22dc

Beginnings of grid
author David Bryant <bagnose@gmail.com>
date Sun, 30 Aug 2009 22:14:01 +0930
parents c2f11e1d7470
children 188397ef9a12
files doodle/cairo/routines.d doodle/dia/grid_layer.d doodle/dia/icanvas.d doodle/gtk/canvas.d doodle/main/prog/doodler.d doodle/main/undo_manager.d doodle/tk/test/test2.d
diffstat 7 files changed, 113 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/doodle/cairo/routines.d	Sun Aug 30 15:32:12 2009 +0930
+++ b/doodle/cairo/routines.d	Sun Aug 30 22:14:01 2009 +0930
@@ -9,3 +9,8 @@
     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);
+}
--- a/doodle/dia/grid_layer.d	Sun Aug 30 15:32:12 2009 +0930
+++ b/doodle/dia/grid_layer.d	Sun Aug 30 22:14:01 2009 +0930
@@ -7,17 +7,25 @@
 private {
     import doodle.cairo.routines;
     import std.math;
+    import std.stdio;
 }
 
-interface Grid {
-    //void zoom_changed();
+private {
+    double start(in double value, in double spacing) {
+        real r = floor(value / spacing);
+        return r * spacing;
+    }
 }
 
 class GridLayer : Layer, Grid {
+    static const double MIN_SPACING = 5.0;      // pixels
+
     this(in string name) {
         super(name);
     }
 
+    // Layer overrides:
+
     override Rectangle bounds() const {
         // We don't require any geometry
         return Rectangle();
@@ -26,11 +34,69 @@
     override void draw(in Viewport viewport,
                        in Rectangle pixel_damage, scope Context pixel_cr,
                        in Rectangle model_damage, scope Context model_cr) const {
-        //double zoom = viewport.zoom;
+        assert(mZoomValid);
+
+        model_cr.save(); {
+            model_cr.setLineWidth(1.0);
+
+            {
+                // vertical grid lines
+                double x = start(model_damage.min_corner.x, mSpacing);
+                double y0 = model_damage.min_corner.y;
+                double y1 = model_damage.max_corner.y;
+
+                for (;;) {
+                    line(model_cr, x, y0, x, y1);
+                    model_cr.stroke();
+
+                    if (x > model_damage.max_corner.x) {
+                        break;
+                    }
+
+                    x += mSpacing;
+                }
+            }
+
+            {
+                // horizontal grid lines
+                double y = start(model_damage.min_corner.y, mSpacing);
+                double x0 = model_damage.min_corner.x;
+                double x1 = model_damage.max_corner.x;
+
+                for (;;) {
+                    line(model_cr, x0, y, x1, y);
+                    model_cr.stroke();
+
+                    if (y > model_damage.max_corner.y) {
+                        break;
+                    }
+
+                    y += mSpacing;
+                }
+            }
+        } model_cr.restore();
+
 
         //double start_x = modf(damage.min_corner.x, zoom);
     }
 
+    // Grid overrides:
+
+    void zoom_changed(double zoom) {
+        mZoom = zoom;
+        mZoomValid = true;
+        mSpacing = 20.0;        // mm
+    }
+
+    bool snap(in Point a, out Point b) const {
+        b = a;
+        return false;
+    }
+
     private {
+        bool mZoomValid;
+        double mZoom;           // pixels per millimetre
+
+        double mSpacing;        // model spacing
     }
 }
--- a/doodle/dia/icanvas.d	Sun Aug 30 15:32:12 2009 +0930
+++ b/doodle/dia/icanvas.d	Sun Aug 30 22:14:01 2009 +0930
@@ -23,7 +23,7 @@
     void damage_pixel(in Rectangle area);      // FIXME as above
 
     /*
-    // FIXME not sure about these:
+    // FIXME hoping we won't need anything like this
     double zoom() const;
     Point model_to_pixel(in Point model) const;
     Point pixel_to_model(in Point pixel) const;
@@ -49,6 +49,13 @@
     bool handle_key_release(scope Viewport viewport, in KeyEvent event);
 }
 
+interface Grid {
+    void zoom_changed(double zoom);
+
+    // TODO 
+    bool snap(in Point a, out Point b) const;
+}
+
 abstract class Layer {
     this(in string name) {
         mName = name;
@@ -57,7 +64,7 @@
     string name() const { return mName; }
 
     Rectangle bounds() const;
-    //void zoom_changed
+
     void draw(in Viewport viewport,
               in Rectangle pixel_damage, scope Context pixel_cr,
               in Rectangle model_damage, scope Context model_cr) const;
--- a/doodle/gtk/canvas.d	Sun Aug 30 15:32:12 2009 +0930
+++ b/doodle/gtk/canvas.d	Sun Aug 30 22:14:01 2009 +0930
@@ -34,13 +34,14 @@
 // x and y run right and up respectively
 
 class Canvas : Table, Viewport {
-    this(in Layer[] layers, EventHandler event_handler, in double ppi) {
+    this(in Layer[] layers, EventHandler event_handler, Grid grid, in double ppi) {
         super(3, 3, 0);
 
         mDamage = Rectangle.DEFAULT;
 
         mLayers = layers.dup;
         mEventHandler = event_handler;
+        mGrid = grid;
         mPPI = ppi;
 
         /*
@@ -134,6 +135,7 @@
 
         update_adjustments;
         update_rulers;
+        mGrid.zoom_changed(mZoom);
         queueDraw;
     }
 
@@ -194,6 +196,8 @@
                 mCanvasBounds = expand(move(layer_bounds, -layer_bounds.size), 2.0 * layer_bounds.size);
                 mViewCentre = mCanvasBounds.centre;
 
+                mGrid.zoom_changed(mZoom);
+
                 mHadConfigure = true;
             }
 
@@ -542,9 +546,9 @@
         Adjustment mVAdjustment;
         VScrollbar mVScrollbar;
 
-        // Layers:
         Layer[] mLayers;
         EventHandler mEventHandler;
+        Grid mGrid;
         double mPPI;
     }
 }
--- a/doodle/main/prog/doodler.d	Sun Aug 30 15:32:12 2009 +0930
+++ b/doodle/main/prog/doodler.d	Sun Aug 30 22:14:01 2009 +0930
@@ -1,6 +1,7 @@
 private {
     import doodle.dia.tool_layer;
     import doodle.dia.standard_tools;
+    import doodle.dia.grid_layer;
     import doodle.dia.page_layer;
 
     import doodle.gtk.canvas;
@@ -24,14 +25,15 @@
     tools ~= new ZoomTool;
     tools ~= new LassoTool;
     auto tool_layer = new ToolLayer(tools, "Tools");
+    auto grid_layer = new GridLayer("Grid");
     Layer[] layers;
     layers ~= new PageLayer("Page");
+    layers ~= grid_layer;
     layers ~= tool_layer;
-    auto canvas = new Canvas(layers, tool_layer, 120.0);
+    auto canvas = new Canvas(layers, tool_layer, grid_layer, 120.0);
     vbox.packStart(canvas, true, true, 0);
     window.add(vbox);
     window.setDefaultSize(380, 380);
     window.showAll();
     Main.run();
-
 }
--- a/doodle/main/undo_manager.d	Sun Aug 30 15:32:12 2009 +0930
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-module doodle.main.undo_manager;
-
-version(none) {
-
-class UndoManager : IUndoManager {
-    this() {
-    }
-
-    void addObserver(IUndoObserver observer) {
-        _observers.add(observer);
-    }
-
-    void removeObserver(IUndoObserver observer) {
-        _observers.remove(observer);
-    }
-
-    void reset() {
-        assert(!inTransaction());
-        _past.clear();
-        _future.clear();
-        foreach(IUndoObserver obs; _observers) {
-            obs.canUndo(false, "");
-            obs.canRedo(false, "");
-        }
-    }
-
-    void undo() {
-        assert(canUndo());
-        Transaction t = _past.pop();
-        t.undo();
-        _future.push(t);
-    }
-
-    void redo() {
-        assert(canRedo());
-        Transaction t = _future.pop();
-        t.redo();
-        _past.push(t);
-    }
-
-    bool canUndo() {
-        assert(!inTransaction());
-        return !_past.empty();
-    }
-
-    bool canRedo() {
-        assert(!inTransaction());
-        return !_future.empty();
-    }
-
-    void beginTransaction(char[] description) {
-        assert(!inTransaction());
-        _current_transaction = new Transaction(description);
-    }
-
-    void cancelTransaction() {
-        assert(inTransaction());
-        _current_transaction.cancel();
-        _current_transaction = null;
-    }
-
-    void endTransaction() {
-        assert(inTransaction());
-        _current_transaction.finalise();
-
-        if (!_future.empty()) {
-            _future.clear();
-            foreach(IUndoObserver obs; _observers) {
-                obs.canRedo(false, "");
-            }
-        }
-
-        _past.push(_current_transaction);
-
-        foreach(IUndoObserver obs; _observers) {
-            bs.canUndo(true, _current_transaction.name());
-        }
-
-        _current_transaction = null;
-    }
-
-    // IUndoManager implementations:
-
-    void addAction(Action action) {
-        assert(inTransaction());
-        _current_transaction.add(action);
-    }
-
-    private {
-        bool inTransaction() {
-            return _current_transaction !is null;
-        }
-
-        class Transaction {
-            enum State {
-                Accumulating,
-                Finalised,
-                Canceled
-            }
-
-            this(char[] description) {
-                _description = description;
-                _state = Accumulating;
-            }
-
-            char[] description() {
-                return _description;
-            }
-
-            void add(Action action) {
-                assert(_state == State.Accumulating);
-                _actions.addTail(action);
-            }
-
-            void finalise() {
-                assert(_state == State.Accumulating);
-                assert(!_actions.empty());
-                _finalised = true;
-            }
-
-            void cancel() {
-                assert(_state == State.Accumulating);
-                foreach_reverse(UndoAction ua; _actions) {
-                    ua.undo();
-                }
-            }
-
-            void redo() {
-                assert(_finalised);
-                foreach (UndoAction ua; _actions) {
-                    ua.redo();
-                }
-            }
-
-            void undo() {
-                assert(_finalised);
-                foreach_reverse(UndoAction ua; _actions) {
-                    ua.undo();
-                }
-            }
-
-            private {
-                char[] _description;
-                List!(Action) _actions;
-                State _state;
-            }
-        }
-
-        Transaction _current_transaction;
-        Stack!(Transaction) _past;
-        Stack!(Transaction) _future;
-        Set!(IUndoObserver) _observers;
-    }
-}
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/tk/test/test2.d	Sun Aug 30 22:14:01 2009 +0930
@@ -0,0 +1,20 @@
+private {
+    import std.stdio;
+    import std.math;
+}
+
+private {
+    double start(in double value, in double spacing) {
+        real r = floor(value / spacing);
+        return r * spacing;
+    }
+}
+
+void test(double a, double b) {
+    double c = start(a, b);
+    writefln("%f %f %f", a, b, c);
+}
+
+void main(string[] args) {
+    test(-100.0, 10.1);
+}