Simon Hunt
Committed by Gerrit Code Review

GUI -- [ONOS-267] -- Mouse gestures added to quick help.

- added ability for view to define 'gestures' to be added to quick help.
- improved the layout of quick help by computing the widest 'key' and using that to space descriptions column.

Change-Id: I5a5a38d3218857ba9bca33c8fc79be38f17f7316
...@@ -63,7 +63,8 @@ ...@@ -63,7 +63,8 @@
63 globalKeys: {}, 63 globalKeys: {},
64 maskedKeys: {}, 64 maskedKeys: {},
65 viewKeys: {}, 65 viewKeys: {},
66 - viewFn: null 66 + viewFn: null,
67 + viewGestures: []
67 }, 68 },
68 alerts = { 69 alerts = {
69 open: false, 70 open: false,
...@@ -452,6 +453,10 @@ ...@@ -452,6 +453,10 @@
452 return true; 453 return true;
453 } 454 }
454 455
456 + function setGestureNotes(g) {
457 + keyHandler.viewGestures = isA(g) || [];
458 + }
459 +
455 function setKeyBindings(keyArg) { 460 function setKeyBindings(keyArg) {
456 var viewKeys, 461 var viewKeys,
457 masked = []; 462 masked = [];
...@@ -614,6 +619,7 @@ ...@@ -614,6 +619,7 @@
614 uid: this.uid, 619 uid: this.uid,
615 setRadio: this.setRadio, 620 setRadio: this.setRadio,
616 setKeys: this.setKeys, 621 setKeys: this.setKeys,
622 + setGestures: this.setGestures,
617 dataLoadError: this.dataLoadError, 623 dataLoadError: this.dataLoadError,
618 alert: this.alert, 624 alert: this.alert,
619 flash: this.flash, 625 flash: this.flash,
...@@ -719,6 +725,10 @@ ...@@ -719,6 +725,10 @@
719 setKeyBindings(keyArg); 725 setKeyBindings(keyArg);
720 }, 726 },
721 727
728 + setGestures: function (g) {
729 + setGestureNotes(g);
730 + },
731 +
722 getTheme: function () { 732 getTheme: function () {
723 return current.theme; 733 return current.theme;
724 }, 734 },
......
...@@ -43,7 +43,8 @@ ...@@ -43,7 +43,8 @@
43 svg = qhdiv.select('svg'), 43 svg = qhdiv.select('svg'),
44 pane, 44 pane,
45 rect, 45 rect,
46 - items; 46 + items,
47 + keyAgg;
47 48
48 // General functions 49 // General functions
49 function isA(a) { 50 function isA(a) {
...@@ -73,7 +74,7 @@ ...@@ -73,7 +74,7 @@
73 var pad = 8, 74 var pad = 8,
74 offy = 45, 75 offy = 45,
75 dy = 14, 76 dy = 14,
76 - offDesc = 40; 77 + offDesc = 8;
77 78
78 // D3 magic 79 // D3 magic
79 function updateKeyItems() { 80 function updateKeyItems() {
...@@ -91,7 +92,7 @@ ...@@ -91,7 +92,7 @@
91 var el = d3.select(this), 92 var el = d3.select(this),
92 y = offy + dy * i; 93 y = offy + dy * i;
93 94
94 - if (d.id === '_') { 95 + if (d.id[0] === '_') {
95 el.append('line') 96 el.append('line')
96 .attr({ x1: 0, y1: y, x2: 1, y2: y}); 97 .attr({ x1: 0, y1: y, x2: 1, y2: y});
97 } else { 98 } else {
...@@ -102,6 +103,8 @@ ...@@ -102,6 +103,8 @@
102 x: 0, 103 x: 0,
103 y: y 104 y: y
104 }); 105 });
106 + // NOTE: used for sizing column width...
107 + keyAgg.append('text').text(d.key).attr('class', 'key');
105 108
106 el.append('text') 109 el.append('text')
107 .text(d.desc) 110 .text(d.desc)
...@@ -113,11 +116,14 @@ ...@@ -113,11 +116,14 @@
113 } 116 }
114 }); 117 });
115 118
119 + var kbox = keyAgg.node().getBBox();
120 + items.selectAll('.desc').attr('x', kbox.width + offDesc);
121 +
116 var box = items.node().getBBox(), 122 var box = items.node().getBBox(),
117 paneW = box.width + pad * 2, 123 paneW = box.width + pad * 2,
118 paneH = box.height + offy; 124 paneH = box.height + offy;
119 125
120 - items.select('line').attr('x2', box.width); 126 + items.selectAll('line').attr('x2', box.width);
121 items.attr('transform', translate(-paneW/2, -pad)); 127 items.attr('transform', translate(-paneW/2, -pad));
122 rect.attr({ 128 rect.attr({
123 width: paneW, 129 width: paneW,
...@@ -134,25 +140,47 @@ ...@@ -134,25 +140,47 @@
134 var gmap = d3.map(bindings.globalKeys), 140 var gmap = d3.map(bindings.globalKeys),
135 vmap = d3.map(bindings.viewKeys), 141 vmap = d3.map(bindings.viewKeys),
136 gkeys = gmap.keys(), 142 gkeys = gmap.keys(),
137 - vkeys = vmap.keys(); 143 + vkeys = vmap.keys(),
144 + vgest = bindings.viewGestures,
145 + sep = 0;
138 146
139 gkeys.sort(); 147 gkeys.sort();
140 vkeys.sort(); 148 vkeys.sort();
141 149
142 data = []; 150 data = [];
143 gkeys.forEach(function (k) { 151 gkeys.forEach(function (k) {
144 - addItem('global', k, gmap.get(k)); 152 + addItem('glob', k, gmap.get(k));
145 }); 153 });
146 - addItem('separator'); 154 + addItem('sep');
147 vkeys.forEach(function (k) { 155 vkeys.forEach(function (k) {
148 addItem('view', k, vmap.get(k)); 156 addItem('view', k, vmap.get(k));
149 }); 157 });
158 + addItem('sep');
159 + vgest.forEach(function (g) {
160 + if (g.length === 2) {
161 + addItem('gest', g[0], g[1]);
162 + }
163 + });
164 +
150 165
151 function addItem(type, k, d) { 166 function addItem(type, k, d) {
152 var id = type + '-' + k, 167 var id = type + '-' + k,
153 a = isA(d), 168 a = isA(d),
154 desc = a && a[1]; 169 desc = a && a[1];
155 - if (desc) { 170 +
171 + if (type === 'sep') {
172 + data.push({
173 + id: '_' + sep++,
174 + type: type
175 + });
176 + } else if (type === 'gest') {
177 + data.push({
178 + id: id,
179 + type: type,
180 + key: k,
181 + desc: d
182 + });
183 + } else if (desc) {
156 data.push( 184 data.push(
157 { 185 {
158 id: id, 186 id: id,
...@@ -161,11 +189,6 @@ ...@@ -161,11 +189,6 @@
161 desc: desc 189 desc: desc
162 } 190 }
163 ); 191 );
164 - } else if (type === 'separator') {
165 - data.push({
166 - id: '_',
167 - type: type
168 - });
169 } 192 }
170 } 193 }
171 } 194 }
...@@ -189,6 +212,7 @@ ...@@ -189,6 +212,7 @@
189 }); 212 });
190 213
191 items = pane.append('g'); 214 items = pane.append('g');
215 + keyAgg = pane.append('g').style('visibility', 'hidden');
192 216
193 aggregateData(bindings); 217 aggregateData(bindings);
194 updateKeyItems(); 218 updateKeyItems();
......
...@@ -146,14 +146,23 @@ ...@@ -146,14 +146,23 @@
146 H: [toggleHosts, 'Toggle host visibility'], 146 H: [toggleHosts, 'Toggle host visibility'],
147 L: [cycleLabels, 'Cycle Device labels'], 147 L: [cycleLabels, 'Cycle Device labels'],
148 P: togglePorts, 148 P: togglePorts,
149 - U: [unpin, 'Unpin node'], 149 + U: [unpin, 'Unpin node (hover mouse over)'],
150 - R: [resetZoomPan, 'Reset zoom/pan'], 150 + R: [resetZoomPan, 'Reset zoom / pan'],
151 V: [showTrafficAction, 'Show related traffic'], 151 V: [showTrafficAction, 'Show related traffic'],
152 A: [showAllTrafficAction, 'Show all traffic'], 152 A: [showAllTrafficAction, 'Show all traffic'],
153 F: [showDeviceLinkFlowsAction, 'Show device link flows'], 153 F: [showDeviceLinkFlowsAction, 'Show device link flows'],
154 esc: handleEscape 154 esc: handleEscape
155 }; 155 };
156 156
157 + // mouse gestures
158 + var gestures = [
159 + ['click', 'Select the item and show details'],
160 + ['shift-click', 'Toggle selection state'],
161 + ['drag', 'Reposition (and pin) device / host'],
162 + ['cmd-scroll', 'Zoom in / out'],
163 + ['cmd-drag', 'Pan']
164 + ];
165 +
157 // state variables 166 // state variables
158 var network = { 167 var network = {
159 view: null, // view token reference 168 view: null, // view token reference
...@@ -2385,6 +2394,7 @@ ...@@ -2385,6 +2394,7 @@
2385 2394
2386 //var showInstances; 2395 //var showInstances;
2387 2396
2397 +/*
2388 function addButtonBar(view) { 2398 function addButtonBar(view) {
2389 var bb = d3.select('#mast') 2399 var bb = d3.select('#mast')
2390 .append('span').classed('right', true).attr('id', 'bb'); 2400 .append('span').classed('right', true).attr('id', 'bb');
...@@ -2398,6 +2408,7 @@ ...@@ -2398,6 +2408,7 @@
2398 2408
2399 //showInstances = mkTogBtn('Show Instances', toggleInst); 2409 //showInstances = mkTogBtn('Show Instances', toggleInst);
2400 } 2410 }
2411 +*/
2401 2412
2402 function panZoom() { 2413 function panZoom() {
2403 return false; 2414 return false;
...@@ -2555,10 +2566,11 @@ ...@@ -2555,10 +2566,11 @@
2555 // set our radio buttons and key bindings 2566 // set our radio buttons and key bindings
2556 layerBtnSet = view.setRadio(layerButtons); 2567 layerBtnSet = view.setRadio(layerButtons);
2557 view.setKeys(keyDispatch); 2568 view.setKeys(keyDispatch);
2569 + view.setGestures(gestures);
2558 2570
2559 // patch in our "button bar" for now 2571 // patch in our "button bar" for now
2560 // TODO: implement a more official frameworky way of doing this.. 2572 // TODO: implement a more official frameworky way of doing this..
2561 - addButtonBar(view); 2573 + //addButtonBar(view);
2562 2574
2563 // Load map data asynchronously; complete startup after that.. 2575 // Load map data asynchronously; complete startup after that..
2564 loadGeoJsonData(); 2576 loadGeoJsonData();
......