changeset 96:66210d8ea37a

Added some junk
author David Bryant <bagnose@gmail.com>
date Thu, 26 Aug 2010 16:32:07 +0930
parents 85589f7a3a28
children dcd641209671
files doodle/fig/diagram_elements.d doodle/fig/diagram_layer.d doodle/fig/network.d nobuild/undo_manager.d
diffstat 4 files changed, 285 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/doodle/fig/diagram_elements.d	Thu Aug 26 16:14:53 2010 +0930
+++ b/doodle/fig/diagram_elements.d	Thu Aug 26 16:32:07 2010 +0930
@@ -1,7 +1,10 @@
 module doodle.fig.diagram_elements;
 
+public {
+    import doodle.tk.geometry;
+}
+
 private {
-    import doodle.tk.geometry;
     import doodle.tk.renderer;
 }
 
@@ -10,25 +13,26 @@
 }
 
 abstract class DiagramElement {
+    /*
     Rectangle bounds() const;
 
     void draw(in Rectangle damage, scope Renderer cr) const;
+    */
 
     private {
         //GraphElement _container;                // FIXME use an interface to the container
     }
 }
 
-/*
-   abstract class SemanticModelBridge {
-   };
+abstract class SemanticModelBridge {
+};
 
-   abstract class GraphElement : DiagramElement {
-// Link to model via bridge goes here
-private {
-SemanticModelBridge _modelBridge;
-GraphConnector[] _anchorages;
-}
+abstract class GraphElement : DiagramElement {
+    // Link to model via bridge goes here
+    private {
+        SemanticModelBridge _modelBridge;
+        GraphConnector[] _anchorages;
+    }
 }
 
 class GraphConnector {
@@ -38,37 +42,34 @@
 }
 
 final class GraphEdge : GraphElement {
-private {
-GraphConnector[2] _anchors;
+    private {
+        GraphConnector[2] _anchors;
+    }
 }
-}
- */
 
 abstract class LeafElement : DiagramElement {
 }
 
-/*
-   class TextElement : LeafElement {
-   }
- */
+class TextElement : LeafElement {
+}
 
 abstract class GraphicPrimitive : LeafElement {
 }
 
-/*
-   class PolylinePrimitive : GraphicPrimitive {
-   private {
-   Point[] _waypoints;
-   }
-   }
- */
+class PolylinePrimitive : GraphicPrimitive {
+    private {
+        Point[] _waypoints;
+    }
+}
 
 final class RectanglePrimitive : GraphicPrimitive {
+    /*
     override void draw(in Rectangle damage, scope Renderer drawable) const {
         drawable.drawRectangle(bounds, false);
     }
 
     override Rectangle bounds() const { return _bounds; }
+    */
 
     private {
         Rectangle _bounds;
--- a/doodle/fig/diagram_layer.d	Thu Aug 26 16:14:53 2010 +0930
+++ b/doodle/fig/diagram_layer.d	Thu Aug 26 16:32:07 2010 +0930
@@ -21,19 +21,23 @@
 
     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;
     }
 
     override void draw(in Rectangle screenDamage, scope Renderer screenRenderer,
                        in Rectangle modelDamage, scope Renderer modelRenderer,
                        in ScreenModel screenModel) const {
+        /*
         foreach (e; _elements) {
             if ((e.bounds & modelDamage).valid) {       // FIXME if (intersects(e.bounds, modelDamage))
                 e.draw(modelDamage, modelRenderer);
             }
         }
+        */
     }
 
     private {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/fig/network.d	Thu Aug 26 16:32:07 2010 +0930
@@ -0,0 +1,99 @@
+module doodle.fig.network;
+
+public {
+    import doodle.fig.diagram_elements;
+}
+
+enum EdgeEnd {
+    Source,
+    Target
+};
+
+interface INetworkObserver {
+    // Node changes
+
+    void nodeAdded(GraphNode node,
+                   GraphElement container);
+    void nodeChanged(GraphNode node);
+    void nodeRelocated(GraphNode node,
+                       GraphElement container);
+    void nodeRemoved(GraphNode node,
+                     GraphElement container);
+
+    // Edge changes
+
+    void edgeAdded(GraphEdge node,
+                   GraphConnector anchor1, GraphConnector anchor2);
+    void edgeChanged(GraphEdge edge);
+    void edgeRerouted();
+    void edgeRemoved();
+}
+
+interface INetwork {
+    void addObserver(INetworkObserver observer);
+    void removeObserver(INetworkObserver observer);
+
+    //
+    // Interrogation:
+    //
+
+    GraphNode[] getRootNodes();
+
+    // Inquire whether in principle a node of node_type
+    // can be added at the given point, possibly nested
+    // within the nest node. The nest can be null.
+    bool canAdd(string node_type,
+                Point point,           // necessary?
+                GraphNode nest);
+
+    bool canRelocate(GraphNode node);
+
+    bool canRemove(GraphNode node);
+
+    // Inquire whether in principle the source element can
+    // be connected to the target element using
+    // an edge of edge_type. This might return true even
+    // though the real operation would fail due to deeper checking.
+    bool canConnect(char[] edge_type,
+                    GraphElement sourceElement, Point sourcePoint,
+                    GraphElement targetElement, Point targetPoint);
+
+    // Inquire whether in principle a given end of an existing edge
+    // can be rerouted from old_element to new_element at new_point.
+    // old_element and new_element may be the same element.
+    bool canReroute(GraphEdge edge, EdgeEnd end,
+                    GraphElement oldElement,
+                    GraphElement newElement, Point newPoint);
+
+    bool canDisconnect(GraphEdge edge);
+
+    //
+    // Manipulation:
+    //
+
+    // Attempt to really add a node...
+    GraphNode add(char[] node_type, /* initial properties, */
+                  Point point,
+                  GraphNode nest);
+
+    void relocate(GraphNode node,
+                  GraphElement oldContainer,
+                  GraphElement newContainer, Point newPoint);
+
+    // Attempt to really remove a node
+    void remove(GraphNode node);
+
+    // Attempt to really connect the source element to the target element
+    // using an edge of the given type with the given initial properties.
+    GraphEdge connect(string edge_type, /* initial properties, */
+                      GraphElement sourceElement, Point sourcePoint,
+                      GraphElement targetElement, Point targetPoint);
+
+    // Attempt to really reroute..
+    void reroute(GraphEdge edge, EdgeEnd end,
+                 GraphElement oldElement,
+                 GraphElement newElement, Point newPoint);
+
+    // Attempt to really remove an edge...
+    void disconnect(GraphEdge edge);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nobuild/undo_manager.d	Thu Aug 26 16:32:07 2010 +0930
@@ -0,0 +1,156 @@
+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;
+    }
+}
+
+}