blob: b765208cbf9c8ed298efc067e392c442f45edcd1 [file] [log] [blame]
Bri Prebilic Cole2e3f8562015-02-17 17:21:31 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Bri Prebilic Cole2e3f8562015-02-17 17:21:31 -08003 *
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 -- Widget -- Toolbar Service
19 */
Simon Huntdf510012015-02-26 16:34:37 -080020// TODO: Augment service to allow toolbars to exist on right edge of screen
Simon Hunt8d22c4b2015-08-06 16:24:43 -070021// TODO: also - make toolbar more object aware (rows etc.)
Simon Huntdf510012015-02-26 16:34:37 -080022
23
Bri Prebilic Cole2e3f8562015-02-17 17:21:31 -080024(function () {
25 'use strict';
26
Simon Huntdf510012015-02-26 16:34:37 -080027 // injected refs
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080028 var $log, fs, ps, bns, is;
Bri Prebilic Cole2e3f8562015-02-17 17:21:31 -080029
Simon Huntdf510012015-02-26 16:34:37 -080030 // configuration
31 var arrowSize = 10,
32 sepWidth = 6,
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080033 defaultSettings = {
34 edge: 'left',
Bri Prebilic Cole258f0462015-02-25 14:48:50 -080035 width: 20,
Bri Prebilic Colebe8b9a42015-02-24 12:12:00 -080036 margin: 0,
37 hideMargin: -20,
Bri Prebilic Coled8745462015-06-01 16:08:57 -070038 top: 'auto',
39 bottom: '10px',
Bri Prebilic Cole258f0462015-02-25 14:48:50 -080040 fade: false,
41 shown: false
Simon Huntdf510012015-02-26 16:34:37 -080042 };
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -080043
Simon Huntdf510012015-02-26 16:34:37 -080044 // internal state
45 var tbars = {};
46
Bri Prebilic Cole751804e2015-02-18 15:44:28 -080047
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080048 // === Helper functions --------------------------------------
49
Bri Prebilic Colebe8b9a42015-02-24 12:12:00 -080050 // translate uses 50 because the svg viewbox is 50
Simon Huntdf510012015-02-26 16:34:37 -080051 function rotateArrowLeft(adiv) {
52 adiv.select('g')
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080053 .attr('transform', 'translate(0 50) rotate(-90)');
54 }
Simon Huntdf510012015-02-26 16:34:37 -080055 function rotateArrowRight(adiv) {
56 adiv.select('g')
Bri Prebilic Colebe8b9a42015-02-24 12:12:00 -080057 .attr('transform', 'translate(50 0) rotate(90)');
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080058 }
Simon Huntdf510012015-02-26 16:34:37 -080059
60 function createArrow(panel) {
61 var arrowDiv = panel.append('div')
Bri Prebilic Coledd805572015-08-04 16:54:08 -070062 .classed('tbar-arrow', true);
Simon Huntdf510012015-02-26 16:34:37 -080063 is.loadIcon(arrowDiv, 'triangleUp', arrowSize, true);
64 return arrowDiv;
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080065 }
66
Simon Huntdf510012015-02-26 16:34:37 -080067 function warn(msg, id) {
68 $log.warn('createToolbar: ' + msg + ': [' + id + ']');
69 return null;
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -080070 }
71
Simon Huntdf510012015-02-26 16:34:37 -080072 // ==================================
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080073
74 function createToolbar(id, opts) {
Simon Huntd3bcef32015-02-27 18:36:42 -080075 if (!id) return warn('no ID given');
Simon Huntdf510012015-02-26 16:34:37 -080076 if (tbars[id]) return warn('duplicate ID given', id);
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -080077
Simon Huntdf510012015-02-26 16:34:37 -080078 var settings = angular.extend({}, defaultSettings, fs.isO(opts)),
Simon Huntd3bcef32015-02-27 18:36:42 -080079 items = {},
Simon Huntdf510012015-02-26 16:34:37 -080080 tbid = 'toolbar-' + id,
81 panel = ps.createPanel(tbid, settings),
82 arrowDiv = createArrow(panel),
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -070083 currentRow = panel.append('div').classed('tbar-row', true),
Simon Hunt8d22c4b2015-08-06 16:24:43 -070084 rowButtonIds = [], // for removable buttons
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -070085 tbWidth = arrowSize + 2, // empty toolbar width
86 maxWidth = panel.width();
Simon Huntdf510012015-02-26 16:34:37 -080087
88 arrowDiv.on('click', toggle);
89
90 // add a descriptor for this toolbar
91 tbars[id] = {
92 settings: settings,
Simon Huntd3bcef32015-02-27 18:36:42 -080093 items: items,
Simon Huntdf510012015-02-26 16:34:37 -080094 panel: panel,
95 panelId: tbid
96 };
97
98 panel.classed('toolbar', true)
Bri Prebilic Coled8745462015-06-01 16:08:57 -070099 .style('top', settings.top)
100 .style('bottom', settings.bottom);
Bri Prebilic Cole5000a752015-02-23 17:20:53 -0800101
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700102 // Helper functions
Simon Huntdf510012015-02-26 16:34:37 -0800103
Simon Huntd3bcef32015-02-27 18:36:42 -0800104 function dupId(id, caller) {
105 if (items[id]) {
106 $log.warn(caller + ': duplicate ID:', id);
107 return true;
108 }
109 return false;
110 }
111
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700112 function adjustWidth(btnWidth) {
Simon Hunta9761342016-06-10 18:02:53 -0700113 // 0.1 fudge for rounding error
114 if (fs.noPxStyle(currentRow, 'width') + 0.1 >= maxWidth) {
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700115 tbWidth += btnWidth;
116 maxWidth = tbWidth;
117 }
118 panel.width(tbWidth);
119 }
120
Simon Huntdf510012015-02-26 16:34:37 -0800121 // API functions
122
123 function addButton(id, gid, cb, tooltip) {
Simon Huntd3bcef32015-02-27 18:36:42 -0800124 if (dupId(id, 'addButton')) return null;
125
Simon Huntdf510012015-02-26 16:34:37 -0800126 var bid = tbid + '-' + id,
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700127 btn = bns.button(currentRow, bid, gid, cb, tooltip);
Simon Huntd3bcef32015-02-27 18:36:42 -0800128
129 items[id] = btn;
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700130 adjustWidth(btn.width());
Simon Huntdf510012015-02-26 16:34:37 -0800131 return btn;
132 }
133
134 function addToggle(id, gid, initState, cb, tooltip) {
Simon Huntd3bcef32015-02-27 18:36:42 -0800135 if (dupId(id, 'addToggle')) return null;
136
Simon Huntdf510012015-02-26 16:34:37 -0800137 var tid = tbid + '-' + id,
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700138 tog = bns.toggle(currentRow, tid, gid, initState, cb, tooltip);
Simon Huntd3bcef32015-02-27 18:36:42 -0800139
140 items[id] = tog;
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700141 adjustWidth(tog.width());
Simon Huntdf510012015-02-26 16:34:37 -0800142 return tog;
143 }
144
145 function addRadioSet(id, rset) {
Simon Huntd3bcef32015-02-27 18:36:42 -0800146 if (dupId(id, 'addRadioSet')) return null;
147
Simon Huntdf510012015-02-26 16:34:37 -0800148 var rid = tbid + '-' + id,
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700149 rad = bns.radioSet(currentRow, rid, rset);
Simon Huntd3bcef32015-02-27 18:36:42 -0800150
151 items[id] = rad;
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700152 adjustWidth(rad.width());
Simon Huntdf510012015-02-26 16:34:37 -0800153 return rad;
154 }
155
156 function addSeparator() {
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700157 currentRow.append('div')
Simon Huntdf510012015-02-26 16:34:37 -0800158 .classed('separator', true);
159 tbWidth += sepWidth;
160 }
161
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700162 function addRow() {
Bri Prebilic Coledb4b87b2015-03-25 09:18:42 -0700163 if (currentRow.select('div').empty()) {
164 return null;
165 } else {
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700166 panel.append('br');
167 currentRow = panel.append('div').classed('tbar-row', true);
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700168
169 // return API to allow caller more access to the row
170 return {
171 clear: rowClear,
172 setText: rowSetText,
173 addButton: rowAddButton,
174 classed: rowClassed
175 };
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700176 }
177 }
178
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700179 function rowClear() {
180 currentRow.selectAll('*').remove();
181 rowButtonIds.forEach(function (bid) {
182 delete items[bid];
183 });
184 rowButtonIds = [];
185 }
186
187 // installs a div with text into the button row
188 function rowSetText(text) {
189 rowClear();
190 currentRow.append('div').classed('tbar-row-text', true)
Simon Hunt239f09e2017-05-18 13:10:09 -0700191 .text(text);
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700192 }
193
194 function rowAddButton(id, gid, cb, tooltip) {
195 var b = addButton(id, gid, cb, tooltip);
196 if (b) {
197 rowButtonIds.push(id);
198 }
199 }
200
201 function rowClassed(classes, bool) {
202 currentRow.classed(classes, bool);
203 }
204
Simon Huntdf510012015-02-26 16:34:37 -0800205 function show(cb) {
206 rotateArrowLeft(arrowDiv);
207 panel.show(cb);
208 }
209
210 function hide(cb) {
211 rotateArrowRight(arrowDiv);
212 panel.hide(cb);
213 }
214
215 function toggle(cb) {
216 if (panel.isVisible()) {
217 hide(cb);
218 } else {
219 show(cb);
220 }
221 }
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800222
Thomas Vachuska0af26912016-03-21 21:37:30 -0700223 function isVisible() {
224 return panel.isVisible();
225 }
226
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800227 return {
Bri Prebilic Colec4403322015-02-23 10:29:22 -0800228 addButton: addButton,
229 addToggle: addToggle,
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800230 addRadioSet: addRadioSet,
Bri Prebilic Cole5000a752015-02-23 17:20:53 -0800231 addSeparator: addSeparator,
Bri Prebilic Cole812f6c02015-03-24 17:10:33 -0700232 addRow: addRow,
Bri Prebilic Cole5000a752015-02-23 17:20:53 -0800233
234 show: show,
235 hide: hide,
Thomas Vachuska0af26912016-03-21 21:37:30 -0700236 toggle: toggle,
237 isVisible: isVisible
Simon Huntdf510012015-02-26 16:34:37 -0800238 };
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800239 }
Simon Hunt69252862015-02-26 11:26:08 -0800240
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800241 function destroyToolbar(id) {
Simon Huntdf510012015-02-26 16:34:37 -0800242 var tb = tbars[id];
243 delete tbars[id];
Bri Prebilic Cole5000a752015-02-23 17:20:53 -0800244
Simon Huntdf510012015-02-26 16:34:37 -0800245 if (tb) {
246 ps.destroyPanel(tb.panelId);
Bri Prebilic Cole258f0462015-02-25 14:48:50 -0800247 }
248 }
Bri Prebilic Cole2e3f8562015-02-17 17:21:31 -0800249
Simon Huntdf510012015-02-26 16:34:37 -0800250 // === Module Definition ===
251
Bri Prebilic Cole2e3f8562015-02-17 17:21:31 -0800252 angular.module('onosWidget')
Simon Hunt69252862015-02-26 11:26:08 -0800253 .factory('ToolbarService',
254 ['$log', 'FnService', 'PanelService', 'ButtonService', 'IconService',
Bri Prebilic Cole2e3f8562015-02-17 17:21:31 -0800255
Simon Hunt69252862015-02-26 11:26:08 -0800256 function (_$log_, _fs_, _ps_, _bns_, _is_) {
257 $log = _$log_;
258 fs = _fs_;
259 ps = _ps_;
260 bns = _bns_;
261 is = _is_;
262
Simon Huntdf510012015-02-26 16:34:37 -0800263 // this function is only used in testing
264 function init() {
265 tbars = {};
266 }
267
Simon Hunt69252862015-02-26 11:26:08 -0800268 return {
269 init: init,
270 createToolbar: createToolbar,
271 destroyToolbar: destroyToolbar
272 };
273 }]);
Bri Prebilic Colec4403322015-02-23 10:29:22 -0800274}());