mxgraph-map-fix
Version:
mxGraph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.
2,089 lines (1,766 loc) • 148 kB
JavaScript
/**
* Copyright (c) 2006-2012, JGraph Ltd
*/
Format = function(editorUi, container)
{
this.editorUi = editorUi;
this.container = container;
};
/**
* Returns information about the current selection.
*/
Format.prototype.labelIndex = 0;
/**
* Returns information about the current selection.
*/
Format.prototype.currentIndex = 0;
/**
* Returns information about the current selection.
*/
Format.prototype.showCloseButton = true;
/**
* Background color for inactive tabs.
*/
Format.prototype.inactiveTabBackgroundColor = '#d7d7d7';
/**
* Adds the label menu items to the given menu and parent.
*/
Format.prototype.init = function()
{
var ui = this.editorUi;
var editor = ui.editor;
var graph = editor.graph;
this.update = mxUtils.bind(this, function(sender, evt)
{
this.clearSelectionState();
this.refresh();
});
graph.getSelectionModel().addListener(mxEvent.CHANGE, this.update);
graph.addListener(mxEvent.EDITING_STARTED, this.update);
graph.addListener(mxEvent.EDITING_STOPPED, this.update);
graph.getModel().addListener(mxEvent.CHANGE, this.update);
graph.addListener(mxEvent.ROOT, mxUtils.bind(this, function()
{
this.refresh();
}));
this.refresh();
};
/**
* Returns information about the current selection.
*/
Format.prototype.clearSelectionState = function()
{
this.selectionState = null;
};
/**
* Returns information about the current selection.
*/
Format.prototype.getSelectionState = function()
{
if (this.selectionState == null)
{
this.selectionState = this.createSelectionState();
}
return this.selectionState;
};
/**
* Returns information about the current selection.
*/
Format.prototype.createSelectionState = function()
{
var cells = this.editorUi.editor.graph.getSelectionCells();
var result = this.initSelectionState();
for (var i = 0; i < cells.length; i++)
{
this.updateSelectionStateForCell(result, cells[i], cells);
}
return result;
};
/**
* Returns information about the current selection.
*/
Format.prototype.initSelectionState = function()
{
return {vertices: [], edges: [], x: null, y: null, width: null, height: null, style: {},
containsImage: false, containsLabel: false, fill: true, glass: true, rounded: true,
comic: true, autoSize: false, image: true, shadow: true, lineJumps: true};
};
/**
* Returns information about the current selection.
*/
Format.prototype.updateSelectionStateForCell = function(result, cell, cells)
{
var graph = this.editorUi.editor.graph;
if (graph.getModel().isVertex(cell))
{
result.vertices.push(cell);
var geo = graph.getCellGeometry(cell);
if (geo != null)
{
if (geo.width > 0)
{
if (result.width == null)
{
result.width = geo.width;
}
else if (result.width != geo.width)
{
result.width = '';
}
}
else
{
result.containsLabel = true;
}
if (geo.height > 0)
{
if (result.height == null)
{
result.height = geo.height;
}
else if (result.height != geo.height)
{
result.height = '';
}
}
else
{
result.containsLabel = true;
}
if (!geo.relative || geo.offset != null)
{
var x = (geo.relative) ? geo.offset.x : geo.x;
var y = (geo.relative) ? geo.offset.y : geo.y;
if (result.x == null)
{
result.x = x;
}
else if (result.x != x)
{
result.x = '';
}
if (result.y == null)
{
result.y = y;
}
else if (result.y != y)
{
result.y = '';
}
}
}
}
else if (graph.getModel().isEdge(cell))
{
result.edges.push(cell);
}
var state = graph.view.getState(cell);
if (state != null)
{
result.autoSize = result.autoSize || this.isAutoSizeState(state);
result.glass = result.glass && this.isGlassState(state);
result.rounded = result.rounded && this.isRoundedState(state);
result.lineJumps = result.lineJumps && this.isLineJumpState(state);
result.comic = result.comic && this.isComicState(state);
result.image = result.image && this.isImageState(state);
result.shadow = result.shadow && this.isShadowState(state);
result.fill = result.fill && this.isFillState(state);
var shape = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
result.containsImage = result.containsImage || shape == 'image';
for (var key in state.style)
{
var value = state.style[key];
if (value != null)
{
if (result.style[key] == null)
{
result.style[key] = value;
}
else if (result.style[key] != value)
{
result.style[key] = '';
}
}
}
}
};
/**
* Returns information about the current selection.
*/
Format.prototype.isFillState = function(state)
{
return state.view.graph.model.isVertex(state.cell) ||
mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null) == 'arrow' ||
mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null) == 'filledEdge' ||
mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null) == 'flexArrow';
};
/**
* Returns information about the current selection.
*/
Format.prototype.isGlassState = function(state)
{
var shape = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
return (shape == 'label' || shape == 'rectangle' || shape == 'internalStorage' ||
shape == 'ext' || shape == 'umlLifeline' || shape == 'swimlane' ||
shape == 'process');
};
/**
* Returns information about the current selection.
*/
Format.prototype.isRoundedState = function(state)
{
var shape = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
return (shape == 'label' || shape == 'rectangle' || shape == 'internalStorage' || shape == 'corner' ||
shape == 'parallelogram' || shape == 'swimlane' || shape == 'triangle' || shape == 'trapezoid' ||
shape == 'ext' || shape == 'step' || shape == 'tee' || shape == 'process' || shape == 'link' ||
shape == 'rhombus' || shape == 'offPageConnector' || shape == 'loopLimit' || shape == 'hexagon' ||
shape == 'manualInput' || shape == 'curlyBracket' || shape == 'singleArrow' || shape == 'callout' ||
shape == 'doubleArrow' || shape == 'flexArrow' || shape == 'card' || shape == 'umlLifeline');
};
/**
* Returns information about the current selection.
*/
Format.prototype.isLineJumpState = function(state)
{
var shape = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
return shape == 'connector' || shape == 'filledEdge';
};
/**
* Returns information about the current selection.
*/
Format.prototype.isComicState = function(state)
{
var shape = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
return mxUtils.indexOf(['label', 'rectangle', 'internalStorage', 'corner', 'parallelogram', 'note', 'collate',
'swimlane', 'triangle', 'trapezoid', 'ext', 'step', 'tee', 'process', 'link', 'rhombus',
'offPageConnector', 'loopLimit', 'hexagon', 'manualInput', 'singleArrow', 'doubleArrow',
'flexArrow', 'filledEdge', 'card', 'umlLifeline', 'connector', 'folder', 'component', 'sortShape',
'cross', 'umlFrame', 'cube', 'isoCube', 'isoRectangle', 'partialRectangle'], shape) >= 0;
};
/**
* Returns information about the current selection.
*/
Format.prototype.isAutoSizeState = function(state)
{
return mxUtils.getValue(state.style, mxConstants.STYLE_AUTOSIZE, null) == '1';
};
/**
* Returns information about the current selection.
*/
Format.prototype.isImageState = function(state)
{
var shape = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
return (shape == 'label' || shape == 'image');
};
/**
* Returns information about the current selection.
*/
Format.prototype.isShadowState = function(state)
{
var shape = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
return (shape != 'image');
};
/**
* Adds the label menu items to the given menu and parent.
*/
Format.prototype.clear = function()
{
this.container.innerHTML = '';
// Destroy existing panels
if (this.panels != null)
{
for (var i = 0; i < this.panels.length; i++)
{
this.panels[i].destroy();
}
}
this.panels = [];
};
/**
* Adds the label menu items to the given menu and parent.
*/
Format.prototype.refresh = function()
{
// Performance tweak: No refresh needed if not visible
if (this.container.style.width == '0px')
{
return;
}
this.clear();
var ui = this.editorUi;
var graph = ui.editor.graph;
var div = document.createElement('div');
div.style.whiteSpace = 'nowrap';
div.style.color = 'rgb(112, 112, 112)';
div.style.textAlign = 'left';
div.style.cursor = 'default';
var label = document.createElement('div');
label.style.border = '1px solid #c0c0c0';
label.style.borderWidth = '0px 0px 1px 0px';
label.style.textAlign = 'center';
label.style.fontWeight = 'bold';
label.style.overflow = 'hidden';
label.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
label.style.paddingTop = '8px';
label.style.height = (mxClient.IS_QUIRKS) ? '34px' : '25px';
label.style.width = '100%';
this.container.appendChild(div);
if (graph.isSelectionEmpty())
{
mxUtils.write(label, mxResources.get('diagram'));
// Adds button to hide the format panel since
// people don't seem to find the toolbar button
// and the menu item in the format menu
if (this.showCloseButton)
{
var img = document.createElement('img');
img.setAttribute('border', '0');
img.setAttribute('src', Dialog.prototype.closeImage);
img.setAttribute('title', mxResources.get('hide'));
img.style.position = 'absolute';
img.style.display = 'block';
img.style.right = '0px';
img.style.top = '8px';
img.style.cursor = 'pointer';
img.style.marginTop = '1px';
img.style.marginRight = '17px';
img.style.border = '1px solid transparent';
img.style.padding = '1px';
img.style.opacity = 0.5;
label.appendChild(img)
mxEvent.addListener(img, 'click', function()
{
ui.actions.get('formatPanel').funct();
});
}
div.appendChild(label);
this.panels.push(new DiagramFormatPanel(this, ui, div));
}
else if (graph.isEditing())
{
mxUtils.write(label, mxResources.get('text'));
div.appendChild(label);
this.panels.push(new TextFormatPanel(this, ui, div));
}
else
{
var containsLabel = this.getSelectionState().containsLabel;
var currentLabel = null;
var currentPanel = null;
var addClickHandler = mxUtils.bind(this, function(elt, panel, index)
{
var clickHandler = mxUtils.bind(this, function(evt)
{
if (currentLabel != elt)
{
if (containsLabel)
{
this.labelIndex = index;
}
else
{
this.currentIndex = index;
}
if (currentLabel != null)
{
currentLabel.style.backgroundColor = this.inactiveTabBackgroundColor;
currentLabel.style.borderBottomWidth = '1px';
}
currentLabel = elt;
currentLabel.style.backgroundColor = '';
currentLabel.style.borderBottomWidth = '0px';
if (currentPanel != panel)
{
if (currentPanel != null)
{
currentPanel.style.display = 'none';
}
currentPanel = panel;
currentPanel.style.display = '';
}
}
});
mxEvent.addListener(elt, 'click', clickHandler);
if (index == ((containsLabel) ? this.labelIndex : this.currentIndex))
{
// Invokes handler directly as a workaround for no click on DIV in KHTML.
clickHandler();
}
});
var idx = 0;
label.style.backgroundColor = this.inactiveTabBackgroundColor;
label.style.borderLeftWidth = '1px';
label.style.width = (containsLabel) ? '50%' : '33.3%';
label.style.width = (containsLabel) ? '50%' : '33.3%';
var label2 = label.cloneNode(false);
var label3 = label2.cloneNode(false);
// Workaround for ignored background in IE
label2.style.backgroundColor = this.inactiveTabBackgroundColor;
label3.style.backgroundColor = this.inactiveTabBackgroundColor;
// Style
if (containsLabel)
{
label2.style.borderLeftWidth = '0px';
}
else
{
label.style.borderLeftWidth = '0px';
mxUtils.write(label, mxResources.get('style'));
div.appendChild(label);
var stylePanel = div.cloneNode(false);
stylePanel.style.display = 'none';
this.panels.push(new StyleFormatPanel(this, ui, stylePanel));
this.container.appendChild(stylePanel);
addClickHandler(label, stylePanel, idx++);
}
// Text
mxUtils.write(label2, mxResources.get('text'));
div.appendChild(label2);
var textPanel = div.cloneNode(false);
textPanel.style.display = 'none';
this.panels.push(new TextFormatPanel(this, ui, textPanel));
this.container.appendChild(textPanel);
// Arrange
mxUtils.write(label3, mxResources.get('arrange'));
div.appendChild(label3);
var arrangePanel = div.cloneNode(false);
arrangePanel.style.display = 'none';
this.panels.push(new ArrangePanel(this, ui, arrangePanel));
this.container.appendChild(arrangePanel);
addClickHandler(label2, textPanel, idx++);
addClickHandler(label3, arrangePanel, idx++);
}
};
/**
* Base class for format panels.
*/
BaseFormatPanel = function(format, editorUi, container)
{
this.format = format;
this.editorUi = editorUi;
this.container = container;
this.listeners = [];
};
/**
* Adds the given color option.
*/
BaseFormatPanel.prototype.getSelectionState = function()
{
var graph = this.editorUi.editor.graph;
var cells = graph.getSelectionCells();
var shape = null;
for (var i = 0; i < cells.length; i++)
{
var state = graph.view.getState(cells[i]);
if (state != null)
{
var tmp = mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE, null);
if (tmp != null)
{
if (shape == null)
{
shape = tmp;
}
else if (shape != tmp)
{
return null;
}
}
}
}
return shape;
};
/**
* Install input handler.
*/
BaseFormatPanel.prototype.installInputHandler = function(input, key, defaultValue, min, max, unit, textEditFallback, isFloat)
{
unit = (unit != null) ? unit : '';
isFloat = (isFloat != null) ? isFloat : false;
var ui = this.editorUi;
var graph = ui.editor.graph;
min = (min != null) ? min : 1;
max = (max != null) ? max : 999;
var selState = null;
var updating = false;
var update = mxUtils.bind(this, function(evt)
{
var value = (isFloat) ? parseFloat(input.value) : parseInt(input.value);
// Special case: angle mod 360
if (!isNaN(value) && key == mxConstants.STYLE_ROTATION)
{
// Workaround for decimal rounding errors in floats is to
// use integer and round all numbers to two decimal point
value = mxUtils.mod(Math.round(value * 100), 36000) / 100;
}
value = Math.min(max, Math.max(min, (isNaN(value)) ? defaultValue : value));
if (graph.cellEditor.isContentEditing() && textEditFallback)
{
if (!updating)
{
updating = true;
if (selState != null)
{
graph.cellEditor.restoreSelection(selState);
selState = null;
}
textEditFallback(value);
input.value = value + unit;
// Restore focus and selection in input
updating = false;
}
}
else if (value != mxUtils.getValue(this.format.getSelectionState().style, key, defaultValue))
{
if (graph.isEditing())
{
graph.stopEditing(true);
}
graph.getModel().beginUpdate();
try
{
graph.setCellStyles(key, value, graph.getSelectionCells());
// Handles special case for fontSize where HTML labels are parsed and updated
if (key == mxConstants.STYLE_FONTSIZE)
{
var cells = graph.getSelectionCells();
for (var i = 0; i < cells.length; i++)
{
var cell = cells[i];
// Changes font tags inside HTML labels
if (graph.isHtmlLabel(cell))
{
var div = document.createElement('div');
div.innerHTML = graph.convertValueToString(cell);
var elts = div.getElementsByTagName('font');
for (var j = 0; j < elts.length; j++)
{
elts[j].removeAttribute('size');
elts[j].style.fontSize = value + 'px';
}
graph.cellLabelChanged(cell, div.innerHTML)
}
}
}
}
finally
{
graph.getModel().endUpdate();
}
ui.fireEvent(new mxEventObject('styleChanged', 'keys', [key],
'values', [value], 'cells', graph.getSelectionCells()));
}
input.value = value + unit;
mxEvent.consume(evt);
});
if (textEditFallback && graph.cellEditor.isContentEditing())
{
// KNOWN: Arrow up/down clear selection text in quirks/IE 8
// Text size via arrow button limits to 16 in IE11. Why?
mxEvent.addListener(input, 'mousedown', function()
{
selState = graph.cellEditor.saveSelection();
});
mxEvent.addListener(input, 'touchstart', function()
{
selState = graph.cellEditor.saveSelection();
});
}
mxEvent.addListener(input, 'change', update);
mxEvent.addListener(input, 'blur', update);
return update;
};
/**
* Adds the given option.
*/
BaseFormatPanel.prototype.createPanel = function()
{
var div = document.createElement('div');
div.style.padding = '12px 0px 12px 18px';
div.style.borderBottom = '1px solid #c0c0c0';
return div;
};
/**
* Adds the given option.
*/
BaseFormatPanel.prototype.createTitle = function(title)
{
var div = document.createElement('div');
div.style.padding = '0px 0px 6px 0px';
div.style.whiteSpace = 'nowrap';
div.style.overflow = 'hidden';
div.style.width = '200px';
div.style.fontWeight = 'bold';
mxUtils.write(div, title);
return div;
};
/**
*
*/
BaseFormatPanel.prototype.createStepper = function(input, update, step, height, disableFocus, defaultValue)
{
step = (step != null) ? step : 1;
height = (height != null) ? height : 8;
if (mxClient.IS_QUIRKS)
{
height = height - 2;
}
else if (mxClient.IS_MT || document.documentMode >= 8)
{
height = height + 1;
}
var stepper = document.createElement('div');
mxUtils.setPrefixedStyle(stepper.style, 'borderRadius', '3px');
stepper.style.border = '1px solid rgb(192, 192, 192)';
stepper.style.position = 'absolute';
var up = document.createElement('div');
up.style.borderBottom = '1px solid rgb(192, 192, 192)';
up.style.position = 'relative';
up.style.height = height + 'px';
up.style.width = '10px';
up.className = 'geBtnUp';
stepper.appendChild(up);
var down = up.cloneNode(false);
down.style.border = 'none';
down.style.height = height + 'px';
down.className = 'geBtnDown';
stepper.appendChild(down);
mxEvent.addListener(down, 'click', function(evt)
{
if (input.value == '')
{
input.value = defaultValue || '2';
}
var val = parseInt(input.value);
if (!isNaN(val))
{
input.value = val - step;
if (update != null)
{
update(evt);
}
}
mxEvent.consume(evt);
});
mxEvent.addListener(up, 'click', function(evt)
{
if (input.value == '')
{
input.value = defaultValue || '0';
}
var val = parseInt(input.value);
if (!isNaN(val))
{
input.value = val + step;
if (update != null)
{
update(evt);
}
}
mxEvent.consume(evt);
});
// Disables transfer of focus to DIV but also :active CSS
// so it's only used for fontSize where the focus should
// stay on the selected text, but not for any other input.
if (disableFocus)
{
var currentSelection = null;
mxEvent.addGestureListeners(stepper,
function(evt)
{
// Workaround for lost current selection in page because of focus in IE
if (mxClient.IS_QUIRKS || document.documentMode == 8)
{
currentSelection = document.selection.createRange();
}
mxEvent.consume(evt);
},
null,
function(evt)
{
// Workaround for lost current selection in page because of focus in IE
if (currentSelection != null)
{
try
{
currentSelection.select();
}
catch (e)
{
// ignore
}
currentSelection = null;
mxEvent.consume(evt);
}
}
);
}
return stepper;
};
/**
* Adds the given option.
*/
BaseFormatPanel.prototype.createOption = function(label, isCheckedFn, setCheckedFn, listener)
{
var div = document.createElement('div');
div.style.padding = '6px 0px 1px 0px';
div.style.whiteSpace = 'nowrap';
div.style.overflow = 'hidden';
div.style.width = '200px';
div.style.height = (mxClient.IS_QUIRKS) ? '27px' : '18px';
var cb = document.createElement('input');
cb.setAttribute('type', 'checkbox');
cb.style.margin = '0px 6px 0px 0px';
div.appendChild(cb);
var span = document.createElement('span');
mxUtils.write(span, label);
div.appendChild(span);
var applying = false;
var value = isCheckedFn();
var apply = function(newValue)
{
if (!applying)
{
applying = true;
if (newValue)
{
cb.setAttribute('checked', 'checked');
cb.defaultChecked = true;
cb.checked = true;
}
else
{
cb.removeAttribute('checked');
cb.defaultChecked = false;
cb.checked = false;
}
if (value != newValue)
{
value = newValue;
// Checks if the color value needs to be updated in the model
if (isCheckedFn() != value)
{
setCheckedFn(value);
}
}
applying = false;
}
};
mxEvent.addListener(div, 'click', function(evt)
{
// Toggles checkbox state for click on label
var source = mxEvent.getSource(evt);
if (source == div || source == span)
{
cb.checked = !cb.checked;
}
apply(cb.checked);
});
apply(value);
if (listener != null)
{
listener.install(apply);
this.listeners.push(listener);
}
return div;
};
/**
* The string 'null' means use null in values.
*/
BaseFormatPanel.prototype.createCellOption = function(label, key, defaultValue, enabledValue, disabledValue, fn, action, stopEditing)
{
enabledValue = (enabledValue != null) ? ((enabledValue == 'null') ? null : enabledValue) : '1';
disabledValue = (disabledValue != null) ? ((disabledValue == 'null') ? null : disabledValue) : '0';
var ui = this.editorUi;
var editor = ui.editor;
var graph = editor.graph;
return this.createOption(label, function()
{
// Seems to be null sometimes, not sure why...
var state = graph.view.getState(graph.getSelectionCell());
if (state != null)
{
return mxUtils.getValue(state.style, key, defaultValue) != disabledValue;
}
return null;
}, function(checked)
{
if (stopEditing)
{
graph.stopEditing();
}
if (action != null)
{
action.funct();
}
else
{
graph.getModel().beginUpdate();
try
{
var value = (checked) ? enabledValue : disabledValue;
graph.setCellStyles(key, value, graph.getSelectionCells());
if (fn != null)
{
fn(graph.getSelectionCells(), value);
}
ui.fireEvent(new mxEventObject('styleChanged', 'keys', [key],
'values', [value], 'cells', graph.getSelectionCells()));
}
finally
{
graph.getModel().endUpdate();
}
}
},
{
install: function(apply)
{
this.listener = function()
{
// Seems to be null sometimes, not sure why...
var state = graph.view.getState(graph.getSelectionCell());
if (state != null)
{
apply(mxUtils.getValue(state.style, key, defaultValue) != disabledValue);
}
};
graph.getModel().addListener(mxEvent.CHANGE, this.listener);
},
destroy: function()
{
graph.getModel().removeListener(this.listener);
}
});
};
/**
* Adds the given color option.
*/
BaseFormatPanel.prototype.createColorOption = function(label, getColorFn, setColorFn, defaultColor, listener, callbackFn, hideCheckbox)
{
var div = document.createElement('div');
div.style.padding = '6px 0px 1px 0px';
div.style.whiteSpace = 'nowrap';
div.style.overflow = 'hidden';
div.style.width = '200px';
div.style.height = (mxClient.IS_QUIRKS) ? '27px' : '18px';
var cb = document.createElement('input');
cb.setAttribute('type', 'checkbox');
cb.style.margin = '0px 6px 0px 0px';
if (!hideCheckbox)
{
div.appendChild(cb);
}
var span = document.createElement('span');
mxUtils.write(span, label);
div.appendChild(span);
var applying = false;
var value = getColorFn();
var btn = null;
var apply = function(color, disableUpdate)
{
if (!applying)
{
applying = true;
btn.innerHTML = '<div style="width:' + ((mxClient.IS_QUIRKS) ? '30' : '36') +
'px;height:12px;margin:3px;border:1px solid black;background-color:' +
((color != null && color != mxConstants.NONE) ? color : defaultColor) + ';"></div>';
// Fine-tuning in Firefox, quirks mode and IE8 standards
if (mxClient.IS_QUIRKS || document.documentMode == 8)
{
btn.firstChild.style.margin = '0px';
}
if (color != null && color != mxConstants.NONE)
{
cb.setAttribute('checked', 'checked');
cb.defaultChecked = true;
cb.checked = true;
}
else
{
cb.removeAttribute('checked');
cb.defaultChecked = false;
cb.checked = false;
}
btn.style.display = (cb.checked || hideCheckbox) ? '' : 'none';
if (callbackFn != null)
{
callbackFn(color);
}
if (!disableUpdate && (hideCheckbox || value != color))
{
value = color;
// Checks if the color value needs to be updated in the model
if (hideCheckbox || getColorFn() != value)
{
setColorFn(value);
}
}
applying = false;
}
};
btn = mxUtils.button('', mxUtils.bind(this, function(evt)
{
this.editorUi.pickColor(value, apply);
mxEvent.consume(evt);
}));
btn.style.position = 'absolute';
btn.style.marginTop = '-4px';
btn.style.right = (mxClient.IS_QUIRKS) ? '0px' : '20px';
btn.style.height = '22px';
btn.className = 'geColorBtn';
btn.style.display = (cb.checked || hideCheckbox) ? '' : 'none';
div.appendChild(btn);
mxEvent.addListener(div, 'click', function(evt)
{
var source = mxEvent.getSource(evt);
if (source == cb || source.nodeName != 'INPUT')
{
// Toggles checkbox state for click on label
if (source != cb)
{
cb.checked = !cb.checked;
}
// Overrides default value with current value to make it easier
// to restore previous value if the checkbox is clicked twice
if (!cb.checked && value != null && value != mxConstants.NONE &&
defaultColor != mxConstants.NONE)
{
defaultColor = value;
}
apply((cb.checked) ? defaultColor : mxConstants.NONE);
}
});
apply(value, true);
if (listener != null)
{
listener.install(apply);
this.listeners.push(listener);
}
return div;
};
/**
*
*/
BaseFormatPanel.prototype.createCellColorOption = function(label, colorKey, defaultColor, callbackFn, setStyleFn)
{
var ui = this.editorUi;
var editor = ui.editor;
var graph = editor.graph;
return this.createColorOption(label, function()
{
// Seems to be null sometimes, not sure why...
var state = graph.view.getState(graph.getSelectionCell());
if (state != null)
{
return mxUtils.getValue(state.style, colorKey, null);
}
return null;
}, function(color)
{
graph.getModel().beginUpdate();
try
{
if (setStyleFn != null)
{
setStyleFn(color);
}
graph.setCellStyles(colorKey, color, graph.getSelectionCells());
ui.fireEvent(new mxEventObject('styleChanged', 'keys', [colorKey],
'values', [color], 'cells', graph.getSelectionCells()));
}
finally
{
graph.getModel().endUpdate();
}
}, defaultColor || mxConstants.NONE,
{
install: function(apply)
{
this.listener = function()
{
// Seems to be null sometimes, not sure why...
var state = graph.view.getState(graph.getSelectionCell());
if (state != null)
{
apply(mxUtils.getValue(state.style, colorKey, null));
}
};
graph.getModel().addListener(mxEvent.CHANGE, this.listener);
},
destroy: function()
{
graph.getModel().removeListener(this.listener);
}
}, callbackFn);
};
/**
*
*/
BaseFormatPanel.prototype.addArrow = function(elt, height)
{
height = (height != null) ? height : 10;
var arrow = document.createElement('div');
arrow.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
arrow.style.padding = '6px';
arrow.style.paddingRight = '4px';
var m = (10 - height);
if (m == 2)
{
arrow.style.paddingTop = 6 + 'px';
}
else if (m > 0)
{
arrow.style.paddingTop = (6 - m) + 'px';
}
else
{
arrow.style.marginTop = '-2px';
}
arrow.style.height = height + 'px';
arrow.style.borderLeft = '1px solid #a0a0a0';
arrow.innerHTML = '<img border="0" src="' + ((mxClient.IS_SVG) ? 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHBJREFUeNpidHB2ZyAGsACxDRBPIKCuA6TwCBB/h2rABu4A8SYmKCcXiP/iUFgAxL9gCi8A8SwsirZCMQMTkmANEH9E4v+CmsaArvAdyNFI/FlQ92EoBIE+qCRIUz168DBgsU4OqhinQpgHMABAgAEALY4XLIsJ20oAAAAASUVORK5CYII=' :
IMAGE_PATH + '/dropdown.png') + '" style="margin-bottom:4px;">';
mxUtils.setOpacity(arrow, 70);
var symbol = elt.getElementsByTagName('div')[0];
if (symbol != null)
{
symbol.style.paddingRight = '6px';
symbol.style.marginLeft = '4px';
symbol.style.marginTop = '-1px';
symbol.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
mxUtils.setOpacity(symbol, 60);
}
mxUtils.setOpacity(elt, 100);
elt.style.border = '1px solid #a0a0a0';
elt.style.backgroundColor = 'white';
elt.style.backgroundImage = 'none';
elt.style.width = 'auto';
elt.className += ' geColorBtn';
mxUtils.setPrefixedStyle(elt.style, 'borderRadius', '3px');
elt.appendChild(arrow);
return symbol;
};
/**
*
*/
BaseFormatPanel.prototype.addUnitInput = function(container, unit, right, width, update, step, marginTop, disableFocus)
{
marginTop = (marginTop != null) ? marginTop : 0;
var input = document.createElement('input');
input.style.position = 'absolute';
input.style.textAlign = 'right';
input.style.marginTop = '-2px';
input.style.right = (right + 12) + 'px';
input.style.width = width + 'px';
container.appendChild(input);
var stepper = this.createStepper(input, update, step, null, disableFocus);
stepper.style.marginTop = (marginTop - 2) + 'px';
stepper.style.right = right + 'px';
container.appendChild(stepper);
return input;
};
/**
*
*/
BaseFormatPanel.prototype.createRelativeOption = function(label, key, width, handler, init)
{
width = (width != null) ? width : 44;
var graph = this.editorUi.editor.graph;
var div = this.createPanel();
div.style.paddingTop = '10px';
div.style.paddingBottom = '10px';
mxUtils.write(div, label);
div.style.fontWeight = 'bold';
function update(evt)
{
if (handler != null)
{
handler(input);
}
else
{
var value = parseInt(input.value);
value = Math.min(100, Math.max(0, (isNaN(value)) ? 100 : value));
var state = graph.view.getState(graph.getSelectionCell());
if (state != null && value != mxUtils.getValue(state.style, key, 100))
{
// Removes entry in style (assumes 100 is default for relative values)
if (value == 100)
{
value = null;
}
graph.setCellStyles(key, value, graph.getSelectionCells());
}
input.value = ((value != null) ? value : '100') + ' %';
}
mxEvent.consume(evt);
};
var input = this.addUnitInput(div, '%', 20, width, update, 10, -15, handler != null);
if (key != null)
{
var listener = mxUtils.bind(this, function(sender, evt, force)
{
if (force || input != document.activeElement)
{
var ss = this.format.getSelectionState();
var tmp = parseInt(mxUtils.getValue(ss.style, key, 100));
input.value = (isNaN(tmp)) ? '' : tmp + ' %';
}
});
mxEvent.addListener(input, 'keydown', function(e)
{
if (e.keyCode == 13)
{
graph.container.focus();
mxEvent.consume(e);
}
else if (e.keyCode == 27)
{
listener(null, null, true);
graph.container.focus();
mxEvent.consume(e);
}
});
graph.getModel().addListener(mxEvent.CHANGE, listener);
this.listeners.push({destroy: function() { graph.getModel().removeListener(listener); }});
listener();
}
mxEvent.addListener(input, 'blur', update);
mxEvent.addListener(input, 'change', update);
if (init != null)
{
init(input);
}
return div;
};
/**
*
*/
BaseFormatPanel.prototype.addLabel = function(div, title, right, width)
{
width = (width != null) ? width : 61;
var label = document.createElement('div');
mxUtils.write(label, title);
label.style.position = 'absolute';
label.style.right = right + 'px';
label.style.width = width + 'px';
label.style.marginTop = '6px';
label.style.textAlign = 'center';
div.appendChild(label);
};
/**
*
*/
BaseFormatPanel.prototype.addKeyHandler = function(input, listener)
{
mxEvent.addListener(input, 'keydown', mxUtils.bind(this, function(e)
{
if (e.keyCode == 13)
{
this.editorUi.editor.graph.container.focus();
mxEvent.consume(e);
}
else if (e.keyCode == 27)
{
if (listener != null)
{
listener(null, null, true);
}
this.editorUi.editor.graph.container.focus();
mxEvent.consume(e);
}
}));
};
/**
*
*/
BaseFormatPanel.prototype.styleButtons = function(elts)
{
for (var i = 0; i < elts.length; i++)
{
mxUtils.setPrefixedStyle(elts[i].style, 'borderRadius', '3px');
mxUtils.setOpacity(elts[i], 100);
elts[i].style.border = '1px solid #a0a0a0';
elts[i].style.padding = '4px';
elts[i].style.paddingTop = '3px';
elts[i].style.paddingRight = '1px';
elts[i].style.margin = '1px';
elts[i].style.width = '24px';
elts[i].style.height = '20px';
elts[i].className += ' geColorBtn';
}
};
/**
* Adds the label menu items to the given menu and parent.
*/
BaseFormatPanel.prototype.destroy = function()
{
if (this.listeners != null)
{
for (var i = 0; i < this.listeners.length; i++)
{
this.listeners[i].destroy();
}
this.listeners = null;
}
};
/**
* Adds the label menu items to the given menu and parent.
*/
ArrangePanel = function(format, editorUi, container)
{
BaseFormatPanel.call(this, format, editorUi, container);
this.init();
};
mxUtils.extend(ArrangePanel, BaseFormatPanel);
/**
* Adds the label menu items to the given menu and parent.
*/
ArrangePanel.prototype.init = function()
{
var graph = this.editorUi.editor.graph;
var ss = this.format.getSelectionState();
this.container.appendChild(this.addLayerOps(this.createPanel()));
// Special case that adds two panels
this.addGeometry(this.container);
this.addEdgeGeometry(this.container);
if (!ss.containsLabel || ss.edges.length == 0)
{
this.container.appendChild(this.addAngle(this.createPanel()));
}
if (!ss.containsLabel && ss.edges.length == 0)
{
this.container.appendChild(this.addFlip(this.createPanel()));
}
if (ss.vertices.length > 1)
{
this.container.appendChild(this.addAlign(this.createPanel()));
this.container.appendChild(this.addDistribute(this.createPanel()));
}
this.container.appendChild(this.addGroupOps(this.createPanel()));
};
/**
*
*/
ArrangePanel.prototype.addLayerOps = function(div)
{
var ui = this.editorUi;
var btn = mxUtils.button(mxResources.get('toFront'), function(evt)
{
ui.actions.get('toFront').funct();
})
btn.setAttribute('title', mxResources.get('toFront') + ' (' + this.editorUi.actions.get('toFront').shortcut + ')');
btn.style.width = '100px';
btn.style.marginRight = '2px';
div.appendChild(btn);
var btn = mxUtils.button(mxResources.get('toBack'), function(evt)
{
ui.actions.get('toBack').funct();
})
btn.setAttribute('title', mxResources.get('toBack') + ' (' + this.editorUi.actions.get('toBack').shortcut + ')');
btn.style.width = '100px';
div.appendChild(btn);
return div;
};
/**
*
*/
ArrangePanel.prototype.addGroupOps = function(div)
{
var ui = this.editorUi;
var graph = ui.editor.graph;
var cell = graph.getSelectionCell();
var ss = this.format.getSelectionState();
var count = 0;
var btn = null;
div.style.paddingTop = '8px';
div.style.paddingBottom = '6px';
if (graph.getSelectionCount() > 1)
{
btn = mxUtils.button(mxResources.get('group'), function(evt)
{
ui.actions.get('group').funct();
})
btn.setAttribute('title', mxResources.get('group') + ' (' + this.editorUi.actions.get('group').shortcut + ')');
btn.style.width = '202px';
btn.style.marginBottom = '2px';
div.appendChild(btn);
count++;
}
else if (graph.getSelectionCount() == 1 && !graph.getModel().isEdge(cell) && !graph.isSwimlane(cell) &&
graph.getModel().getChildCount(cell) > 0)
{
btn = mxUtils.button(mxResources.get('ungroup'), function(evt)
{
ui.actions.get('ungroup').funct();
})
btn.setAttribute('title', mxResources.get('ungroup') + ' (' + this.editorUi.actions.get('ungroup').shortcut + ')');
btn.style.width = '202px';
btn.style.marginBottom = '2px';
div.appendChild(btn);
count++;
}
if (graph.getSelectionCount() == 1 && graph.getModel().isVertex(cell) &&
graph.getModel().isVertex(graph.getModel().getParent(cell)))
{
if (count > 0)
{
mxUtils.br(div);
}
btn = mxUtils.button(mxResources.get('removeFromGroup'), function(evt)
{
ui.actions.get('removeFromGroup').funct();
})
btn.setAttribute('title', mxResources.get('removeFromGroup'));
btn.style.width = '202px';
btn.style.marginBottom = '2px';
div.appendChild(btn);
count++;
}
else if (graph.getSelectionCount() > 0)
{
if (count > 0)
{
mxUtils.br(div);
}
btn = mxUtils.button(mxResources.get('clearWaypoints'), mxUtils.bind(this, function(evt)
{
this.editorUi.actions.get('clearWaypoints').funct();
}));
btn.setAttribute('title', mxResources.get('clearWaypoints') + ' (' + this.editorUi.actions.get('clearWaypoints').shortcut + ')');
btn.style.width = '202px';
btn.style.marginBottom = '2px';
div.appendChild(btn);
count++;
}
if (graph.getSelectionCount() == 1)
{
if (count > 0)
{
mxUtils.br(div);
}
btn = mxUtils.button(mxResources.get('editData'), mxUtils.bind(this, function(evt)
{
this.editorUi.actions.get('editData').funct();
}));
btn.setAttribute('title', mxResources.get('editData') + ' (' + this.editorUi.actions.get('editData').shortcut + ')');
btn.style.width = '100px';
btn.style.marginBottom = '2px';
div.appendChild(btn);
count++;
btn = mxUtils.button(mxResources.get('editLink'), mxUtils.bind(this, function(evt)
{
this.editorUi.actions.get('editLink').funct();
}));
btn.setAttribute('title', mxResources.get('editLink'));
btn.style.width = '100px';
btn.style.marginLeft = '2px';
btn.style.marginBottom = '2px';
div.appendChild(btn);
count++;
}
if (count == 0)
{
div.style.display = 'none';
}
return div;
};
/**
*
*/
ArrangePanel.prototype.addAlign = function(div)
{
var graph = this.editorUi.editor.graph;
div.style.paddingTop = '6px';
div.style.paddingBottom = '12px';
div.appendChild(this.createTitle(mxResources.get('align')));
var stylePanel = document.createElement('div');
stylePanel.style.position = 'relative';
stylePanel.style.paddingLeft = '0px';
stylePanel.style.borderWidth = '0px';
stylePanel.className = 'geToolbarContainer';
if (mxClient.IS_QUIRKS)
{
div.style.height = '60px';
}
var left = this.editorUi.toolbar.addButton('geSprite-alignleft', mxResources.get('left'),
function() { graph.alignCells(mxConstants.ALIGN_LEFT); }, stylePanel);
var center = this.editorUi.toolbar.addButton('geSprite-aligncenter', mxResources.get('center'),
function() { graph.alignCells(mxConstants.ALIGN_CENTER); }, stylePanel);
var right = this.editorUi.toolbar.addButton('geSprite-alignright', mxResources.get('right'),
function() { graph.alignCells(mxConstants.ALIGN_RIGHT); }, stylePanel);
var top = this.editorUi.toolbar.addButton('geSprite-aligntop', mxResources.get('top'),
function() { graph.alignCells(mxConstants.ALIGN_TOP); }, stylePanel);
var middle = this.editorUi.toolbar.addButton('geSprite-alignmiddle', mxResources.get('middle'),
function() { graph.alignCells(mxConstants.ALIGN_MIDDLE); }, stylePanel);
var bottom = this.editorUi.toolbar.addButton('geSprite-alignbottom', mxResources.get('bottom'),
function() { graph.alignCells(mxConstants.ALIGN_BOTTOM); }, stylePanel);
this.styleButtons([left, center, right, top, middle, bottom]);
right.style.marginRight = '6px';
div.appendChild(stylePanel);
return div;
};
/**
*
*/
ArrangePanel.prototype.addFlip = function(div)
{
var ui = this.editorUi;
var editor = ui.editor;
var graph = editor.graph;
div.style.paddingTop = '6px';
div.style.paddingBottom = '10px';
var span = document.createElement('div');
span.style.marginTop = '2px';
span.style.marginBottom = '8px';
span.style.fontWeight = 'bold';
mxUtils.write(span, mxResources.get('flip'));
div.appendChild(span);
var btn = mxUtils.button(mxResources.get('horizontal'), function(evt)
{
graph.toggleCellStyles(mxConstants.STYLE_FLIPH, false);
})
btn.setAttribute('title', mxResources.get('horizontal'));
btn.style.width = '100px';
btn.style.marginRight = '2px';
div.appendChild(btn);
var btn = mxUtils.button(mxResources.get('vertical'), function(evt)
{
graph.toggleCellStyles(mxConstants.STYLE_FLIPV, false);
})
btn.setAttribute('title', mxResources.get('vertical'));
btn.style.width = '100px';
div.appendChild(btn);
return div;
};
/**
*
*/
ArrangePanel.prototype.addDistribute = function(div)
{
var ui = this.editorUi;
var editor = ui.editor;
var graph = editor.graph;
div.style.paddingTop = '6px';
div.style.paddingBottom = '12px';
div.appendChild(this.createTitle(mxResources.get('distribute')));
var btn = mxUtils.button(mxResources.get('horizontal'), function(evt)
{
graph.distributeCells(true);
})
btn.setAttribute('title', mxResources.get('horizontal'));
btn.style.width = '100px';
btn.style.marginRight = '2px';
div.appendChild(btn);
var btn = mxUtils.button(mxResources.get('vertical'), function(evt)
{
graph.distributeCells(false);
})
btn.setAttribute('title', mxResources.get('vertical'));
btn.style.width = '100px';
div.appendChild(btn);
return div;
};
/**
*
*/
ArrangePanel.prototype.addAngle = function(div)
{
var ui = this.editorUi;
var editor = ui.editor;
var graph = editor.graph;
var ss = this.format.getSelectionState();
div.style.paddingBottom = '8px';
var span = document.createElement('div');
span.style.position = 'absolute';
span.style.width = '70px';
span.style.marginTop = '0px';
span.style.fontWeight = 'bold';
var input = null;
var update = null;
var btn = null;
if (ss.edges.length == 0)
{
mxUtils.write(span, mxResources.get('angle'));
div.appendChild(span);
input = this.addUnitInput(div, '°', 20, 44, function()
{
update.apply(this, arguments);
});
mxUtils.br(div);
div.style.paddingTop = '10px';
}
else
{
div.style.paddingTop = '8px';
}
if (!ss.containsLabel)
{
var label = mxResources.get('reverse');
if (ss.vertices.length > 0 && ss.edges.length > 0)
{
label = mxResources.get('turn') + ' / ' + label;
}
else if (ss.vertices.length > 0)
{
label = mxResources.get('turn');
}
btn = mxUtils.button(label, function(evt)
{
ui.actions.get('turn').funct();
})
btn.setAttribute('title', label + ' (' + this.editorUi.actions.get('turn').shortcut + ')');
btn.style.width = '202px';
div.appendChild(btn);
if (input != null)
{
btn.style.marginTop = '8px';
}
}
if (input != null)
{
var listener = mxUtils.bind(this, function(sender, evt, force)
{
if (force || document.activeElement != input)
{
ss = this.format.getSelectionState();
var tmp = parseFloat(mxUtils.getValue(ss.style, mxConstants.STYLE_ROTATION, 0));
input.value = (isNaN(tmp)) ? '' : tmp + '°';
}
});
update = this.installInputHandler(input, mxConstants.STYLE_ROTATION, 0, 0, 360, '°', null, true);
this.addKeyHandler(input, listener);
graph.getModel().addListener(mxEvent.CHANGE, listener);
this.listeners.push({destroy: function() { graph.getModel().removeListener(listener); }});
listener();
}
return div;
};
/**
*
*/
ArrangePanel.prototype.addGeometry = function(container)
{
var ui = this.editorUi;
var graph = ui.editor.graph;
var rect = this.format.getSelectionState();
var div = this.createPanel();
div.style.paddingBottom = '8px';
var span = document.createElement('div');
span.style.position = 'absolute';
span.style.width = '50px';
span.style.marginTop = '0px';
span.style.fontWeight = 'bold';
mxUtils.write(span, mxResources.get('size'));
div.appendChild(span);
var widthUpdate, heightUpdate, leftUpdate, topUpdate;
var width = this.addUnitInput(div, 'pt', 84, 44, function()
{
widthUpdate.apply(this, arguments);
});
var height = this.addUnitInput(div, 'pt', 20, 44, function()
{
heightUpdate.apply(this, arguments);
});
var autosizeBtn = document.createElement('div');
autosizeBtn.className = 'geSprite geSprite-fit';
autosizeBtn.setAttribute('title', mxResources.get('autosize') + ' (' + this.editorUi.actions.get('autosize').shortcut + ')');
autosizeBtn.style.position = 'relative';
autosizeBtn.style.cursor = 'pointer';
autosizeBtn.style.marginTop = '-3px';
autosizeBtn.style.border = '0px';
autosizeBtn.style.left = '52px';
mxUtils.setOpacity(autosizeBtn, 50);
mxEvent.addListener(autosizeBtn, 'mouseenter', function()
{
mxUtils.setOpacity(autosizeBtn, 100);
});
mxEvent.addListener(autosizeBtn, 'mouseleave', function()
{
mxUtils.setOpacity(autosizeBtn, 50);
});
mxEvent.addListener(autosizeBtn, 'click', function()
{
ui.actions.get('autosize').funct();
});
div.appendChild(autosizeBtn);
this.addLabel(div, mxResources.get('width'), 84);
this.addLabel(div, mxResources.get('height'), 20);
mxUtils.br(div);
var wrapper = document.createElement('div');
wrapper.style.paddingTop = '8px';
wrapper.style.paddingRight = '20px';
wrapper.style.whiteSpace = 'nowrap';
wrapper.style.textAlign = 'right';
var opt = this.createCellOption(mxResources.get('constrainProportions'),
mxConstants.STYLE_ASPECT, null, 'fixed', 'null');
opt.style.width = '100%';
wrapper.appendChild(opt);
div.appendChild(wrapper);
this.addKeyHandler(width, listener);
this.addKeyHandler(height, listener);
widthUpdate = this.addGeometryHandler(width, function(geo, value)
{
if (geo.width > 0)
{
geo.width = Math.max(1, value);
}
});
heightUpdate = this.addGeometryHandler(height, function(geo, value)
{
if (geo.height > 0)
{
geo.height = Math.max(1, value);
}
});
container.appendChild(div);
var div2 = this.createPanel();
div2.style.paddingBottom = '30px';
var span = document.createElement('div');
span.style.position = 'absolute';
span.style.width = '70px';
span.style.marginTop = '0px';
span.style.fontWeight = 'bold';
mxUtils.write(span, mxResources.get('position'));
div2.appendChild(span);
var left = this.addUnitInput(div2, 'pt', 84, 44, function()
{
leftUpdate.apply(this, arguments);
});
var top = this.addUnitInput(div2, 'pt', 20, 44, function()
{
topUpdate.apply(this, arguments);
});
mxUtils.br(div2);
this.addLabel(div2, mxResources.get('left'), 84);
this.addLabel(div2, mxResources.get('top'), 20);
var listener = mxUtils.bind(this, function(sender, evt, force)
{
rect = this.format.getSelectionState();
if (!rect.containsLabel && rect.vertices.length == graph.getSelectionCount() &&
rect.width != null && rect.height != null)
{
div.style.display = '';
if (force || document.activeElement != width)
{
width.value = rect.width + ((rect.width == '') ? '' : ' pt');
}
if (force || document.activeElement != height)
{
height.value = rect.height + ((rect.height == '') ? '' : ' pt');
}
}
else
{
div.style.display = 'none';
}
if (rect.vertices.length == graph.getSelectionCount() &&
rect.x != null && rect.y != null)
{
div2.style.display = '';
if (force || document.activeElement != left)
{
left.value = rect.x + ((rect.x == '') ? '' : ' pt');
}
if (force || document.activeElement != top)
{
top.value = rect.y + ((rect.y == '') ? '' : ' pt');
}
}
else
{
div2.style.display = 'none';
}
});
this.addKeyHandler(left, listener);
this.addKeyHandler(top, listener);
graph.getModel().addListener(mxEvent.CHANGE, listener);
this.listeners.push({destroy: function() { graph.getModel().removeListener(listener); }});
listener();
leftUpdate = this.addGeometryHandler(left, function(geo, value)
{
if (geo.relative)
{
geo.offset.x = value;
}
else
{
geo.x = value;
}
});
topUpdate = this.addGeometryHandler(top, function(geo, value)
{
if (geo.relative)
{
geo.offset.y = value;
}
else
{
geo.y = value;
}
});
container.appendChild(div2);
};
/**
*
*/
ArrangePanel.prototype.addGeometryHandler = function(input, fn)
{
var ui = this.editorUi;
var graph = ui.editor.graph;
var initialValue = null;
function update(evt)
{
if (input.value != '')
{
var value = parseFloat(input.value);
if (value != initialValue)
{
graph.getModel().beginUpdate();
try
{
var cells = graph.getSelectionCells();
for (var i = 0; i < cells.length; i++)
{
if (graph.getModel().isVertex(cells[i]))
{
var geo = graph.getCellGeometry(cells[i]);
if (geo != null)
{
geo = geo.clone();
fn(geo, value);
graph.getModel().setGeometry(cells[i], geo);
}
}
}
}
finally
{
graph.getModel().endUpdate();
}
initialValue = value;
input.value = value + ' pt';
}
else if (isNaN(value))
{
input.value = initialValue + ' pt';
}
}
mxEvent.consume(evt);
};
mxEvent.addListener(input, 'blur', update);
mxEvent.addListener(input, 'change', update);
mxEvent.addListener(input, 'focus', function()
{
initialValue = input.value;
});
return update;
};
/**
*
*/
ArrangePanel.prototype.addEdgeGeometry = function(container)
{
var ui = this.editorUi;
var graph = ui.editor.graph;