blob: b64f58dc24beb8ba415e9bce46a46e614ba38b51 [file] [log] [blame]
Simon Hunta1028c42017-02-07 20:08:03 -08001/*
2 * Copyright 2017-present Open Networking Laboratory
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 -- SVG -- Sprite Service
19 * For defining sprites and layouts (of sprites).
20 */
21(function () {
22 'use strict';
23
24 // injected references
25 var $log, fs, sds;
26
27 // configuration of default options
28 var optDefaults = {
29 sprite: {
30 builder: {
31 // none for now
32 },
33 addRect: {
Simon Hunta6ae1212017-03-18 17:58:53 -070034 fill: 'gray1',
35 stroke: 'none'
Simon Hunta1028c42017-02-07 20:08:03 -080036 },
37 addPath: {
Simon Hunta6ae1212017-03-18 17:58:53 -070038 fill: 'none',
39 stroke: 'gray1'
Simon Hunta1028c42017-02-07 20:08:03 -080040 }
41 },
42 layout: {
43 builder: {
Simon Hunta6ae1212017-03-18 17:58:53 -070044 grid: 10 // grid square size (in layout coord-space)
Simon Hunta1028c42017-02-07 20:08:03 -080045 },
46 addSprite: {
47 anchor: 'topleft' // topleft, center
48 },
49 addLabel: {
50 anchor: 'center', // center, left, right
51 fontStyle: 'normal' // normal, italic, bold
52 }
53 }
54 };
55
56 // internal state
57 var sprites, // sprite cache
58 layouts, // layout cache
59 api;
60
61 // ----------------------------------------------------------------------
62 // === Sprite Builder ===
63
64 // Sample usage:
65 //
66 // ss.createSprite('foo', 100, 100)
Simon Hunta6ae1212017-03-18 17:58:53 -070067 // .addPath('M40,40h20v20h-20z', {fill: 'gold1'})
68 // .addRect(50, 50, 10, 20, {stroke: 'gold1'})
Simon Hunta1028c42017-02-07 20:08:03 -080069 // .register();
70
71 function spriteBuilder(id, w, h, opts) {
72 var o = angular.extend({}, optDefaults.sprite.builder, opts),
73 builder,
74 paths = [],
75 rects = [];
76
77 // TODO: verify id has not already been registered
78
79 // x,y is top left corner; w,h is width and height of rectangle
80 function addRect(x, y, w, h, opts) {
81 var o = angular.extend({}, optDefaults.sprite.addRect, opts);
82
83 rects.push({
Simon Hunta6ae1212017-03-18 17:58:53 -070084 x: x, y: y, w: w, h: h, o: o
Simon Hunta1028c42017-02-07 20:08:03 -080085 });
86 return builder;
87 }
88
89 function addPath(d, opts) {
90 var o = angular.extend({}, optDefaults.sprite.addPath, opts);
91
92 if (fs.isS(d)) {
Simon Hunta6ae1212017-03-18 17:58:53 -070093 paths.push({d: d, o: o});
Simon Hunta1028c42017-02-07 20:08:03 -080094 } else if (fs.isA(d)) {
Simon Hunta6ae1212017-03-18 17:58:53 -070095 paths.push({d: d.join(''), o: o});
Simon Hunta1028c42017-02-07 20:08:03 -080096 } else {
97 $log.warn('addPath: path not a string or array', d);
98 }
99 return builder;
100 }
101
102 function register() {
103 sprites.set(id, builder);
104 }
105
106 // define the builder object...
107 builder = {
108 type: 'sprite',
109 data: {
110 id: id,
111 w: w,
112 h: h,
113 opts: o
114 },
115 paths: paths,
116 rects: rects,
117
118 // builder API
119 addRect: addRect,
120 addPath: addPath,
121 register: register
122 };
123
124 return builder;
125 }
126
127 // ----------------------------------------------------------------------
128 // === Layout Builder ===
129
130 // Sample usage:
131 //
132 // ss.createLayout('fooLayout', 400, 300)
133 // .addSprite('foo', 10, 10, 40)
134 // .addSprite('foo', 60, 10, 40)
135 // .addSprite('foo', 110, 10, 40)
136 // .register();
137
138 function layoutBuilder(id, w, h, opts) {
139 var o = angular.extend({}, optDefaults.layout.builder, opts),
140 builder,
141 sprs = [],
142 labs = [];
143
144 // TODO: verify id has not already been registered
145
146 function addSprite(id, x, y, w, opts) {
147 var o = angular.extend({}, optDefaults.layout.addSprite, opts),
148 s = sprites.get(id);
149
150 if (!s) {
151 $log.warn('no such sprite:', id);
152 return builder;
153 }
154
155 sprs.push({
156 sprite: s, x: x, y: y, w: w, anchor: o.anchor
157 });
158 return builder;
159 }
160
161 function addLabel(text, x, y, opts) {
162 var o = angular.extend({}, optDefaults.layout.addLabel, opts);
163
164 labs.push({
165 text: text, x: x, y: y, anchor: o.anchor, style: o.fontStyle
166 });
167 return builder;
168 }
169
170 function register() {
171 layouts.set(id, builder);
172 }
173
174 // define the builder object...
175 builder = {
176 type: 'layout',
177 data: {
178 id: id,
179 w: w,
180 h: h,
181 opts: o
182 },
183 sprites: sprs,
184 labels: labs,
185
186 // builder API
187 addSprite: addSprite,
188 addLabel: addLabel,
189 register: register
190 };
191
192 return builder;
193 }
194
195 // ----------------------------------------------------------------------
196 // === API functions ===
197
198 // Clears the sprite / layout caches.
199 function clear() {
200 sprites = d3.map();
201 layouts = d3.map();
202 }
203
204 // Initializes the sprite / layout caches with core elements.
205 function init() {
206 sds.registerCoreSprites(api);
207 }
208
209 // Returns a sprite "builder", which can be used to programmatically
210 // define a sprite.
211 function createSprite(id, w, h) {
212 $log.debug('createSprite:', id, w, 'x', h);
213 return spriteBuilder(id, w, h);
214 }
215
216 // Returns a layout "builder", which can be used to programmatically
217 // define a layout.
Simon Hunt0ee20bf2017-05-10 19:59:17 -0700218 function createLayout(id, w, h, opts) {
219 $log.debug('createLayout:', id, w, 'x', h, '(opts:', opts, ')');
220 return layoutBuilder(id, w, h, opts);
Simon Hunta1028c42017-02-07 20:08:03 -0800221 }
222
223 // Registers a sprite defined by the given object (JSON structure).
224 function registerSprite(json) {
225 $log.debug('registerSprite:', json);
226 // TODO: create and register a sprite based on JSON data
227 }
228
229 // Registers a layout defined by the given object (JSON structure).
230 function registerLayout(json) {
231 $log.debug('registerLayout:', json);
232 // TODO: create and register a layout based on JSON data
233 }
234
235 // Returns the sprite with the given ID, or undefined otherwise.
236 function sprite(id) {
237 return sprites.get(id);
238 }
239
240 // Returns the layout with the given ID, or undefined otherwise.
241 function layout(id) {
Steven Burrows3cc0c372017-02-10 15:15:24 +0000242 return layouts.get(id);
Simon Hunta1028c42017-02-07 20:08:03 -0800243 }
244
245 // Returns a count of registered sprites and layouts.
246 function count() {
247 return {
248 sprites: sprites.size(),
249 layouts: layouts.size()
250 };
251 }
252
253 // Dumps the cache contents to console
254 function dump() {
255 $log.debug('Dumping Caches...');
256 $log.debug('sprites:', sprites);
257 $log.debug('layouts:', layouts);
258 }
259
260 // ----------------------------------------------------------------------
261
262 angular.module('onosSvg')
263 .factory('SpriteService',
264 ['$log', 'FnService', 'SpriteDataService',
265
266 function (_$log_, _fs_, _sds_) {
267 $log = _$log_;
268 fs = _fs_;
269 sds = _sds_;
270
271 api = {
272 clear: clear,
273 init: init,
274 createSprite: createSprite,
275 createLayout: createLayout,
276 registerSprite: registerSprite,
277 registerLayout: registerLayout,
278 sprite: sprite,
279 layout: layout,
280 count: count,
281 dump: dump
282 };
283 return api;
284 }]
285 )
286 .run(['$log', function ($log) {
287 $log.debug('Clearing sprite and layout caches');
288 clear();
289 }]);
290
291}());