/* * 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 -- Toolbar Service */ // TODO: Augment service to allow toolbars to exist on right edge of screen // TODO: also - make toolbar more object aware (rows etc.) (function () { 'use strict'; // injected refs var $log, fs, ps, bns, is; // configuration var arrowSize = 10, sepWidth = 6, defaultSettings = { edge: 'left', width: 20, margin: 0, hideMargin: -20, top: 'auto', bottom: '10px', fade: false, shown: false }; // internal state var tbars = {}; // === Helper functions -------------------------------------- // translate uses 50 because the svg viewbox is 50 function rotateArrowLeft(adiv) { adiv.select('g') .attr('transform', 'translate(0 50) rotate(-90)'); } function rotateArrowRight(adiv) { adiv.select('g') .attr('transform', 'translate(50 0) rotate(90)'); } function createArrow(panel) { var arrowDiv = panel.append('div') .classed('tbar-arrow', true); is.loadIcon(arrowDiv, 'triangleUp', arrowSize, true); return arrowDiv; } function warn(msg, id) { $log.warn('createToolbar: ' + msg + ': [' + id + ']'); return null; } // ================================== function createToolbar(id, opts) { if (!id) return warn('no ID given'); if (tbars[id]) return warn('duplicate ID given', id); var settings = angular.extend({}, defaultSettings, fs.isO(opts)), items = {}, tbid = 'toolbar-' + id, panel = ps.createPanel(tbid, settings), arrowDiv = createArrow(panel), currentRow = panel.append('div').classed('tbar-row', true), rowButtonIds = [], // for removable buttons tbWidth = arrowSize + 2, // empty toolbar width maxWidth = panel.width(); arrowDiv.on('click', toggle); // add a descriptor for this toolbar tbars[id] = { settings: settings, items: items, panel: panel, panelId: tbid }; panel.classed('toolbar', true) .style('top', settings.top) .style('bottom', settings.bottom); // Helper functions function dupId(id, caller) { if (items[id]) { $log.warn(caller + ': duplicate ID:', id); return true; } return false; } function adjustWidth(btnWidth) { if (fs.noPxStyle(currentRow, 'width') >= maxWidth) { tbWidth += btnWidth; maxWidth = tbWidth; } panel.width(tbWidth); } // API functions function addButton(id, gid, cb, tooltip) { if (dupId(id, 'addButton')) return null; var bid = tbid + '-' + id, btn = bns.button(currentRow, bid, gid, cb, tooltip); items[id] = btn; adjustWidth(btn.width()); return btn; } function addToggle(id, gid, initState, cb, tooltip) { if (dupId(id, 'addToggle')) return null; var tid = tbid + '-' + id, tog = bns.toggle(currentRow, tid, gid, initState, cb, tooltip); items[id] = tog; adjustWidth(tog.width()); return tog; } function addRadioSet(id, rset) { if (dupId(id, 'addRadioSet')) return null; var rid = tbid + '-' + id, rad = bns.radioSet(currentRow, rid, rset); items[id] = rad; adjustWidth(rad.width()); return rad; } function addSeparator() { currentRow.append('div') .classed('separator', true); tbWidth += sepWidth; } function addRow() { if (currentRow.select('div').empty()) { return null; } else { panel.append('br'); currentRow = panel.append('div').classed('tbar-row', true); // return API to allow caller more access to the row return { clear: rowClear, setText: rowSetText, addButton: rowAddButton, classed: rowClassed }; } } function rowClear() { currentRow.selectAll('*').remove(); rowButtonIds.forEach(function (bid) { delete items[bid]; }); rowButtonIds = []; } // installs a div with text into the button row function rowSetText(text) { rowClear(); currentRow.append('div').classed('tbar-row-text', true) .html(text); } function rowAddButton(id, gid, cb, tooltip) { var b = addButton(id, gid, cb, tooltip); if (b) { rowButtonIds.push(id); } } function rowClassed(classes, bool) { currentRow.classed(classes, bool); } function show(cb) { rotateArrowLeft(arrowDiv); panel.show(cb); } function hide(cb) { rotateArrowRight(arrowDiv); panel.hide(cb); } function toggle(cb) { if (panel.isVisible()) { hide(cb); } else { show(cb); } } return { addButton: addButton, addToggle: addToggle, addRadioSet: addRadioSet, addSeparator: addSeparator, addRow: addRow, show: show, hide: hide, toggle: toggle }; } function destroyToolbar(id) { var tb = tbars[id]; delete tbars[id]; if (tb) { ps.destroyPanel(tb.panelId); } } // === Module Definition === angular.module('onosWidget') .factory('ToolbarService', ['$log', 'FnService', 'PanelService', 'ButtonService', 'IconService', function (_$log_, _fs_, _ps_, _bns_, _is_) { $log = _$log_; fs = _fs_; ps = _ps_; bns = _bns_; is = _is_; // this function is only used in testing function init() { tbars = {}; } return { init: init, createToolbar: createToolbar, destroyToolbar: destroyToolbar }; }]); }());