diff --git a/js/ui/mxgraph/src/js/view/mxCellStatePreview.js b/js/ui/mxgraph/src/js/view/mxCellStatePreview.js new file mode 100644 index 0000000..7b0924d --- /dev/null +++ b/js/ui/mxgraph/src/js/view/mxCellStatePreview.js @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * + * Class: mxCellStatePreview + * + * Implements a live preview for moving cells. + * + * Constructor: mxCellStatePreview + * + * Constructs a move preview for the given graph. + * + * Parameters: + * + * graph - Reference to the enclosing . + */ +function mxCellStatePreview(graph) +{ + this.deltas = new mxDictionary(); + this.graph = graph; +}; + +/** + * Variable: graph + * + * Reference to the enclosing . + */ +mxCellStatePreview.prototype.graph = null; + +/** + * Variable: deltas + * + * Reference to the enclosing . + */ +mxCellStatePreview.prototype.deltas = null; + +/** + * Variable: count + * + * Contains the number of entries in the map. + */ +mxCellStatePreview.prototype.count = 0; + +/** + * Function: isEmpty + * + * Returns true if this contains no entries. + */ +mxCellStatePreview.prototype.isEmpty = function() +{ + return this.count == 0; +}; + +/** + * Function: moveState + */ +mxCellStatePreview.prototype.moveState = function(state, dx, dy, add, includeEdges) +{ + add = (add != null) ? add : true; + includeEdges = (includeEdges != null) ? includeEdges : true; + + var delta = this.deltas.get(state.cell); + + if (delta == null) + { + // Note: Deltas stores the point and the state since the key is a string. + delta = {point: new mxPoint(dx, dy), state: state}; + this.deltas.put(state.cell, delta); + this.count++; + } + else if (add) + { + delta.point.x += dx; + delta.point.y += dy; + } + else + { + delta.point.x = dx; + delta.point.y = dy; + } + + if (includeEdges) + { + this.addEdges(state); + } + + return delta.point; +}; + +/** + * Function: show + */ +mxCellStatePreview.prototype.show = function(visitor) +{ + this.deltas.visit(mxUtils.bind(this, function(key, delta) + { + this.translateState(delta.state, delta.point.x, delta.point.y); + })); + + this.deltas.visit(mxUtils.bind(this, function(key, delta) + { + this.revalidateState(delta.state, delta.point.x, delta.point.y, visitor); + })); +}; + +/** + * Function: translateState + */ +mxCellStatePreview.prototype.translateState = function(state, dx, dy) +{ + if (state != null) + { + var model = this.graph.getModel(); + + if (model.isVertex(state.cell)) + { + state.view.updateCellState(state); + var geo = model.getGeometry(state.cell); + + // Moves selection cells and non-relative vertices in + // the first phase so that edge terminal points will + // be updated in the second phase + if ((dx != 0 || dy != 0) && geo != null && (!geo.relative || this.deltas.get(state.cell) != null)) + { + state.x += dx; + state.y += dy; + } + } + + var childCount = model.getChildCount(state.cell); + + for (var i = 0; i < childCount; i++) + { + this.translateState(state.view.getState(model.getChildAt(state.cell, i)), dx, dy); + } + } +}; + +/** + * Function: revalidateState + */ +mxCellStatePreview.prototype.revalidateState = function(state, dx, dy, visitor) +{ + if (state != null) + { + var model = this.graph.getModel(); + + // Updates the edge terminal points and restores the + // (relative) positions of any (relative) children + if (model.isEdge(state.cell)) + { + state.view.updateCellState(state); + } + + var geo = this.graph.getCellGeometry(state.cell); + var pState = state.view.getState(model.getParent(state.cell)); + + // Moves selection vertices which are relative + if ((dx != 0 || dy != 0) && geo != null && geo.relative && + model.isVertex(state.cell) && (pState == null || + model.isVertex(pState.cell) || this.deltas.get(state.cell) != null)) + { + state.x += dx; + state.y += dy; + } + + this.graph.cellRenderer.redraw(state); + + // Invokes the visitor on the given state + if (visitor != null) + { + visitor(state); + } + + var childCount = model.getChildCount(state.cell); + + for (var i = 0; i < childCount; i++) + { + this.revalidateState(this.graph.view.getState(model.getChildAt(state.cell, i)), dx, dy, visitor); + } + } +}; + +/** + * Function: addEdges + */ +mxCellStatePreview.prototype.addEdges = function(state) +{ + var model = this.graph.getModel(); + var edgeCount = model.getEdgeCount(state.cell); + + for (var i = 0; i < edgeCount; i++) + { + var s = state.view.getState(model.getEdgeAt(state.cell, i)); + + if (s != null) + { + this.moveState(s, 0, 0); + } + } +};