blob: 8b37002218ec681f3d964fc5c86b17861c02d3b3 [file] [log] [blame]
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- Topology Toolbar Module.
Simon Hunt09060142015-03-18 20:23:32 -070019 Functions for creating and interacting with the toolbar.
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -070020 */
21
22(function () {
Bri Prebilic Cole54d09382015-03-19 18:40:27 -070023 'use strict';
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -070024
25 // injected references
Simon Hunta211f7f2015-11-09 12:48:23 -080026 var $log, fs, tbs, ps, tov, tds, api;
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -070027
Simon Hunt8d22c4b2015-08-06 16:24:43 -070028 // API:
29 // getActionEntry
30 // setUpKeys
31
Simon Huntcaed0412017-08-12 13:49:17 -070032 // function to be replaced by the localization bundle function
33 var topoLion = function (x) {
34 return '#ttbar#' + x + '#';
35 };
36
Simon Hunt09060142015-03-18 20:23:32 -070037 // internal state
Simon Hunta5b53af2015-10-12 15:56:40 -070038 var toolbar, keyData, cachedState, thirdRow, ovRset, ovIndex;
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -070039
Bri Prebilic Coled6219052015-03-19 14:34:02 -070040 // constants
Simon Huntc7ae7952015-04-08 18:59:27 -070041 var name = 'topo-tbar',
Simon Hunt8d22c4b2015-08-06 16:24:43 -070042 cooktag = 'topo_prefs',
43 soa = 'switchOverlayActions: ',
Simon Huntcaed0412017-08-12 13:49:17 -070044 selOver = '************',
Simon Hunta5b53af2015-10-12 15:56:40 -070045 defaultOverlay = 'traffic';
Simon Hunt8d22c4b2015-08-06 16:24:43 -070046
Bri Prebilic Coled6219052015-03-19 14:34:02 -070047
Simon Hunt09060142015-03-18 20:23:32 -070048 // key to button mapping data
49 var k2b = {
Steven Burrows1c2a9682017-07-14 16:52:46 +010050 O: { id: 'summary-tog', gid: 'm_summary', isel: true },
Simon Huntc217cb92016-08-30 16:17:51 -070051 I: { id: 'instance-tog', gid: 'm_uiAttached', isel: true },
52 D: { id: 'details-tog', gid: 'm_details', isel: true },
53 H: { id: 'hosts-tog', gid: 'm_endstation', isel: false },
54 M: { id: 'offline-tog', gid: 'm_switch', isel: true },
55 P: { id: 'ports-tog', gid: 'm_ports', isel: true },
56 B: { id: 'bkgrnd-tog', gid: 'm_map', isel: false },
57 G: { id: 'bkgrnd-sel', gid: 'm_selectMap' },
58 S: { id: 'sprite-tog', gid: 'm_cloud', isel: false },
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -070059
Simon Huntc217cb92016-08-30 16:17:51 -070060 Z: { id: 'oblique-tog', gid: 'm_oblique', isel: false },
61 N: { id: 'filters-btn', gid: 'm_filters' },
62 L: { id: 'cycleLabels-btn', gid: 'm_cycleLabels' },
63 R: { id: 'resetZoom-btn', gid: 'm_resetZoom' },
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -070064
Steven Burrows1c2a9682017-07-14 16:52:46 +010065 E: { id: 'eqMaster-btn', gid: 'm_eqMaster' },
Simon Hunt09060142015-03-18 20:23:32 -070066 };
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -070067
Simon Hunt8d22c4b2015-08-06 16:24:43 -070068 var prohibited = [
69 'T', 'backSlash', 'slash',
Steven Burrows1c2a9682017-07-14 16:52:46 +010070 'X', // needed until we re-instate X above.
Simon Hunt8d22c4b2015-08-06 16:24:43 -070071 ];
72 prohibited = prohibited.concat(d3.map(k2b).keys());
73
74
Simon Huntc7ae7952015-04-08 18:59:27 -070075 // initial toggle state: default settings and tag to key mapping
76 var defaultPrefsState = {
Simon Huntfcbde892015-04-16 12:05:28 -070077 insts: 1,
Thomas Vachuska0af26912016-03-21 21:37:30 -070078 summary: 1,
Simon Huntc7ae7952015-04-08 18:59:27 -070079 detail: 1,
Simon Huntfcbde892015-04-16 12:05:28 -070080 hosts: 0,
81 offdev: 1,
Thomas Vachuska0af26912016-03-21 21:37:30 -070082 dlbls: 0,
Simon Hunt10618f62017-06-15 19:30:52 -070083 hlbls: 0,
Simon Huntfcbde892015-04-16 12:05:28 -070084 porthl: 1,
Simon Huntd0fe66c2015-06-10 10:16:36 -070085 bg: 0,
Simon Huntfcbde892015-04-16 12:05:28 -070086 spr: 0,
Steven Burrows1c2a9682017-07-14 16:52:46 +010087 ovid: 'traffic', // default to traffic overlay
88 toolbar: 0,
Simon Huntc7ae7952015-04-08 18:59:27 -070089 },
90 prefsMap = {
Simon Huntc7ae7952015-04-08 18:59:27 -070091 summary: 'O',
Simon Huntfcbde892015-04-16 12:05:28 -070092 insts: 'I',
93 detail: 'D',
94 hosts: 'H',
95 offdev: 'M',
96 porthl: 'P',
97 bg: 'B',
Steven Burrows1c2a9682017-07-14 16:52:46 +010098 spr: 'S',
Simon Huntfcbde892015-04-16 12:05:28 -070099 // NOTE: toolbar state is handled separately
Simon Huntc7ae7952015-04-08 18:59:27 -0700100 };
101
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700102 function init(_api_) {
103 api = _api_;
Simon Huntc7ae7952015-04-08 18:59:27 -0700104 // retrieve initial toggle button settings from user prefs
105 setInitToggleState();
106 }
107
108 function topoDefPrefs() {
109 return angular.extend({}, defaultPrefsState);
110 }
111
112 function setInitToggleState() {
Simon Huntfc5c5842017-02-01 23:32:18 -0800113 cachedState = ps.asNumbers(
114 ps.getPrefs(cooktag, defaultPrefsState), ['ovid'], true
115 );
Simon Huntfcbde892015-04-16 12:05:28 -0700116 $log.debug('TOOLBAR---- read prefs state:', cachedState);
Simon Huntc7ae7952015-04-08 18:59:27 -0700117
Simon Huntfcbde892015-04-16 12:05:28 -0700118 if (!cachedState) {
119 cachedState = topoDefPrefs();
120 ps.setPrefs(cooktag, cachedState);
121 $log.debug('TOOLBAR---- Set default prefs state:', cachedState);
Simon Huntc7ae7952015-04-08 18:59:27 -0700122 }
123
124 angular.forEach(prefsMap, function (v, k) {
Simon Huntfcbde892015-04-16 12:05:28 -0700125 var cfg = k2b[v];
126 cfg && (cfg.isel = !!cachedState[k]);
Simon Huntc7ae7952015-04-08 18:59:27 -0700127 });
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700128 }
129
Simon Hunt09060142015-03-18 20:23:32 -0700130 function initKeyData() {
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700131 // TODO: use angular forEach instead of d3.map
Simon Hunt09060142015-03-18 20:23:32 -0700132 keyData = d3.map(k2b);
Steven Burrows1c2a9682017-07-14 16:52:46 +0100133 keyData.forEach(function (key, value) {
Simon Hunte1e968e2017-08-09 19:18:56 -0700134 var data = api.getActionEntry(key),
135 ttfn = data[1]; // tooltip-possibly-a-function
136
Simon Hunt5989ddf2017-08-02 20:38:12 -0700137 value.key = key;
Steven Burrows1c2a9682017-07-14 16:52:46 +0100138 value.cb = data[0]; // on-click callback
Simon Hunte1e968e2017-08-09 19:18:56 -0700139
140 // tooltip function invoked at the time the tooltip is displayed
141 value.tt = function () {
Simon Huntcaed0412017-08-12 13:49:17 -0700142 return fs.isF(ttfn) ? ttfn() : '' + ttfn;
Simon Hunte1e968e2017-08-09 19:18:56 -0700143 };
Simon Hunt09060142015-03-18 20:23:32 -0700144 });
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700145 }
146
Simon Hunt5989ddf2017-08-02 20:38:12 -0700147 // returns a no-args function that returns the tooltip text
148 function deferredText(v) {
149 // this function will get invoked at the time the tooltip is displayed:
150 return function () {
Simon Hunte1e968e2017-08-09 19:18:56 -0700151 return (fs.isF(v.tt) ? v.tt() : v.tt) + ' (' + v.key + ')';
Simon Hunt5989ddf2017-08-02 20:38:12 -0700152 };
153 }
154
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700155 function addButton(key) {
156 var v = keyData.get(key);
Simon Hunt5989ddf2017-08-02 20:38:12 -0700157 v.btn = toolbar.addButton(v.id, v.gid, v.cb, deferredText(v));
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700158 }
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700159
Bri Prebilic Coled8745462015-06-01 16:08:57 -0700160 function addToggle(key, suppressIfMobile) {
Simon Hunt09060142015-03-18 20:23:32 -0700161 var v = keyData.get(key);
Bri Prebilic Coled8745462015-06-01 16:08:57 -0700162 if (suppressIfMobile && fs.isMobile()) { return; }
Simon Hunt5989ddf2017-08-02 20:38:12 -0700163 v.tog = toolbar.addToggle(v.id, v.gid, v.isel, v.cb, deferredText(v));
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700164 }
165
Bri Prebilic Cole04b41402015-03-18 17:25:34 -0700166 function addFirstRow() {
Simon Hunt09060142015-03-18 20:23:32 -0700167 addToggle('I');
Simon Huntda2f3cc2015-03-19 15:11:57 -0700168 addToggle('O');
Simon Hunt09060142015-03-18 20:23:32 -0700169 addToggle('D');
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700170 toolbar.addSeparator();
171
Simon Hunt09060142015-03-18 20:23:32 -0700172 addToggle('H');
173 addToggle('M');
Bri Prebilic Coled8745462015-06-01 16:08:57 -0700174 addToggle('P', true);
Simon Hunt09060142015-03-18 20:23:32 -0700175 addToggle('B');
Thomas Vachuska26be4f32016-03-31 01:10:27 -0700176 addButton('G');
Bri Prebilic Coled8745462015-06-01 16:08:57 -0700177 addToggle('S', true);
Bri Prebilic Cole04b41402015-03-18 17:25:34 -0700178 }
Simon Hunt72e44bf2015-07-21 21:34:20 -0700179
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700180 function addSecondRow() {
Steven Burrows1c2a9682017-07-14 16:52:46 +0100181 // addToggle('X');
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700182 addToggle('Z');
Bri Prebilic Coleb5f2b152015-04-07 14:58:09 -0700183 addButton('N');
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700184 addButton('L');
185 addButton('R');
Simon Hunt72e44bf2015-07-21 21:34:20 -0700186 toolbar.addSeparator();
187 addButton('E');
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700188 }
Simon Hunt72e44bf2015-07-21 21:34:20 -0700189
Simon Hunt72e44bf2015-07-21 21:34:20 -0700190 function addOverlays() {
191 toolbar.addSeparator();
192
193 // generate radio button set for overlays; start with 'none'
194 var rset = [{
Simon Huntc217cb92016-08-30 16:17:51 -0700195 gid: 'm_unknown',
Simon Huntcaed0412017-08-12 13:49:17 -0700196 tooltip: topoLion('ov_tt_none'),
Simon Hunte05cae42015-07-23 17:35:24 -0700197 cb: function () {
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700198 tov.tbSelection(null, switchOverlayActions);
Steven Burrows1c2a9682017-07-14 16:52:46 +0100199 },
Simon Hunt72e44bf2015-07-21 21:34:20 -0700200 }];
Simon Hunta5b53af2015-10-12 15:56:40 -0700201 ovIndex = tov.augmentRbset(rset, switchOverlayActions);
202 ovRset = toolbar.addRadioSet('topo-overlays', rset);
Simon Hunt72e44bf2015-07-21 21:34:20 -0700203 }
204
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700205 // invoked by overlay service to switch out old buttons and switch in new
206 function switchOverlayActions(oid, keyBindings) {
207 var prohibits = [],
208 kb = fs.isO(keyBindings) || {},
209 order = fs.isA(kb._keyOrder) || [];
210
211 if (keyBindings && !keyBindings._keyOrder) {
212 $log.warn(soa + 'no _keyOrder property defined');
213 } else {
214 // sanity removal of reserved property names
215 ['esc', '_keyListener', '_helpFormat'].forEach(function (k) {
216 fs.removeFromArray(k, order);
217 });
218 }
219
Simon Hunta211f7f2015-11-09 12:48:23 -0800220 // ensure dialog has closed (if opened by outgoing overlay)
221 tds.closeDialog();
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700222 thirdRow.clear();
223
Simon Hunt5ab45e12016-07-07 15:29:52 -0700224 // persist our choice of overlay...
Simon Huntfc5c5842017-02-01 23:32:18 -0800225 persistTopoPrefs('ovid', oid);
Simon Hunt5ab45e12016-07-07 15:29:52 -0700226
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700227 if (!order.length) {
228 thirdRow.setText(selOver);
229 thirdRow.classed('right', true);
230 api.setUpKeys(); // clear previous overlay key bindings
231
232 } else {
233 thirdRow.classed('right', false);
234 angular.forEach(order, function (key) {
235 var value, bid, gid, tt;
236
237 if (prohibited.indexOf(key) > -1) {
238 prohibits.push(key);
239
240 } else {
241 value = keyBindings[key];
242 bid = oid + '-' + key;
243 gid = tov.mkGlyphId(oid, value.gid);
Simon Huntcaed0412017-08-12 13:49:17 -0700244 tt = function () {
245 var ttfn = value.tt,
246 txt = fs.isF(ttfn) ? ttfn() : ttfn;
247 return txt + ' (' + key + ')';
248 };
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700249 thirdRow.addButton(bid, gid, value.cb, tt);
250 }
251 });
252 api.setUpKeys(keyBindings); // add overlay key bindings
253 }
254
255 if (prohibits.length) {
256 $log.warn(soa + 'Prohibited key bindings ignored:', prohibits);
257 }
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700258 }
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700259
Bri Prebilic Cole04b41402015-03-18 17:25:34 -0700260 function createToolbar() {
Simon Hunt09060142015-03-18 20:23:32 -0700261 initKeyData();
Bri Prebilic Coled6219052015-03-19 14:34:02 -0700262 toolbar = tbs.createToolbar(name);
Bri Prebilic Cole04b41402015-03-18 17:25:34 -0700263 addFirstRow();
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700264 toolbar.addRow();
265 addSecondRow();
Simon Hunt72e44bf2015-07-21 21:34:20 -0700266 addOverlays();
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700267 thirdRow = toolbar.addRow();
268 thirdRow.setText(selOver);
269 thirdRow.classed('right', true);
Simon Hunt72e44bf2015-07-21 21:34:20 -0700270
Simon Huntfcbde892015-04-16 12:05:28 -0700271 if (cachedState.toolbar) {
272 toolbar.show();
273 } else {
274 toolbar.hide();
275 }
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700276 }
277
Bri Prebilic Coled6219052015-03-19 14:34:02 -0700278 function destroyToolbar() {
279 tbs.destroyToolbar(name);
Simon Hunt4a6b54b2015-10-27 22:08:25 -0700280 tov.resetOnToolbarDestroy();
Bri Prebilic Coled6219052015-03-19 14:34:02 -0700281 }
282
Simon Hunt09060142015-03-18 20:23:32 -0700283 // allows us to ensure the button states track key strokes
284 function keyListener(key) {
285 var v = keyData.get(key);
286
287 if (v) {
288 // we have a valid button mapping
289 if (v.tog) {
290 // it's a toggle button
291 v.tog.toggleNoCb();
292 }
293 }
294 }
295
Simon Hunt5ab45e12016-07-07 15:29:52 -0700296 function persistTopoPrefs(key, val) {
Thomas Vachuska0af26912016-03-21 21:37:30 -0700297 var prefs = ps.getPrefs(cooktag, defaultPrefsState);
Simon Hunt5ab45e12016-07-07 15:29:52 -0700298 prefs[key] = val === undefined ? !prefs[key] : val;
Thomas Vachuska0af26912016-03-21 21:37:30 -0700299 ps.setPrefs('topo_prefs', prefs);
Simon Hunt90dcc3e2015-03-25 15:01:27 -0700300 }
301
Simon Hunt5ab45e12016-07-07 15:29:52 -0700302 function toggleToolbar() {
303 toolbar.toggle();
304 persistTopoPrefs('toolbar');
305 }
Simon Hunt10618f62017-06-15 19:30:52 -0700306
Simon Huntfc5c5842017-02-01 23:32:18 -0800307 function selectOverlay(ovid) {
308 var idx = ovIndex[defaultOverlay] || 0,
309 pidx = (ovid === null) ? 0 : ovIndex[ovid] || -1;
310 if (pidx >= 0 && pidx < ovRset.size()) {
311 idx = pidx;
Simon Hunt5ab45e12016-07-07 15:29:52 -0700312 }
Simon Hunta5b53af2015-10-12 15:56:40 -0700313 ovRset.selectedIndex(idx);
314 }
315
Simon Hunt5b024d72016-01-29 11:02:43 -0800316 // an overlay was selected via Function-Key press
317 function fnkey(idx) {
318 if (idx < ovRset.size() && idx !== ovRset.selectedIndex()) {
319 ovRset.selectedIndex(idx);
320 }
321 }
322
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700323 angular.module('ovTopo')
Simon Huntc7ae7952015-04-08 18:59:27 -0700324 .factory('TopoToolbarService',
Bri Prebilic Coled8745462015-06-01 16:08:57 -0700325 ['$log', 'FnService', 'ToolbarService', 'PrefsService',
Simon Hunta211f7f2015-11-09 12:48:23 -0800326 'TopoOverlayService', 'TopoDialogService',
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700327
Simon Hunta211f7f2015-11-09 12:48:23 -0800328 function (_$log_, _fs_, _tbs_, _ps_, _tov_, _tds_) {
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700329 $log = _$log_;
Bri Prebilic Coled8745462015-06-01 16:08:57 -0700330 fs = _fs_;
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700331 tbs = _tbs_;
Simon Huntc7ae7952015-04-08 18:59:27 -0700332 ps = _ps_;
Simon Hunt72e44bf2015-07-21 21:34:20 -0700333 tov = _tov_;
Simon Hunta211f7f2015-11-09 12:48:23 -0800334 tds = _tds_;
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700335
336 return {
337 init: init,
Simon Hunt09060142015-03-18 20:23:32 -0700338 createToolbar: createToolbar,
Bri Prebilic Coled6219052015-03-19 14:34:02 -0700339 destroyToolbar: destroyToolbar,
Simon Hunt90dcc3e2015-03-25 15:01:27 -0700340 keyListener: keyListener,
Simon Hunta5b53af2015-10-12 15:56:40 -0700341 toggleToolbar: toggleToolbar,
Simon Huntfc5c5842017-02-01 23:32:18 -0800342 selectOverlay: selectOverlay,
Thomas Vachuska0af26912016-03-21 21:37:30 -0700343 defaultPrefs: defaultPrefsState,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100344 fnkey: fnkey,
Simon Huntcaed0412017-08-12 13:49:17 -0700345 setLionBundle: function (bundle) { topoLion = bundle; },
Bri Prebilic Cole4db8dce2015-03-18 13:57:24 -0700346 };
347 }]);
Steven Burrows1c2a9682017-07-14 16:52:46 +0100348}());