mirror of https://gitee.com/bigwinds/arangodb
449 lines
12 KiB
JavaScript
449 lines
12 KiB
JavaScript
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
|
|
/*global $, _, d3*/
|
|
/*global document, window*/
|
|
/*global modalDialogHelper, uiComponentsHelper */
|
|
/*global EventDispatcher*/
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Graph functionality
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// @author Michael Hackstein
|
|
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function EventDispatcherControls(list, nodeShaper, edgeShaper, start, dispatcherConfig) {
|
|
"use strict";
|
|
|
|
if (list === undefined) {
|
|
throw "A list element has to be given.";
|
|
}
|
|
if (nodeShaper === undefined) {
|
|
throw "The NodeShaper has to be given.";
|
|
}
|
|
if (edgeShaper === undefined) {
|
|
throw "The EdgeShaper has to be given.";
|
|
}
|
|
if (start === undefined) {
|
|
throw "The Start callback has to be given.";
|
|
}
|
|
|
|
var self = this,
|
|
icons = {
|
|
expand: "expand",
|
|
add: "add",
|
|
trash: "trash",
|
|
drag: "drag",
|
|
edge: "connect",
|
|
edit: "edit",
|
|
view: "view"
|
|
},
|
|
dispatcher = new EventDispatcher(nodeShaper, edgeShaper, dispatcherConfig),
|
|
|
|
appendToList = function(button) {
|
|
list.appendChild(button);
|
|
},
|
|
createIcon = function(icon, title, callback) {
|
|
var btn = uiComponentsHelper.createIconButton(
|
|
icon,
|
|
"control_event_" + title,
|
|
callback
|
|
);
|
|
appendToList(btn);
|
|
},
|
|
rebindNodes = function(actions) {
|
|
dispatcher.rebind("nodes", actions);
|
|
},
|
|
rebindEdges = function(actions) {
|
|
dispatcher.rebind("edges", actions);
|
|
},
|
|
rebindSVG = function(actions) {
|
|
dispatcher.rebind("svg", actions);
|
|
},
|
|
getCursorPosition = function (ev) {
|
|
var e = ev || window.event,
|
|
res = {};
|
|
res.x = e.clientX;
|
|
res.y = e.clientY;
|
|
res.x += document.body.scrollLeft;
|
|
res.y += document.body.scrollTop;
|
|
return res;
|
|
},
|
|
getCursorPositionInSVG = function (ev) {
|
|
var pos = getCursorPosition(ev),
|
|
off = $('svg').offset();
|
|
// Hack for Firefox
|
|
/*
|
|
var off = {
|
|
left: 166,
|
|
top: 171
|
|
};
|
|
*/
|
|
pos.x -= off.left;
|
|
pos.y -= off.top;
|
|
return pos;
|
|
},
|
|
callbacks = {
|
|
nodes: {},
|
|
edges: {},
|
|
svg: {}
|
|
},
|
|
|
|
/*******************************************
|
|
* Create callbacks wenn clicking on objects
|
|
*
|
|
*******************************************/
|
|
|
|
createNewNodeCB = function() {
|
|
var prefix = "control_event_new_node",
|
|
idprefix = prefix + "_",
|
|
createCallback = function(ev) {
|
|
var pos = getCursorPositionInSVG(ev);
|
|
modalDialogHelper.createModalCreateDialog(
|
|
"Create New Node",
|
|
idprefix,
|
|
{},
|
|
function(data) {
|
|
dispatcher.events.CREATENODE(data, function(node) {
|
|
$("#" + idprefix + "modal").modal('hide');
|
|
nodeShaper.reshapeNodes();
|
|
start();
|
|
}, pos.x, pos.y)();
|
|
}
|
|
);
|
|
};
|
|
callbacks.nodes.newNode = createCallback;
|
|
},
|
|
createViewCBs = function() {
|
|
var prefix = "control_event_view",
|
|
idprefix = prefix + "_",
|
|
nodeCallback = function(n) {
|
|
modalDialogHelper.createModalViewDialog(
|
|
"View Node " + n._id,
|
|
"control_event_node_view_",
|
|
n._data,
|
|
function() {
|
|
modalDialogHelper.createModalEditDialog(
|
|
"Edit Node " + n._id,
|
|
"control_event_node_edit_",
|
|
n._data,
|
|
function(newData) {
|
|
dispatcher.events.PATCHNODE(n, newData, function() {
|
|
$("#control_event_node_edit_modal").modal('hide');
|
|
})();
|
|
}
|
|
);
|
|
}
|
|
);
|
|
},
|
|
edgeCallback = function(e) {
|
|
modalDialogHelper.createModalViewDialog(
|
|
"View Edge " + e._id,
|
|
"control_event_edge_view_",
|
|
e._data,
|
|
function() {
|
|
modalDialogHelper.createModalEditDialog(
|
|
"Edit Edge " + e._id,
|
|
"control_event_edge_edit_",
|
|
e._data,
|
|
function(newData) {
|
|
dispatcher.events.PATCHEDGE(e, newData, function() {
|
|
$("#control_event_edge_edit_modal").modal('hide');
|
|
})();
|
|
}
|
|
);
|
|
}
|
|
);
|
|
};
|
|
|
|
callbacks.nodes.view = nodeCallback;
|
|
callbacks.edges.view = edgeCallback;
|
|
},
|
|
createConnectCBs = function() {
|
|
var prefix = "control_event_connect",
|
|
idprefix = prefix + "_",
|
|
nodesDown = dispatcher.events.STARTCREATEEDGE(function(startNode, ev) {
|
|
var pos = getCursorPositionInSVG(ev),
|
|
moveCB = edgeShaper.addAnEdgeFollowingTheCursor(pos.x, pos.y);
|
|
dispatcher.bind("svg", "mousemove", function(ev) {
|
|
var pos = getCursorPositionInSVG(ev);
|
|
moveCB(pos.x, pos.y);
|
|
});
|
|
}),
|
|
nodesUp = dispatcher.events.FINISHCREATEEDGE(function(edge){
|
|
edgeShaper.removeCursorFollowingEdge();
|
|
dispatcher.bind("svg", "mousemove", function(){});
|
|
start();
|
|
}),
|
|
svgUp = function() {
|
|
dispatcher.events.CANCELCREATEEDGE();
|
|
edgeShaper.removeCursorFollowingEdge();
|
|
dispatcher.bind("svg", "mousemove", function(){});
|
|
};
|
|
callbacks.nodes.startEdge = nodesDown;
|
|
callbacks.nodes.endEdge = nodesUp;
|
|
callbacks.svg.cancelEdge = svgUp;
|
|
},
|
|
|
|
createEditsCBs = function() {
|
|
var nodeCallback = function(n) {
|
|
modalDialogHelper.createModalEditDialog(
|
|
"Edit Node " + n._id,
|
|
"control_event_node_edit_",
|
|
n._data,
|
|
function(newData) {
|
|
dispatcher.events.PATCHNODE(n, newData, function() {
|
|
$("#control_event_node_edit_modal").modal('hide');
|
|
})();
|
|
}
|
|
);
|
|
},
|
|
edgeCallback = function(e) {
|
|
modalDialogHelper.createModalEditDialog(
|
|
"Edit Edge " + e._id,
|
|
"control_event_edge_edit_",
|
|
e._data,
|
|
function(newData) {
|
|
dispatcher.events.PATCHEDGE(e, newData, function() {
|
|
$("#control_event_edge_edit_modal").modal('hide');
|
|
})();
|
|
}
|
|
);
|
|
};
|
|
callbacks.nodes.edit = nodeCallback;
|
|
callbacks.edges.edit = edgeCallback;
|
|
},
|
|
|
|
createDeleteCBs = function() {
|
|
var nodeCallback = function(n) {
|
|
modalDialogHelper.createModalDeleteDialog(
|
|
"Delete Node " + n._id,
|
|
"control_event_node_delete_",
|
|
n,
|
|
function(n) {
|
|
dispatcher.events.DELETENODE(function() {
|
|
$("#control_event_node_delete_modal").modal('hide');
|
|
nodeShaper.reshapeNodes();
|
|
edgeShaper.reshapeEdges();
|
|
start();
|
|
})(n);
|
|
}
|
|
);
|
|
},
|
|
edgeCallback = function(e) {
|
|
modalDialogHelper.createModalDeleteDialog(
|
|
"Delete Edge " + e._id,
|
|
"control_event_edge_delete_",
|
|
e,
|
|
function(e) {
|
|
dispatcher.events.DELETEEDGE(function() {
|
|
$("#control_event_edge_delete_modal").modal('hide');
|
|
nodeShaper.reshapeNodes();
|
|
edgeShaper.reshapeEdges();
|
|
start();
|
|
})(e);
|
|
}
|
|
);
|
|
};
|
|
callbacks.nodes.del = nodeCallback;
|
|
callbacks.edges.del = edgeCallback;
|
|
},
|
|
|
|
createSpotCB = function() {
|
|
callbacks.nodes.spot = dispatcher.events.EXPAND;
|
|
};
|
|
|
|
createNewNodeCB();
|
|
createViewCBs();
|
|
createConnectCBs();
|
|
createEditsCBs();
|
|
createDeleteCBs();
|
|
createSpotCB();
|
|
|
|
/*******************************************
|
|
* Raw rebind objects
|
|
*
|
|
*******************************************/
|
|
this.dragRebinds = function() {
|
|
return {
|
|
nodes: {
|
|
drag: dispatcher.events.DRAG
|
|
}
|
|
};
|
|
};
|
|
|
|
this.newNodeRebinds = function() {
|
|
return {
|
|
svg: {
|
|
click: callbacks.nodes.newNode
|
|
}
|
|
};
|
|
};
|
|
|
|
this.viewRebinds = function() {
|
|
return {
|
|
nodes: {
|
|
click: callbacks.nodes.view
|
|
},
|
|
edges: {
|
|
click: callbacks.edges.view
|
|
}
|
|
};
|
|
};
|
|
|
|
this.connectNodesRebinds = function() {
|
|
return {
|
|
nodes: {
|
|
mousedown: callbacks.nodes.startEdge,
|
|
mouseup: callbacks.nodes.endEdge
|
|
},
|
|
svg: {
|
|
mouseup: callbacks.svg.cancelEdge
|
|
}
|
|
};
|
|
};
|
|
|
|
this.editRebinds = function() {
|
|
return {
|
|
nodes: {
|
|
click: callbacks.nodes.edit
|
|
},
|
|
edges: {
|
|
click: callbacks.edges.edit
|
|
}
|
|
};
|
|
};
|
|
|
|
this.expandRebinds = function() {
|
|
return {
|
|
nodes: {
|
|
click: callbacks.nodes.spot
|
|
}
|
|
};
|
|
};
|
|
|
|
this.deleteRebinds = function() {
|
|
return {
|
|
nodes: {
|
|
click: callbacks.nodes.del
|
|
},
|
|
edges: {
|
|
click: callbacks.edges.del
|
|
}
|
|
};
|
|
};
|
|
|
|
this.rebindAll = function(obj) {
|
|
rebindNodes(obj.nodes);
|
|
rebindEdges(obj.edges);
|
|
rebindSVG(obj.svg);
|
|
};
|
|
|
|
/*******************************************
|
|
* Inject controls into right-click menus
|
|
*
|
|
*******************************************/
|
|
|
|
nodeShaper.addMenuEntry("View", callbacks.nodes.view);
|
|
nodeShaper.addMenuEntry("Edit", callbacks.nodes.edit);
|
|
nodeShaper.addMenuEntry("Spot", callbacks.nodes.spot);
|
|
nodeShaper.addMenuEntry("Trash", callbacks.nodes.del);
|
|
|
|
edgeShaper.addMenuEntry("View", callbacks.edges.view);
|
|
edgeShaper.addMenuEntry("Edit", callbacks.edges.edit);
|
|
edgeShaper.addMenuEntry("Trash", callbacks.edges.del);
|
|
|
|
|
|
/*******************************************
|
|
* Functions to add controls
|
|
*
|
|
*******************************************/
|
|
|
|
|
|
this.addControlNewNode = function() {
|
|
var icon = icons.add,
|
|
callback = function() {
|
|
self.rebindAll(self.newNodeRebinds());
|
|
};
|
|
createIcon(icon, "new_node", callback);
|
|
};
|
|
|
|
this.addControlView = function() {
|
|
var icon = icons.view,
|
|
callback = function() {
|
|
self.rebindAll(self.viewRebinds());
|
|
};
|
|
createIcon(icon, "view", callback);
|
|
};
|
|
|
|
this.addControlDrag = function() {
|
|
var prefix = "control_event_drag",
|
|
idprefix = prefix + "_",
|
|
icon = icons.drag,
|
|
callback = function() {
|
|
self.rebindAll(self.dragRebinds());
|
|
};
|
|
createIcon(icon, "drag", callback);
|
|
};
|
|
|
|
this.addControlEdit = function() {
|
|
var icon = icons.edit,
|
|
callback = function() {
|
|
self.rebindAll(self.editRebinds());
|
|
};
|
|
createIcon(icon, "edit", callback);
|
|
};
|
|
|
|
this.addControlExpand = function() {
|
|
var icon = icons.expand,
|
|
callback = function() {
|
|
self.rebindAll(self.expandRebinds());
|
|
};
|
|
createIcon(icon, "expand", callback);
|
|
};
|
|
|
|
this.addControlDelete = function() {
|
|
var icon = icons.trash,
|
|
callback = function() {
|
|
self.rebindAll(self.deleteRebinds());
|
|
};
|
|
createIcon(icon, "delete", callback);
|
|
};
|
|
|
|
this.addControlConnect = function() {
|
|
var icon = icons.edge,
|
|
callback = function() {
|
|
self.rebindAll(self.connectNodesRebinds());
|
|
};
|
|
createIcon(icon, "connect", callback);
|
|
};
|
|
|
|
this.addAll = function () {
|
|
self.addControlDrag();
|
|
self.addControlView();
|
|
self.addControlEdit();
|
|
self.addControlExpand();
|
|
self.addControlDelete();
|
|
self.addControlConnect();
|
|
self.addControlNewNode();
|
|
};
|
|
}
|