/* * 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 -- Topology Sprite Module. Defines behavior for loading sprites into the sprite layer. */ (function () { 'use strict'; // injected refs var $log, $http, fs, gs, sus, wss; // constants var tssid = 'TopoSpriteService: ', fontsize = 20; // default font size 20pt. // internal state var spriteLayer, defsElement; function registerPathsAsGlyphs(paths) { var custom = {}, ids = []; function mkd(d) { return fs.isA(d) ? d.join('') : d; } paths.forEach(function (path) { var tag = 'spr_' + path.tag; if (path.glyph) { // assumption is that we are using a built-in glyph return; } custom['_' + tag] = path.viewbox || '0 0 1000 1000'; custom[tag] = mkd(path.d); ids.push(tag); }); gs.registerGlyphs(custom); gs.loadDefs(defsElement, ids, true); } function applyStrokeStyle(s, use) { var style; if (s) { style = {}; angular.forEach(s, function (value, key) { style['stroke-' + key] = value; }); use.style(style); } } function applyFillClass(f, use) { use.classed('fill-' + f, true); } function doSprite(spr, def, pathmeta) { var pmeta = pathmeta[def.path], c = spr.class || 'gray1', p = spr.pos || [0,0], lab = spr.label, dim = def.dim || [40,40], w = dim[0], h = dim[1], dy = def.labelyoff || 1, sc = def.scale, xfm = sus.translate(p), g, attr, use; if (sc) { xfm += sus.scale(sc, sc); } g = spriteLayer.append('g') .classed(c, true) .attr('transform', xfm); attr = { width: w, height: h, 'xlink:href': '#' + pmeta.u }; use = g.append('use').attr(attr); applyStrokeStyle(pmeta.s, use); applyFillClass(def.fill, use); // add subpaths if they have been defined if (fs.isA(def.subpaths)) { def.subpaths.forEach(function (v) { pmeta = pathmeta[v.path]; attr = { width: w, height: h, 'xlink:href': '#' + pmeta.u, transform: sus.translate(v.pos) }; use = g.append('use').attr(attr); applyStrokeStyle(pmeta.s, use); applyFillClass(def.subpathfill, use); }); } if (lab) { g.append('text') .text(lab) .attr({ x: w / 2, y: h * dy }); } } function doLabel(label) { var c = label.class || 'gray1', p = label.pos || [0,0], sz = label.size || 1.0, g = spriteLayer.append('g') .classed(c, true) .attr('transform', sus.translate(p)) .append('text') .text(label.text) .style('font-size', (fontsize * sz)+'pt'); } // ========================== // event handlers // Handles response from 'spriteListRequest' which lists all the // registered sprite definitions on the server. // (see onos-upload-sprites) function inList(payload) { $log.debug(tssid + 'Registered sprite definitions:', payload.names); // Some day, we will make this list available to the user in // a dropdown selection box... } // Handles response from 'spriteDataRequest' which provides the // data for the requested sprite definition. function inData(payload) { var data = payload.data, name, desc, pfx, sprites, labels, alpha, paths, defn, load, pathmeta = {}, defs = {}, warn = []; if (!data) { $log.warn(tssid + 'No sprite data loaded.'); return; } name = data.defn_name; desc = data.defn_desc; paths = data.paths; defn = data.defn; load = data.load; pfx = tssid + '[' + name + ']: '; $log.debug("Loading sprites...[" + name + "]", desc); function no(what) { warn.push(pfx + 'No ' + what + ' property defined'); } if (!paths) no('paths'); if (!defn) no('defn'); if (!load) no('load'); if (warn.length) { $log.error(warn.join('\n')); return; } // any custom paths need to be added to the glyph DB, and imported registerPathsAsGlyphs(paths); paths.forEach(function (p) { pathmeta[p.tag] = { s: p.stroke, u: p.glyph || 'spr_' + p.tag }; }); defn.forEach(function (d) { defs[d.id] = d; }); // sprites, labels and alpha are each optional components of the load sprites = load.sprites; labels = load.labels; alpha = load.alpha; if (alpha) { spriteLayer.style('opacity', alpha); } if (sprites) { sprites.forEach(function (spr) { var def = defs[spr.id]; doSprite(spr, def, pathmeta); }); } if (labels) { labels.forEach(doLabel); } } function loadSprites(layer, defsElem, defname) { var name = defname || 'sprites'; spriteLayer = layer; defsElement = defsElem; $log.info(tssid + 'Requesting sprite definition ['+name+']...'); wss.sendEvent('spriteListRequest'); wss.sendEvent('spriteDataRequest', {name: name}); } // === ----------------------------------------------------- // === MODULE DEFINITION === angular.module('ovTopo') .factory('TopoSpriteService', ['$log', '$http', 'FnService', 'GlyphService', 'SvgUtilService', 'WebSocketService', function (_$log_, _$http_, _fs_, _gs_, _sus_, _wss_) { $log = _$log_; $http = _$http_; fs = _fs_; gs = _gs_; sus = _sus_; wss = _wss_; return { loadSprites: loadSprites, spriteListResponse: inList, spriteDataResponse: inData }; }]); }());