changeset 25:8f58a8f88735

Checkpoint
author "David Bryant <bagnose@gmail.com>"
date Wed, 15 Jul 2009 23:49:02 +0930
parents a24c13bb9c98
children 06c30d250c0a
files common/undo.d import/canvas.d import/geometry.d import/undo.d tk/geometry.d undo_manager.d
diffstat 6 files changed, 183 insertions(+), 406 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/undo.d	Wed Jul 15 23:49:02 2009 +0930
@@ -0,0 +1,15 @@
+module common.undo;
+
+abstract class Action {
+    void undo();
+    void redo();
+}
+
+interface IUndoObserver {
+    void canUndo(in bool value, in string description);
+    void canRedo(in bool value, in string description);
+}
+
+interface IUndoManager {
+    void addAction(Action action);
+}
--- a/import/canvas.d	Wed Jul 15 23:39:29 2009 +0930
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-module interaction.canvas;
-
-import presentation.geometry;
-
-// World coordinates
-
-interface Canvas {
-    // color, line color, line style, line width, fill color,
-    // stroke, fill,
-    // image
-    // text, clip,
-}
-
-// Pixel coordinates
-
-interface Screen {
-}
--- a/import/geometry.d	Wed Jul 15 23:39:29 2009 +0930
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-module interaction.geometry;
-
-private import std.math;
-
-private const double EPSILON = 1e-20;
-
-final class Point {
-    this() {
-        this(0.0, 0.0);
-    }
-
-    this(double x, double y) {
-        _x = x;
-        _y = y;
-    }
-
-    char[] toString() {
-        return "(" ~ std.string.toString(_x) ~ ", " ~ std.string.toString(_y) ~ ")";
-    }
-
-    Point opAdd(in Vector v) {
-        return new Point(_x + v._x, _y + v._y);
-    }
-
-    Vector opSub(in Point p) {
-        return new Vector(_x - p._x, _y - p._y);
-    }
-
-    double x() { return _x; }
-    double y() { return _y; }
-
-    private {
-        double _x;
-        double _y;
-    }
-}
-
-//
-
-final class Vector {
-    this() {
-        this(0.0, 0.0);
-    }
-
-    this(double x, double y) {
-        _x = x;
-        _y = y;
-    }
-
-    char[] toString() {
-        return "[" ~ std.string.toString(_x) ~ ", " ~ std.string.toString(_y) ~ "]";
-    }
-
-    Vector opAdd(in Vector v) {
-        return new Vector(_x + v._x, _y + v._y);
-    }
-
-    Vector opSub(in Vector v) {
-        return new Vector(_x - v._x, _y - v._y);
-    }
-
-    Vector opNeg() {
-        return new Vector(-_x, -_y);
-    }
-
-    Vector opMul_r(double d) {
-        return new Vector(d * _x, d * _y);
-    }
-
-    double length() {
-        return sqrt(_x * _x + _y * _y);
-    }
-
-    bool has_length() {
-        return _x * _x + _y * _y > EPSILON * EPSILON;
-    }
-
-    double x() { return _x; }
-    double y() { return _y; }
-
-    private {
-        double _x;
-        double _y;
-    }
-}
-
-//
-
-final class Segment {
-    this() {
-    }
-
-    this(Point start, Point end) {
-        _start = start;
-        _end = end;
-    }
-
-    Point start() { return _start; }
-    Point end() { return _end; }
-
-    private {
-        Point _start;
-        Point _end;
-    }
-}
-
-//
-
-final class Line {
-    this() {
-    }
-
-    this(Point point, Vector vector) {
-        assert(vector.has_length);
-        _point = point;
-        _vector = vector;
-    }
-
-    this(Point point1, Point point2) {
-        _point = point1;
-        _vector = point2 - point1;
-        assert(_vector.has_length);
-    }
-
-    private {
-        Point _point;
-        Vector _vector;
-    }
-}
-
-//
-
-final class Rectangle {
-    this() {
-        this(0.0, 0.0, 0.0, 0.0);
-    }
-
-    this(double x, double y, double w, double h) {
-        assert(w >= 0.0);
-        assert(h >= 0.0);
-        _x = x;
-        _y = y;
-        _w = w;
-        _h = h;
-    }
-
-    double x() { return _x; }
-    double y() { return _y; }
-    double w() { return _w; }
-    double h() { return _h; }
-    double xw() { return _x + _w; }
-    double yh() { return _y + _h; }
-
-    /*
-    Point corner00() { return new Point(_x,      _y     ); }
-    Point corner10() { return new Point(_x + _w, _y     ); }
-    Point corner11() { return new Point(_x + _w, _y + _h); }
-    Point corner01() { return new Point(_x,      _y + _h); }
-
-    Point centre() { return new Point(_x + _w / 2.0, _y + _h / 2.0); }
-    */
-
-    double area() {
-        return _w * _h;
-    }
-
-    bool has_area() {
-        return area > 0.0;
-    }
-
-    bool contains(Point point) {
-        return point.x > x && point.x < xw & point.y > y && point.y < xy;
-    }
-
-    bool contains(Segment segment) {
-        return contains(segment.start, segment.end);
-    }
-
-    private double _x, _y, _w, _h;
-}
-
-unittest {
-    const double absdiff = 1e-20, reldiff= 1e-20;
-
-    bool cmpdouble(in double lhs, in double rhs) {
-        double adiff = fabs(rhs - lhs);
-
-        if (adiff < absdiff && adiff > -absdiff) {
-            return true;
-        }
-
-        if (fabs(lhs) > absdiff && fabs(rhs) > absdiff) {
-            double rdiff = rhs / lhs;
-
-            if (rdiff < (1.0 + reldiff) && rdiff > 1.0 / (1.0 + reldiff)) {
-                return true;
-            }
-        }
-
-        // They must differ significantly
-
-        return false;
-    }
-
-    bool cmpvector(in Vector lhs, in Vector rhs) {
-        return cmpdouble(lhs._x, rhs._x) && cmpdouble(lhs._y, rhs._y);
-    }
-
-    bool cmppoint(in Point lhs, in Point rhs) {
-        return cmpdouble(lhs._x, rhs._x) && cmpdouble(lhs._y, rhs._y);
-    }
-
-    assert(cmpvector(new Vector(0.0, 0.0), new Vector));
-    assert(!cmpvector(new Vector(0.0, 1e-10), new Vector));
-    assert(cmpvector(new Vector(1.0, 2.0) + new Vector(3.0, 4.0), new Vector(4.0, 6.0)));
-    assert(cmpvector(new Vector(1.0, 2.0) - new Vector(3.0, 4.0), new Vector(-2.0, -2.0)));
-    assert(cmpvector(-(new Vector(1.0, 2.0)), new Vector(-1.0, -2.0)));
-    assert(cmpdouble((new Vector(3.0, 4.0)).length(), 5.0));
-    assert(cmpvector(3.0 * (new Vector(3.0, 4.0)), new Vector(9.0, 12.0)));
-}
--- a/import/undo.d	Wed Jul 15 23:39:29 2009 +0930
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-module dog.core.undo;
-
-import util.list;
-
-abstract class Action {
-    void undo();
-    void redo();
-}
-
-interface IUndoObserver {
-    void canUndo(bool value, char[] description);
-    void canRedo(bool value, char[] description);
-}
-
-interface IUndoManager {
-    void addAction(Action action);
-}
-
-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);
-                foreachreverse(UndoAction ua; _actions) {
-                    ua.undo();
-                }
-            }
-
-            void redo() {
-                assert(_finalised);
-                foreach (UndoAction ua; _actions) {
-                    ua.redo();
-                }
-            }
-
-            void undo() {
-                assert(_finalised);
-                foreachreverse(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;
-    }
-}
--- a/tk/geometry.d	Wed Jul 15 23:39:29 2009 +0930
+++ b/tk/geometry.d	Wed Jul 15 23:49:02 2009 +0930
@@ -233,3 +233,18 @@
         Vector _size;
     }
 }
+
+/*
+struct Segment {
+    private {
+        Point _begin, _end;
+    }
+}
+
+struct Line {
+    private {
+        Point _point;
+        Vector _gradien;
+    }
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/undo_manager.d	Wed Jul 15 23:49:02 2009 +0930
@@ -0,0 +1,153 @@
+module undo_manager;
+
+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);
+                foreachreverse(UndoAction ua; _actions) {
+                    ua.undo();
+                }
+            }
+
+            void redo() {
+                assert(_finalised);
+                foreach (UndoAction ua; _actions) {
+                    ua.redo();
+                }
+            }
+
+            void undo() {
+                assert(_finalised);
+                foreachreverse(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;
+    }
+}