| /* |
| * Copyright 2015-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| ONOS GUI -- Widget -- Button Service |
| */ |
| (function () { |
| 'use strict'; |
| |
| // injected refs |
| var $log, fs, is, tts; |
| |
| // configuration |
| var btnSize = 25, |
| btnPadding = 4; |
| |
| |
| // === Helper Functions |
| |
| function divExists(div, msg) { |
| if (!div) { |
| $log.warn('div undefined (' + msg + ')'); |
| } |
| return !!div; |
| } |
| |
| function createDiv(div, cls, id) { |
| return div.append('div') |
| .classed(cls, true) |
| .attr('id', id); |
| } |
| |
| function noop() {} |
| |
| function buttonWidth() { |
| return btnSize + 2 * btnPadding; |
| } |
| |
| // === BUTTON ================================================= |
| |
| // div is where to put the button (d3.selection of a DIV element) |
| // id should be globally unique |
| // gid is glyph ID (from Glyph Service) |
| // cb is callback function on click |
| // tooltip is text for tooltip |
| function button(div, id, gid, cb, tooltip) { |
| if (!divExists(div, 'button')) return null; |
| |
| var btnDiv = createDiv(div, 'button', id), |
| cbFnc = fs.isF(cb) || noop; |
| |
| is.loadIcon(btnDiv, gid, btnSize, true); |
| if (tooltip) { tts.addTooltip(btnDiv, tooltip); } |
| |
| btnDiv.on('click', cbFnc); |
| |
| return { |
| id: id, |
| width: buttonWidth |
| } |
| } |
| |
| |
| // === TOGGLE BUTTON ========================================== |
| |
| // div is where to put the button (d3.selection of a DIV element) |
| // id should be globally unique |
| // gid is glyph ID (from Glyph Service) |
| // initState is whether the toggle is on or not to begin |
| // cb is callback function on click |
| // tooltip is text for tooltip |
| function toggle(div, id, gid, initState, cb, tooltip) { |
| if (!divExists(div, 'toggle button')) return null; |
| |
| var sel = !!initState, |
| togDiv = createDiv(div, 'toggleButton', id), |
| cbFnc = fs.isF(cb) || noop; |
| |
| is.loadIcon(togDiv, gid, btnSize, true); |
| togDiv.classed('selected', sel); |
| if (tooltip) { tts.addTooltip(togDiv, tooltip); } |
| |
| function _toggle(b, nocb) { |
| sel = (b === undefined) ? !sel : !!b; |
| togDiv.classed('selected', sel); |
| nocb || cbFnc(sel); |
| } |
| |
| // toggle the button state without invoking the callback |
| function toggleNoCb() { |
| _toggle(undefined, true); |
| } |
| |
| togDiv.on('click', _toggle); |
| |
| return { |
| id: id, |
| width: buttonWidth, |
| selected: function () { return sel; }, |
| toggle: _toggle, |
| toggleNoCb: toggleNoCb |
| } |
| } |
| |
| |
| // === RADIO BUTTON SET ======================================= |
| |
| |
| // div is where to put the button (d3.selection of a DIV element) |
| // id should be globally unique |
| // rset is an array of button descriptors of the following form: |
| // { |
| // gid: glyphId, |
| // tooltip: tooltipText, |
| // cb: callbackFunction |
| // } |
| function radioSet(div, id, rset) { |
| if (!divExists(div, 'radio button set')) return null; |
| |
| if (!fs.isA(rset) || !rset.length) { |
| $log.warn('invalid array (radio button set)'); |
| return null; |
| } |
| |
| var rDiv = createDiv(div, 'radioSet', id), |
| rads = [], |
| idxByKey = {}, |
| currIdx = 0; |
| |
| function rsetWidth() { |
| return ((btnSize + btnPadding) * rads.length) + btnPadding; |
| } |
| |
| function rbclick() { |
| var id = d3.select(this).attr('id'), |
| m = /^.*-(\d+)$/.exec(id), |
| idx = Number(m[1]); |
| |
| if (idx !== currIdx) { |
| rads[currIdx].el.classed('selected', false); |
| currIdx = idx; |
| rads[currIdx].el.classed('selected', true); |
| invokeCurrent(); |
| } |
| } |
| |
| // { |
| // gid: gid, |
| // tooltip: ..., (optional) |
| // key: ..., (optional) |
| // cb: cb |
| // id: ... (added by us) |
| // index: ... (added by us) |
| // } |
| |
| rset.forEach(function (btn, index) { |
| |
| if (!fs.isO(btn)) { |
| $log.warn('radio button descriptor at index ' + index + |
| ' not an object'); |
| return; |
| } |
| |
| var rid = id + '-' + index, |
| initSel = (index === 0), |
| rbdiv = createDiv(rDiv, 'radioButton', rid); |
| |
| rbdiv.classed('selected', initSel); |
| rbdiv.on('click', rbclick); |
| is.loadIcon(rbdiv, btn.gid, btnSize, true); |
| if (btn.tooltip) { tts.addTooltip(rbdiv, btn.tooltip); } |
| angular.extend(btn, { |
| el: rbdiv, |
| id: rid, |
| cb: fs.isF(btn.cb) || noop, |
| index: index |
| }); |
| |
| if (btn.key) { |
| idxByKey[btn.key] = index; |
| } |
| |
| rads.push(btn); |
| }); |
| |
| |
| function invokeCurrent() { |
| var curr = rads[currIdx]; |
| curr.cb(curr.index, curr.key); |
| } |
| |
| function selected(x) { |
| var curr = rads[currIdx], |
| idx; |
| |
| if (x === undefined) { |
| return curr.key || curr.index; |
| } else { |
| idx = idxByKey[x]; |
| if (idx === undefined) { |
| $log.warn('no radio button with key:', x); |
| } else { |
| selectedIndex(idx); |
| } |
| } |
| } |
| |
| function selectedIndex(x) { |
| if (x === undefined) { |
| return currIdx; |
| } else { |
| if (x >= 0 && x < rads.length) { |
| if (currIdx !== x) { |
| rads[currIdx].el.classed('selected', false); |
| currIdx = x; |
| rads[currIdx].el.classed('selected', true); |
| invokeCurrent(); |
| } else { |
| $log.warn('current index already selected:', x); |
| } |
| } else { |
| $log.warn('invalid radio button index:', x); |
| } |
| } |
| } |
| |
| return { |
| width: rsetWidth, |
| selected: selected, |
| selectedIndex: selectedIndex, |
| size: function () { return rads.length; } |
| } |
| } |
| |
| |
| angular.module('onosWidget') |
| .factory('ButtonService', |
| ['$log', 'FnService', 'IconService', 'TooltipService', |
| |
| function (_$log_, _fs_, _is_, _tts_) { |
| $log = _$log_; |
| fs = _fs_; |
| is = _is_; |
| tts = _tts_; |
| |
| return { |
| button: button, |
| toggle: toggle, |
| radioSet: radioSet |
| }; |
| }]); |
| |
| }()); |