Simon Hunt

GUI -- TopoView - added node selection logic.

- added inArray() and removeFromArray() functions to FnService.

Change-Id: I0e9631fa9e5865cb171e8d505f45c1963a1903dc
......@@ -117,6 +117,32 @@
return -1;
}
// search through array to find (the first occurrence of) item,
// returning its index if found; otherwise returning -1.
function inArray(item, array) {
var i;
if (isA(array)) {
for (i=0; i<array.length; i++) {
if (array[i] === item) {
return i;
}
}
}
return -1;
}
// remove (the first occurrence of) the specified item from the given
// array, if any. Return true if the removal was made; false otherwise.
function removeFromArray(item, array) {
var found = false,
i = inArray(item, array);
if (i >= 0) {
array.splice(i, 1);
found = true;
}
return found;
}
angular.module('onosUtil')
.factory('FnService', ['$window', function (_$window_) {
$window = _$window_;
......@@ -130,7 +156,9 @@
areFunctions: areFunctions,
areFunctionsNonStrict: areFunctionsNonStrict,
windowSize: windowSize,
find: find
find: find,
inArray: inArray,
removeFromArray: removeFromArray
};
}]);
......
......@@ -111,8 +111,7 @@
<div id="quickhelp"></div>
<div id="veil"
resize
ng-style="resizeWithOffset(0, 0)"
></div>
ng-style="resizeWithOffset(0, 0)"></div>
</div>
</body>
</html>
......
......@@ -77,7 +77,9 @@
oblique = false, // whether we are in the oblique view
nodeLock = false, // whether nodes can be dragged or not (locked)
width, height, // the width and height of the force layout
hovered; // the node over which the mouse is hovering
hovered, // the node over which the mouse is hovering
selections = {}, // what is currently selected
selectOrder = []; // the order in which we made selections
// SVG elements;
var linkG, linkLabelG, nodeG;
......@@ -1323,15 +1325,77 @@
}
function updateDetailPanel() {
// TODO update detail panel
$log.debug("TODO: updateDetailPanel() ...");
}
// ==========================
// === SELECTION / DESELECTION
function selectObject(obj) {
var el = this,
ev = d3.event.sourceEvent,
n;
if (zoomingOrPanning(ev)) {
return;
}
if (el) {
n = d3.select(el);
} else {
node.each(function (d) {
if (d == obj) {
n = d3.select(el = this);
}
});
}
if (!n) return;
if (ev.shiftKey && n.classed('selected')) {
deselectObject(obj.id);
updateDetailPanel();
return;
}
if (!ev.shiftKey) {
deselectAll();
}
selections[obj.id] = { obj: obj, el: el };
selectOrder.push(obj.id);
n.classed('selected', true);
updateDeviceColors(obj);
updateDetailPanel();
}
function deselectObject(id) {
var obj = selections[id];
if (obj) {
d3.select(obj.el).classed('selected', false);
delete selections[id];
fs.removeFromArray(id, selectOrder);
updateDeviceColors(obj.obj);
}
}
function deselectAll() {
// deselect all nodes in the network...
node.classed('selected', false);
selections = {};
selectOrder = [];
updateDeviceColors();
updateDetailPanel();
}
// ==========================
// === MOUSE GESTURE HANDLERS
function selectCb(d) {
// this is the selected node
$log.debug("\n\n\nSelect Object: ");
$log.debug("d is ", d);
$log.debug("this is ", this);
$log.debug('\n\n');
function zoomingOrPanning(ev) {
return ev.metaKey || ev.altKey;
}
function atDragEnd(d) {
......@@ -1345,8 +1409,7 @@
function dragEnabled() {
var ev = d3.event.sourceEvent;
// nodeLock means we aren't allowing nodes to be dragged...
// meta or alt key pressed means we are zooming/panning...
return !nodeLock && !(ev.metaKey || ev.altKey);
return !nodeLock && !zoomingOrPanning(ev);
}
// predicate that indicates when clicking is active
......@@ -1406,7 +1469,7 @@
.on('tick', tick);
drag = sus.createDragBehavior(force,
selectCb, atDragEnd, dragEnabled, clickEnabled);
selectObject, atDragEnd, dragEnabled, clickEnabled);
}
function resize(dim) {
......
......@@ -201,7 +201,8 @@ describe('factory: fw/util/fn.js', function() {
it('should define api functions', function () {
expect(fs.areFunctions(fs, [
'isF', 'isA', 'isS', 'isO', 'contains',
'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'find'
'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'find',
'inArray', 'removeFromArray'
])).toBeTruthy();
});
......@@ -260,4 +261,68 @@ describe('factory: fw/util/fn.js', function() {
it('should find Zevvv', function () {
expect(fs.find('Zevvv', dataset, 'name')).toEqual(4);
});
// === Tests for inArray()
var objRef = { x:1, y:2 },
array = [1, 3.14, 'hey', objRef, 'there', true],
array2 = ['b', 'a', 'd', 'a', 's', 's'];
it('should return -1 on non-arrays', function () {
expect(fs.inArray(1, {x:1})).toEqual(-1);
});
it('should not find HOO', function () {
expect(fs.inArray('HOO', array)).toEqual(-1);
});
it('should find 1', function () {
expect(fs.inArray(1, array)).toEqual(0);
});
it('should find pi', function () {
expect(fs.inArray(3.14, array)).toEqual(1);
});
it('should find hey', function () {
expect(fs.inArray('hey', array)).toEqual(2);
});
it('should find the object', function () {
expect(fs.inArray(objRef, array)).toEqual(3);
});
it('should find there', function () {
expect(fs.inArray('there', array)).toEqual(4);
});
it('should find true', function () {
expect(fs.inArray(true, array)).toEqual(5);
});
it('should find the first occurrence A', function () {
expect(fs.inArray('a', array2)).toEqual(1);
});
it('should find the first occurrence S', function () {
expect(fs.inArray('s', array2)).toEqual(4);
});
it('should not find X', function () {
expect(fs.inArray('x', array2)).toEqual(-1);
});
// === Tests for removeFromArray()
it('should ignore non-arrays', function () {
expect(fs.removeFromArray(1, {x:1})).toBe(false);
});
it('should keep the array the same, for non-match', function () {
var array = [1, 2, 3];
expect(fs.removeFromArray(4, array)).toBe(false);
expect(array).toEqual([1, 2, 3]);
});
it('should remove a value', function () {
var array = [1, 2, 3];
expect(fs.removeFromArray(2, array)).toBe(true);
expect(array).toEqual([1, 3]);
});
it('should remove the first occurrence', function () {
var array = ['x', 'y', 'z', 'z', 'y'];
expect(fs.removeFromArray('y', array)).toBe(true);
expect(array).toEqual(['x', 'z', 'z', 'y']);
expect(fs.removeFromArray('x', array)).toBe(true);
expect(array).toEqual(['z', 'z', 'y']);
});
});
......