///
///
///
var AB;
(function (AB) {
var ContextMenu = (function () {
function ContextMenu(viewer) {
var scope = this;
// Members
this.viewer = viewer;
this.showing = false;
this.savedColor = Raphael.rgb(255, 255, 255);
this.overColor = Raphael.rgb(140, 200, 230);
// Context menu elements
this.elements = [
{ text: "Reduce", rect: null, action: "onReduce" },
{ text: "Delete", rect: null, action: "onRemoveNode" },
{ text: "Delete branch", rect: null, action: "onRemoveBranch" },
{ text: "Connect / Disconnect", rect: null, action: "onDetachNode" },
{ text: "Copy", rect: null, action: "onCopyStructure" },
{ text: "Paste", rect: null, action: "onPasteStructure" },
// Add other elements here
{ text: "", rect: null, action: null } // Color separator (top)
];
// Finish
this.attachControl(viewer.graph.canvas);
}
// Attaches controls to the viewer
// element: the viewer element (canvas or div or etc.)
ContextMenu.prototype.attachControl = function (element) {
var scope = this;
var onClick = function (event) {
var x = scope.viewer.mousex;
var y = scope.viewer.mousey;
// Remove all context menu nodes, and run action if selected
if (scope.showing) {
for (var i = 0; i < scope.elements.length; i++) {
var el = scope.elements[i];
if (el.action && el.rect.isPointInside(x, y))
scope.viewer.utils[el.action]();
scope.viewer._removeNode(el.rect);
}
}
scope.showing = false;
};
var onMouseMove = function (event) {
// Override context menu's node color if mouse is inside
if (scope.showing) {
for (var i = 0; i < scope.elements.length; i++) {
var el = scope.elements[i];
if (el.text == "")
continue;
var x = scope.viewer.mousex;
var y = scope.viewer.mousey;
if (el.rect.isPointInside(x, y))
el.rect.attr(el.rect.rect, "fill", scope.overColor);
else
el.rect.attr(el.rect.rect, "fill", scope.savedColor);
}
}
};
var onRightClick = function (event) {
var x = scope.viewer.mousex;
var y = scope.viewer.mousey;
if (y + (AB.Graph.NODE_HEIGHT * scope.elements.length) > scope.viewer.element.offsetHeight + scope.viewer.element.scrollTop)
y = (AB.Graph.NODE_HEIGHT * scope.elements.length);
if (x + AB.Graph.NODE_WIDTH > scope.viewer.element.offsetWidth + scope.viewer.element.scrollLeft)
x -= AB.Graph.NODE_WIDTH;
scope.viewer.onClick(event);
// Set selected node
var result = scope.viewer.traverseGraph(null, x, y);
if (result.hit) {
scope.viewer.selectedNode = result.element;
}
if (!scope.showing) {
if (scope.viewer.selectedNode == null)
return;
// Create elements
var yOffset = 10;
for (var i = 0; i < scope.elements.length - 1; i++) {
var el = scope.elements[i];
el.rect = scope.viewer._createNode(el.text, Raphael.rgb(216, 216, 216), true);
scope.viewer._setNodePosition(el.rect, x, y + yOffset);
el.rect.text.attr("x", x + 5);
yOffset += AB.Graph.NODE_HEIGHT;
}
// Color separator
var separator = scope.elements[scope.elements.length - 1];
separator.rect = scope.viewer._createNode("", scope.viewer.getNodeColor(scope.viewer.selectedNode), true);
scope.viewer._setNodePosition(separator.rect, x, y);
separator.rect.attr(separator.rect.rect, "height", 10);
// Finish
scope.showing = true;
}
else {
onClick();
onRightClick(event);
}
window.event.returnValue = false;
};
document.addEventListener("click", onClick);
document.addEventListener("mousemove", onMouseMove);
element.addEventListener("contextmenu", onRightClick);
}
return ContextMenu;
})();
AB.ContextMenu = ContextMenu;
})(AB || (AB = { }));