blob: 721f60410368ec58f92aef87c132b2779076201f [file] [log] [blame]
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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 -- Button Service
19 */
20(function () {
21 'use strict';
22
Simon Hunt69252862015-02-26 11:26:08 -080023 // injected refs
Bri Prebilic Cole9a5e0062015-05-11 17:20:57 -070024 var $log, $rootScope, fs, is, tts;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080025
Simon Hunt69252862015-02-26 11:26:08 -080026 // configuration
Bri Prebilic Cole258f0462015-02-25 14:48:50 -080027 var btnSize = 25,
28 btnPadding = 4;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080029
Simon Hunt85fa2b82015-02-26 14:33:23 -080030
31 // === Helper Functions
32
33 function divExists(div, msg) {
34 if (!div) {
35 $log.warn('div undefined (' + msg + ')');
36 }
37 return !!div;
38 }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080039
40 function createDiv(div, cls, id) {
41 return div.append('div')
42 .classed(cls, true)
43 .attr('id', id);
44 }
45
Simon Hunt85fa2b82015-02-26 14:33:23 -080046 function noop() {}
47
48 function buttonWidth() {
49 return btnSize + 2 * btnPadding;
50 }
51
Bri Prebilic Cole54d09382015-03-19 18:40:27 -070052 function addTooltip(elem, tooltip) {
53 elem.on('mouseover', function () { tts.showTooltip(this, tooltip); });
54 elem.on('mouseout', function () { tts.cancelTooltip(this); });
Bri Prebilic Cole9a5e0062015-05-11 17:20:57 -070055 $rootScope.$on('$routeChangeStart', function () {
56 tts.cancelTooltip(elem.node());
57 });
Bri Prebilic Cole54d09382015-03-19 18:40:27 -070058 }
59
Simon Hunt85fa2b82015-02-26 14:33:23 -080060
61 // === BUTTON =================================================
62
63 // div is where to put the button (d3.selection of a DIV element)
64 // id should be globally unique
65 // gid is glyph ID (from Glyph Service)
66 // cb is callback function on click
67 // tooltip is text for tooltip
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080068 function button(div, id, gid, cb, tooltip) {
Simon Hunt85fa2b82015-02-26 14:33:23 -080069 if (!divExists(div, 'button')) return null;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080070
Bri Prebilic Colef7280d02015-02-24 16:20:47 -080071 var btnDiv = createDiv(div, 'button', id),
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080072 cbFnc = fs.isF(cb) || noop;
73
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080074 is.loadIcon(btnDiv, gid, btnSize, true);
Bri Prebilic Cole54d09382015-03-19 18:40:27 -070075 if (tooltip) { addTooltip(btnDiv, tooltip); }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080076
77 btnDiv.on('click', cbFnc);
78
79 return {
80 id: id,
Simon Hunt85fa2b82015-02-26 14:33:23 -080081 width: buttonWidth
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080082 }
83 }
84
Simon Hunt85fa2b82015-02-26 14:33:23 -080085
86 // === TOGGLE BUTTON ==========================================
87
88 // div is where to put the button (d3.selection of a DIV element)
89 // id should be globally unique
90 // gid is glyph ID (from Glyph Service)
91 // initState is whether the toggle is on or not to begin
92 // cb is callback function on click
93 // tooltip is text for tooltip
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -080094 function toggle(div, id, gid, initState, cb, tooltip) {
Simon Hunt85fa2b82015-02-26 14:33:23 -080095 if (!divExists(div, 'toggle button')) return null;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080096
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -080097 var sel = !!initState,
Bri Prebilic Colef7280d02015-02-24 16:20:47 -080098 togDiv = createDiv(div, 'toggleButton', id),
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080099 cbFnc = fs.isF(cb) || noop;
100
Bri Prebilic Cole5000a752015-02-23 17:20:53 -0800101 is.loadIcon(togDiv, gid, btnSize, true);
Bri Prebilic Colef7280d02015-02-24 16:20:47 -0800102 togDiv.classed('selected', sel);
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700103 if (tooltip) { addTooltip(togDiv, tooltip); }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800104
Simon Hunt09060142015-03-18 20:23:32 -0700105 function _toggle(b, nocb) {
Simon Hunt85fa2b82015-02-26 14:33:23 -0800106 sel = (b === undefined) ? !sel : !!b;
Bri Prebilic Colef7280d02015-02-24 16:20:47 -0800107 togDiv.classed('selected', sel);
Simon Hunt09060142015-03-18 20:23:32 -0700108 nocb || cbFnc(sel);
109 }
110
111 // toggle the button state without invoking the callback
112 function toggleNoCb() {
113 _toggle(undefined, true);
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800114 }
115
116 togDiv.on('click', _toggle);
117
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800118 return {
119 id: id,
Simon Hunt85fa2b82015-02-26 14:33:23 -0800120 width: buttonWidth,
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800121 selected: function () { return sel; },
Simon Hunt09060142015-03-18 20:23:32 -0700122 toggle: _toggle,
123 toggleNoCb: toggleNoCb
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800124 }
125 }
126
Simon Hunt85fa2b82015-02-26 14:33:23 -0800127
128 // === RADIO BUTTON SET =======================================
129
130
131 // div is where to put the button (d3.selection of a DIV element)
132 // id should be globally unique
133 // rset is an array of button descriptors of the following form:
134 // {
135 // gid: glyphId,
136 // tooltip: tooltipText,
137 // cb: callbackFunction
138 // }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800139 function radioSet(div, id, rset) {
Simon Hunt85fa2b82015-02-26 14:33:23 -0800140 if (!divExists(div, 'radio button set')) return null;
141
142 if (!fs.isA(rset) || !rset.length) {
143 $log.warn('invalid array (radio button set)');
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800144 return null;
145 }
Simon Hunt85fa2b82015-02-26 14:33:23 -0800146
147 var rDiv = createDiv(div, 'radioSet', id),
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800148 rads = [],
Simon Hunt85fa2b82015-02-26 14:33:23 -0800149 idxByKey = {},
150 currIdx = 0;
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800151
Simon Hunt85fa2b82015-02-26 14:33:23 -0800152 function rsetWidth() {
153 return ((btnSize + btnPadding) * rads.length) + btnPadding;
154 }
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800155
Simon Hunt85fa2b82015-02-26 14:33:23 -0800156 function rbclick() {
157 var id = d3.select(this).attr('id'),
158 m = /^.*-(\d+)$/.exec(id),
159 idx = Number(m[1]);
160
161 if (idx !== currIdx) {
162 rads[currIdx].el.classed('selected', false);
163 currIdx = idx;
164 rads[currIdx].el.classed('selected', true);
165 invokeCurrent();
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800166 }
167 }
168
Simon Hunt85fa2b82015-02-26 14:33:23 -0800169 // {
170 // gid: gid,
171 // tooltip: ..., (optional)
172 // key: ..., (optional)
173 // cb: cb
174 // id: ... (added by us)
175 // index: ... (added by us)
176 // }
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800177
178 rset.forEach(function (btn, index) {
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800179
Simon Hunt85fa2b82015-02-26 14:33:23 -0800180 if (!fs.isO(btn)) {
181 $log.warn('radio button descriptor at index ' + index +
182 ' not an object');
183 return;
184 }
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800185
Simon Hunt85fa2b82015-02-26 14:33:23 -0800186 var rid = id + '-' + index,
187 initSel = (index === 0),
188 rbdiv = createDiv(rDiv, 'radioButton', rid);
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800189
Simon Hunt85fa2b82015-02-26 14:33:23 -0800190 rbdiv.classed('selected', initSel);
191 rbdiv.on('click', rbclick);
192 is.loadIcon(rbdiv, btn.gid, btnSize, true);
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700193 if (btn.tooltip) { addTooltip(rbdiv, btn.tooltip); }
Simon Hunt85fa2b82015-02-26 14:33:23 -0800194 angular.extend(btn, {
195 el: rbdiv,
196 id: rid,
197 cb: fs.isF(btn.cb) || noop,
198 index: index
199 });
200
201 if (btn.key) {
202 idxByKey[btn.key] = index;
203 }
204
205 rads.push(btn);
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800206 });
Simon Hunt85fa2b82015-02-26 14:33:23 -0800207
208
209 function invokeCurrent() {
210 var curr = rads[currIdx];
211 curr.cb(curr.index, curr.key);
212 }
213
214 function selected(x) {
215 var curr = rads[currIdx],
216 idx;
217
218 if (x === undefined) {
219 return curr.key || curr.index;
220 } else {
221 idx = idxByKey[x];
222 if (idx === undefined) {
Bri Prebilic Cole18489172015-02-27 17:12:00 -0800223 $log.warn('no radio button with key:', x);
Simon Hunt85fa2b82015-02-26 14:33:23 -0800224 } else {
225 selectedIndex(idx);
226 }
227 }
228 }
229
230 function selectedIndex(x) {
231 if (x === undefined) {
232 return currIdx;
233 } else {
234 if (x >= 0 && x < rads.length) {
Bri Prebilic Cole18489172015-02-27 17:12:00 -0800235 if (currIdx !== x) {
236 currIdx = x;
237 invokeCurrent();
238 } else {
239 $log.warn('current index already selected:', x);
240 }
Simon Hunt85fa2b82015-02-26 14:33:23 -0800241 } else {
Bri Prebilic Cole18489172015-02-27 17:12:00 -0800242 $log.warn('invalid radio button index:', x);
Simon Hunt85fa2b82015-02-26 14:33:23 -0800243 }
244 }
245 }
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800246
247 return {
Simon Hunt85fa2b82015-02-26 14:33:23 -0800248 width: rsetWidth,
249 selected: selected,
250 selectedIndex: selectedIndex
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800251 }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800252 }
253
Bri Prebilic Cole258f0462015-02-25 14:48:50 -0800254
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800255 angular.module('onosWidget')
Simon Hunt69252862015-02-26 11:26:08 -0800256 .factory('ButtonService',
Bri Prebilic Cole9a5e0062015-05-11 17:20:57 -0700257 ['$log', '$rootScope', 'FnService', 'IconService', 'TooltipService',
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800258
Bri Prebilic Cole9a5e0062015-05-11 17:20:57 -0700259 function (_$log_, _$rootScope_, _fs_, _is_, _tts_) {
Simon Hunt69252862015-02-26 11:26:08 -0800260 $log = _$log_;
Bri Prebilic Cole9a5e0062015-05-11 17:20:57 -0700261 $rootScope = _$rootScope_;
Simon Hunt69252862015-02-26 11:26:08 -0800262 fs = _fs_;
263 is = _is_;
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700264 tts = _tts_;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800265
Simon Hunt69252862015-02-26 11:26:08 -0800266 return {
267 button: button,
268 toggle: toggle,
Simon Hunt85fa2b82015-02-26 14:33:23 -0800269 radioSet: radioSet
Simon Hunt69252862015-02-26 11:26:08 -0800270 };
271 }]);
272
273}());