204 lines
4.2 KiB
JavaScript
204 lines
4.2 KiB
JavaScript
|
/**
|
||
|
* 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 <mxGraph>.
|
||
|
*/
|
||
|
function mxCellStatePreview(graph)
|
||
|
{
|
||
|
this.deltas = new mxDictionary();
|
||
|
this.graph = graph;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Variable: graph
|
||
|
*
|
||
|
* Reference to the enclosing <mxGraph>.
|
||
|
*/
|
||
|
mxCellStatePreview.prototype.graph = null;
|
||
|
|
||
|
/**
|
||
|
* Variable: deltas
|
||
|
*
|
||
|
* Reference to the enclosing <mxGraph>.
|
||
|
*/
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
};
|