Simon Hunt

GUI -- Implemented node lock ('X' key) in preparation for oblique view.

Change-Id: I485ca7977d18fe50ca7e5c500b3fc616506f4543
......@@ -27,7 +27,9 @@
return $.isFunction(f) ? f : null;
}
function createDragBehavior(force, selectCb, atDragEnd, enabled) {
// TODO: sensible defaults
function createDragBehavior(force, selectCb, atDragEnd,
dragEnabled, clickEnabled) {
var draggedThreshold = d3.scale.linear()
.domain([0, 0.1])
.range([5, 20])
......@@ -35,7 +37,8 @@
drag,
fSel = isF(selectCb),
fEnd = isF(atDragEnd),
fEnb = isF(enabled),
fDEn = isF(dragEnabled),
fCEn = isF(clickEnabled),
bad = [];
function naf(what) {
......@@ -48,8 +51,11 @@
if (!fEnd) {
bad.push(naf('atDragEnd'));
}
if (!fEnb) {
bad.push(naf('enabled'));
if (!fDEn) {
bad.push(naf('dragEnabled'));
}
if (!fCEn) {
bad.push(naf('clickEnabled'));
}
if (bad.length) {
......@@ -71,7 +77,7 @@
drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on('dragstart', function(d) {
if (enabled()) {
if (clickEnabled() || dragEnabled()) {
d3.event.sourceEvent.stopPropagation();
d.oldX = d.x;
......@@ -82,7 +88,7 @@
}
})
.on('drag', function(d) {
if (enabled()) {
if (dragEnabled()) {
d.px = d3.event.x;
d.py = d3.event.y;
if (dragged(d)) {
......@@ -96,13 +102,18 @@
if (d.dragStarted) {
d.dragStarted = false;
if (!dragged(d)) {
// consider this the same as a 'click' (selection of node)
selectCb(d, this); // TODO: set 'this' context instead of param
// consider this the same as a 'click'
// (selection of a node)
if (clickEnabled()) {
selectCb(d, this); // TODO: set 'this' context instead of param
}
}
d.fixed &= ~6;
// hook at the end of a drag gesture
atDragEnd(d, this); // TODO: set 'this' context instead of param
if (dragEnabled()) {
atDragEnd(d, this); // TODO: set 'this' context instead of param
}
}
});
......
......@@ -148,6 +148,8 @@
V: [showTrafficAction, 'Show related traffic'],
A: [showAllTrafficAction, 'Show all traffic'],
F: [showDeviceLinkFlowsAction, 'Show device link flows'],
X: [toggleNodeLock, 'Lock / unlock node positions'],
Z: [toggleOblique, 'Toggle oblique view'],
esc: handleEscape
};
......@@ -203,7 +205,8 @@
showOffline = true,
useDetails = true,
haveDetails = false,
dragAllowed = true;
nodeLock = false,
oblique = false;
// constants
var hoverModeAll = 1,
......@@ -323,6 +326,16 @@
bgImg.style('visibility', visVal(vis === 'hidden'));
}
function toggleNodeLock() {
nodeLock = !nodeLock;
flash('Node positions ' + (nodeLock ? 'locked' : 'unlocked'))
}
function toggleOblique() {
oblique = !oblique;
// TODO: oblique transformation
}
function toggleHosts() {
showHosts = !showHosts;
updateHostVisibility();
......@@ -2704,9 +2717,12 @@
// predicate that indicates when dragging is active
function dragEnabled() {
// meta key pressed means we are zooming/panning (so disable drag)
return dragAllowed && !d3.event.sourceEvent.metaKey;
// dragAllowed will be set false when we are in oblique view
// or when we 'lock' node positions
return !nodeLock && !d3.event.sourceEvent.metaKey;
}
// predicate that indicates when clicking is active
function clickEnabled() {
return true;
}
// set up the force layout
......@@ -2722,7 +2738,7 @@
.on('tick', tick);
network.drag = d3u.createDragBehavior(network.force,
selectCb, atDragEnd, dragEnabled);
selectCb, atDragEnd, dragEnabled, clickEnabled);
// create mask layer for when we lose connection to server.
......