Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 1 | /* |
Brian O'Connor | a09fe5b | 2017-08-03 21:12:30 -0700 | [diff] [blame] | 2 | * Copyright 2015-present Open Networking Foundation |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 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 -- Topology Sprite Module. |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 19 | Defines behavior for loading sprites into the sprite layer. |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 20 | */ |
| 21 | |
| 22 | (function () { |
| 23 | 'use strict'; |
| 24 | |
| 25 | // injected refs |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 26 | var $log, fs, gs, sus, wss; |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 27 | |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 28 | // constants |
| 29 | var tssid = 'TopoSpriteService: ', |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 30 | fontsize = 20; // default font size 20pt. |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 31 | |
| 32 | // internal state |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 33 | var spriteLayer, defsElement; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 34 | |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 35 | |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 36 | function registerPathsAsGlyphs(paths) { |
| 37 | var custom = {}, |
| 38 | ids = []; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 39 | |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 40 | function mkd(d) { |
| 41 | return fs.isA(d) ? d.join('') : d; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 42 | } |
| 43 | |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 44 | paths.forEach(function (path) { |
| 45 | var tag = 'spr_' + path.tag; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 46 | |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 47 | if (path.glyph) { |
| 48 | // assumption is that we are using a built-in glyph |
| 49 | return; |
| 50 | } |
| 51 | |
| 52 | custom['_' + tag] = path.viewbox || '0 0 1000 1000'; |
| 53 | custom[tag] = mkd(path.d); |
| 54 | ids.push(tag); |
| 55 | }); |
| 56 | |
| 57 | gs.registerGlyphs(custom); |
| 58 | gs.loadDefs(defsElement, ids, true); |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 59 | } |
| 60 | |
Simon Hunt | 7f62f7c | 2015-05-11 17:38:02 -0700 | [diff] [blame] | 61 | function applyStrokeStyle(s, use) { |
| 62 | var style; |
| 63 | if (s) { |
| 64 | style = {}; |
| 65 | angular.forEach(s, function (value, key) { |
| 66 | style['stroke-' + key] = value; |
| 67 | }); |
| 68 | use.style(style); |
| 69 | } |
| 70 | } |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 71 | |
Simon Hunt | 7f62f7c | 2015-05-11 17:38:02 -0700 | [diff] [blame] | 72 | function applyFillClass(f, use) { |
| 73 | use.classed('fill-' + f, true); |
| 74 | } |
| 75 | |
| 76 | function doSprite(spr, def, pathmeta) { |
| 77 | var pmeta = pathmeta[def.path], |
| 78 | c = spr.class || 'gray1', |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 79 | p = spr.pos || [0, 0], |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 80 | lab = spr.label, |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 81 | dim = def.dim || [40, 40], |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 82 | w = dim[0], |
| 83 | h = dim[1], |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 84 | dy = def.labelyoff || 1, |
| 85 | sc = def.scale, |
| 86 | xfm = sus.translate(p), |
Simon Hunt | 7f62f7c | 2015-05-11 17:38:02 -0700 | [diff] [blame] | 87 | g, attr, use; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 88 | |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 89 | if (sc) { |
| 90 | xfm += sus.scale(sc, sc); |
| 91 | } |
| 92 | |
| 93 | g = spriteLayer.append('g') |
| 94 | .classed(c, true) |
| 95 | .attr('transform', xfm); |
| 96 | |
| 97 | attr = { |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 98 | width: w, |
| 99 | height: h, |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 100 | 'xlink:href': '#' + pmeta.u, |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 101 | }; |
| 102 | |
| 103 | use = g.append('use').attr(attr); |
Simon Hunt | 7f62f7c | 2015-05-11 17:38:02 -0700 | [diff] [blame] | 104 | applyStrokeStyle(pmeta.s, use); |
| 105 | applyFillClass(def.fill, use); |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 106 | |
Simon Hunt | 7f62f7c | 2015-05-11 17:38:02 -0700 | [diff] [blame] | 107 | |
| 108 | // add subpaths if they have been defined |
| 109 | if (fs.isA(def.subpaths)) { |
| 110 | def.subpaths.forEach(function (v) { |
| 111 | pmeta = pathmeta[v.path]; |
| 112 | attr = { |
| 113 | width: w, |
| 114 | height: h, |
| 115 | 'xlink:href': '#' + pmeta.u, |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 116 | transform: sus.translate(v.pos), |
Simon Hunt | 7f62f7c | 2015-05-11 17:38:02 -0700 | [diff] [blame] | 117 | }; |
| 118 | use = g.append('use').attr(attr); |
| 119 | applyStrokeStyle(pmeta.s, use); |
| 120 | applyFillClass(def.subpathfill, use); |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 121 | }); |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 122 | } |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 123 | |
| 124 | if (lab) { |
| 125 | g.append('text') |
| 126 | .text(lab) |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 127 | .attr({ x: w / 2, y: h * dy }); |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 128 | } |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 129 | } |
| 130 | |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 131 | function doLabel(label) { |
| 132 | var c = label.class || 'gray1', |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 133 | p = label.pos || [0, 0], |
| 134 | sz = label.size || 1.0; |
| 135 | |
| 136 | spriteLayer.append('g') |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 137 | .classed(c, true) |
| 138 | .attr('transform', sus.translate(p)) |
| 139 | .append('text') |
| 140 | .text(label.text) |
| 141 | .style('font-size', (fontsize * sz)+'pt'); |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 145 | // ========================== |
| 146 | // event handlers |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 147 | |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 148 | // Handles response from 'spriteListRequest' which lists all the |
| 149 | // registered sprite definitions on the server. |
| 150 | // (see onos-upload-sprites) |
| 151 | function inList(payload) { |
| 152 | $log.debug(tssid + 'Registered sprite definitions:', payload.names); |
| 153 | // Some day, we will make this list available to the user in |
| 154 | // a dropdown selection box... |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 155 | } |
| 156 | |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 157 | // Handles response from 'spriteDataRequest' which provides the |
| 158 | // data for the requested sprite definition. |
| 159 | function inData(payload) { |
| 160 | var data = payload.data, |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 161 | name, desc, pfx, sprites, labels, alpha, |
| 162 | paths, defn, load, |
| 163 | pathmeta = {}, |
| 164 | defs = {}, |
| 165 | warn = []; |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 166 | |
| 167 | if (!data) { |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 168 | $log.warn(tssid + 'No sprite data loaded.'); |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 169 | return; |
| 170 | } |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 171 | name = data.defn_name; |
| 172 | desc = data.defn_desc; |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 173 | paths = data.paths; |
| 174 | defn = data.defn; |
| 175 | load = data.load; |
| 176 | pfx = tssid + '[' + name + ']: '; |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 177 | |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 178 | $log.debug('Loading sprites...[' + name + ']', desc); |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 179 | |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 180 | function no(what) { |
| 181 | warn.push(pfx + 'No ' + what + ' property defined'); |
Simon Hunt | b2c4cc8 | 2015-04-15 17:16:28 -0700 | [diff] [blame] | 182 | } |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 183 | |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 184 | if (!paths) no('paths'); |
| 185 | if (!defn) no('defn'); |
| 186 | if (!load) no('load'); |
| 187 | |
| 188 | if (warn.length) { |
| 189 | $log.error(warn.join('\n')); |
| 190 | return; |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 191 | } |
| 192 | |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 193 | // any custom paths need to be added to the glyph DB, and imported |
| 194 | registerPathsAsGlyphs(paths); |
| 195 | |
| 196 | paths.forEach(function (p) { |
| 197 | pathmeta[p.tag] = { |
| 198 | s: p.stroke, |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 199 | u: p.glyph || 'spr_' + p.tag, |
Simon Hunt | 017a7c3 | 2015-04-15 19:23:27 -0700 | [diff] [blame] | 200 | }; |
| 201 | }); |
| 202 | |
| 203 | defn.forEach(function (d) { |
| 204 | defs[d.id] = d; |
| 205 | }); |
| 206 | |
| 207 | // sprites, labels and alpha are each optional components of the load |
| 208 | sprites = load.sprites; |
| 209 | labels = load.labels; |
| 210 | alpha = load.alpha; |
| 211 | |
| 212 | if (alpha) { |
| 213 | spriteLayer.style('opacity', alpha); |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 214 | } |
| 215 | |
| 216 | if (sprites) { |
| 217 | sprites.forEach(function (spr) { |
Simon Hunt | 7f62f7c | 2015-05-11 17:38:02 -0700 | [diff] [blame] | 218 | var def = defs[spr.id]; |
| 219 | doSprite(spr, def, pathmeta); |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 220 | }); |
| 221 | } |
| 222 | |
| 223 | if (labels) { |
| 224 | labels.forEach(doLabel); |
| 225 | } |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 226 | } |
| 227 | |
| 228 | |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 229 | function loadSprites(layer, defsElem, defname) { |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 230 | var name = defname || 'sprites'; |
| 231 | spriteLayer = layer; |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 232 | defsElement = defsElem; |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 233 | |
| 234 | $log.info(tssid + 'Requesting sprite definition ['+name+']...'); |
| 235 | |
| 236 | wss.sendEvent('spriteListRequest'); |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 237 | wss.sendEvent('spriteDataRequest', { name: name }); |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 238 | } |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 239 | |
| 240 | // === ----------------------------------------------------- |
| 241 | // === MODULE DEFINITION === |
| 242 | |
| 243 | angular.module('ovTopo') |
| 244 | .factory('TopoSpriteService', |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 245 | ['$log', 'FnService', 'GlyphService', |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 246 | 'SvgUtilService', 'WebSocketService', |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 247 | |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 248 | function (_$log_, _fs_, _gs_, _sus_, _wss_) { |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 249 | $log = _$log_; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 250 | fs = _fs_; |
Simon Hunt | abf66d9 | 2015-04-15 12:57:31 -0700 | [diff] [blame] | 251 | gs = _gs_; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 252 | sus = _sus_; |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 253 | wss = _wss_; |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 254 | |
| 255 | return { |
Simon Hunt | fd8c7d7 | 2015-04-14 17:53:37 -0700 | [diff] [blame] | 256 | loadSprites: loadSprites, |
| 257 | spriteListResponse: inList, |
Steven Burrows | 1c2a968 | 2017-07-14 16:52:46 +0100 | [diff] [blame] | 258 | spriteDataResponse: inData, |
Simon Hunt | 2052e5d | 2015-04-13 17:40:44 -0700 | [diff] [blame] | 259 | }; |
| 260 | }]); |
| 261 | |
| 262 | }()); |