blob: 0f97fdd252d5d2e97a2e10dd53a7e75d8948393d [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 Cole54d09382015-03-19 18:40:27 -070024 var $log, 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); });
55 }
56
Simon Hunt85fa2b82015-02-26 14:33:23 -080057
58 // === BUTTON =================================================
59
60 // div is where to put the button (d3.selection of a DIV element)
61 // id should be globally unique
62 // gid is glyph ID (from Glyph Service)
63 // cb is callback function on click
64 // tooltip is text for tooltip
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080065 function button(div, id, gid, cb, tooltip) {
Simon Hunt85fa2b82015-02-26 14:33:23 -080066 if (!divExists(div, 'button')) return null;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080067
Bri Prebilic Colef7280d02015-02-24 16:20:47 -080068 var btnDiv = createDiv(div, 'button', id),
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080069 cbFnc = fs.isF(cb) || noop;
70
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080071 is.loadIcon(btnDiv, gid, btnSize, true);
Bri Prebilic Cole54d09382015-03-19 18:40:27 -070072 if (tooltip) { addTooltip(btnDiv, tooltip); }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080073
74 btnDiv.on('click', cbFnc);
75
76 return {
77 id: id,
Simon Hunt85fa2b82015-02-26 14:33:23 -080078 width: buttonWidth
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080079 }
80 }
81
Simon Hunt85fa2b82015-02-26 14:33:23 -080082
83 // === TOGGLE BUTTON ==========================================
84
85 // div is where to put the button (d3.selection of a DIV element)
86 // id should be globally unique
87 // gid is glyph ID (from Glyph Service)
88 // initState is whether the toggle is on or not to begin
89 // cb is callback function on click
90 // tooltip is text for tooltip
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -080091 function toggle(div, id, gid, initState, cb, tooltip) {
Simon Hunt85fa2b82015-02-26 14:33:23 -080092 if (!divExists(div, 'toggle button')) return null;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080093
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -080094 var sel = !!initState,
Bri Prebilic Colef7280d02015-02-24 16:20:47 -080095 togDiv = createDiv(div, 'toggleButton', id),
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -080096 cbFnc = fs.isF(cb) || noop;
97
Bri Prebilic Cole5000a752015-02-23 17:20:53 -080098 is.loadIcon(togDiv, gid, btnSize, true);
Bri Prebilic Colef7280d02015-02-24 16:20:47 -080099 togDiv.classed('selected', sel);
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700100 if (tooltip) { addTooltip(togDiv, tooltip); }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800101
Simon Hunt09060142015-03-18 20:23:32 -0700102 function _toggle(b, nocb) {
Simon Hunt85fa2b82015-02-26 14:33:23 -0800103 sel = (b === undefined) ? !sel : !!b;
Bri Prebilic Colef7280d02015-02-24 16:20:47 -0800104 togDiv.classed('selected', sel);
Simon Hunt09060142015-03-18 20:23:32 -0700105 nocb || cbFnc(sel);
106 }
107
108 // toggle the button state without invoking the callback
109 function toggleNoCb() {
110 _toggle(undefined, true);
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800111 }
112
113 togDiv.on('click', _toggle);
114
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800115 return {
116 id: id,
Simon Hunt85fa2b82015-02-26 14:33:23 -0800117 width: buttonWidth,
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800118 selected: function () { return sel; },
Simon Hunt09060142015-03-18 20:23:32 -0700119 toggle: _toggle,
120 toggleNoCb: toggleNoCb
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800121 }
122 }
123
Simon Hunt85fa2b82015-02-26 14:33:23 -0800124
125 // === RADIO BUTTON SET =======================================
126
127
128 // div is where to put the button (d3.selection of a DIV element)
129 // id should be globally unique
130 // rset is an array of button descriptors of the following form:
131 // {
132 // gid: glyphId,
133 // tooltip: tooltipText,
134 // cb: callbackFunction
135 // }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800136 function radioSet(div, id, rset) {
Simon Hunt85fa2b82015-02-26 14:33:23 -0800137 if (!divExists(div, 'radio button set')) return null;
138
139 if (!fs.isA(rset) || !rset.length) {
140 $log.warn('invalid array (radio button set)');
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800141 return null;
142 }
Simon Hunt85fa2b82015-02-26 14:33:23 -0800143
144 var rDiv = createDiv(div, 'radioSet', id),
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800145 rads = [],
Simon Hunt85fa2b82015-02-26 14:33:23 -0800146 idxByKey = {},
147 currIdx = 0;
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800148
Simon Hunt85fa2b82015-02-26 14:33:23 -0800149 function rsetWidth() {
150 return ((btnSize + btnPadding) * rads.length) + btnPadding;
151 }
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800152
Simon Hunt85fa2b82015-02-26 14:33:23 -0800153 function rbclick() {
154 var id = d3.select(this).attr('id'),
155 m = /^.*-(\d+)$/.exec(id),
156 idx = Number(m[1]);
157
158 if (idx !== currIdx) {
159 rads[currIdx].el.classed('selected', false);
160 currIdx = idx;
161 rads[currIdx].el.classed('selected', true);
162 invokeCurrent();
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800163 }
164 }
165
Simon Hunt85fa2b82015-02-26 14:33:23 -0800166 // {
167 // gid: gid,
168 // tooltip: ..., (optional)
169 // key: ..., (optional)
170 // cb: cb
171 // id: ... (added by us)
172 // index: ... (added by us)
173 // }
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800174
175 rset.forEach(function (btn, index) {
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800176
Simon Hunt85fa2b82015-02-26 14:33:23 -0800177 if (!fs.isO(btn)) {
178 $log.warn('radio button descriptor at index ' + index +
179 ' not an object');
180 return;
181 }
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800182
Simon Hunt85fa2b82015-02-26 14:33:23 -0800183 var rid = id + '-' + index,
184 initSel = (index === 0),
185 rbdiv = createDiv(rDiv, 'radioButton', rid);
Bri Prebilic Cole664d4702015-02-25 12:16:14 -0800186
Simon Hunt85fa2b82015-02-26 14:33:23 -0800187 rbdiv.classed('selected', initSel);
188 rbdiv.on('click', rbclick);
189 is.loadIcon(rbdiv, btn.gid, btnSize, true);
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700190 if (btn.tooltip) { addTooltip(rbdiv, btn.tooltip); }
Simon Hunt85fa2b82015-02-26 14:33:23 -0800191 angular.extend(btn, {
192 el: rbdiv,
193 id: rid,
194 cb: fs.isF(btn.cb) || noop,
195 index: index
196 });
197
198 if (btn.key) {
199 idxByKey[btn.key] = index;
200 }
201
202 rads.push(btn);
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800203 });
Simon Hunt85fa2b82015-02-26 14:33:23 -0800204
205
206 function invokeCurrent() {
207 var curr = rads[currIdx];
208 curr.cb(curr.index, curr.key);
209 }
210
211 function selected(x) {
212 var curr = rads[currIdx],
213 idx;
214
215 if (x === undefined) {
216 return curr.key || curr.index;
217 } else {
218 idx = idxByKey[x];
219 if (idx === undefined) {
Bri Prebilic Cole18489172015-02-27 17:12:00 -0800220 $log.warn('no radio button with key:', x);
Simon Hunt85fa2b82015-02-26 14:33:23 -0800221 } else {
222 selectedIndex(idx);
223 }
224 }
225 }
226
227 function selectedIndex(x) {
228 if (x === undefined) {
229 return currIdx;
230 } else {
231 if (x >= 0 && x < rads.length) {
Bri Prebilic Cole18489172015-02-27 17:12:00 -0800232 if (currIdx !== x) {
233 currIdx = x;
234 invokeCurrent();
235 } else {
236 $log.warn('current index already selected:', x);
237 }
Simon Hunt85fa2b82015-02-26 14:33:23 -0800238 } else {
Bri Prebilic Cole18489172015-02-27 17:12:00 -0800239 $log.warn('invalid radio button index:', x);
Simon Hunt85fa2b82015-02-26 14:33:23 -0800240 }
241 }
242 }
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800243
244 return {
Simon Hunt85fa2b82015-02-26 14:33:23 -0800245 width: rsetWidth,
246 selected: selected,
247 selectedIndex: selectedIndex
Bri Prebilic Cole08381ce2015-02-20 17:01:50 -0800248 }
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800249 }
250
Bri Prebilic Cole258f0462015-02-25 14:48:50 -0800251
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800252 angular.module('onosWidget')
Simon Hunt69252862015-02-26 11:26:08 -0800253 .factory('ButtonService',
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700254 ['$log', 'FnService', 'IconService', 'TooltipService',
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800255
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700256 function (_$log_, _fs_, _is_, _tts_) {
Simon Hunt69252862015-02-26 11:26:08 -0800257 $log = _$log_;
258 fs = _fs_;
259 is = _is_;
Bri Prebilic Cole54d09382015-03-19 18:40:27 -0700260 tts = _tts_;
Bri Prebilic Cole40be6b22015-02-19 17:12:23 -0800261
Simon Hunt69252862015-02-26 11:26:08 -0800262 return {
263 button: button,
264 toggle: toggle,
Simon Hunt85fa2b82015-02-26 14:33:23 -0800265 radioSet: radioSet
Simon Hunt69252862015-02-26 11:26:08 -0800266 };
267 }]);
268
269}());