# HG changeset patch # User David Bryant # Date 1282806127 -34200 # Node ID 66210d8ea37a124949de4e9be7309f20c106fd5f # Parent 85589f7a3a280ef5d2d00c53174c23b590cb086c Added some junk diff -r 85589f7a3a28 -r 66210d8ea37a doodle/fig/diagram_elements.d --- 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; diff -r 85589f7a3a28 -r 66210d8ea37a doodle/fig/diagram_layer.d --- 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 { diff -r 85589f7a3a28 -r 66210d8ea37a doodle/fig/network.d --- /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); +} diff -r 85589f7a3a28 -r 66210d8ea37a nobuild/undo_manager.d --- /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; + } +} + +}