blob: 6ad00157e63532ea2ce57a82a2547a05d145e896 [file] [log] [blame]
/*
* Copyright 2015 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;
// 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);
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);
function _toggle(b) {
sel = (b === undefined) ? !sel : !!b;
togDiv.classed('selected', sel);
cbFnc(sel);
}
togDiv.on('click', _toggle);
return {
id: id,
width: buttonWidth,
selected: function () { return sel; },
toggle: _toggle
}
}
// === 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);
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) {
currIdx = x;
invokeCurrent();
} else {
$log.warn('invalid radio button index', x);
}
}
}
return {
width: rsetWidth,
selected: selected,
selectedIndex: selectedIndex
}
}
angular.module('onosWidget')
.factory('ButtonService',
['$log', 'FnService', 'IconService',
function (_$log_, _fs_, _is_) {
$log = _$log_;
fs = _fs_;
is = _is_;
return {
button: button,
toggle: toggle,
radioSet: radioSet
};
}]);
}());