Committed by
Simon Hunt
GUI -- implemented Theme Service.
- moved body class handling into Theme Service, (out of Key Service). Change-Id: Ied0d22523fec36cadef8b9669194089585f73959
Showing
7 changed files
with
192 additions
and
23 deletions
... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
23 | 'use strict'; | 23 | 'use strict'; |
24 | 24 | ||
25 | // references to injected services | 25 | // references to injected services |
26 | - var $log, f; | 26 | + var $log, fs, ts; |
27 | 27 | ||
28 | // internal state | 28 | // internal state |
29 | var keyHandler = { | 29 | var keyHandler = { |
... | @@ -32,8 +32,7 @@ | ... | @@ -32,8 +32,7 @@ |
32 | viewKeys: {}, | 32 | viewKeys: {}, |
33 | viewFn: null, | 33 | viewFn: null, |
34 | viewGestures: [] | 34 | viewGestures: [] |
35 | - }, | 35 | + }; |
36 | - theme = 'light'; | ||
37 | 36 | ||
38 | // TODO: we need to have the concept of view token here.. | 37 | // TODO: we need to have the concept of view token here.. |
39 | function getViewToken() { | 38 | function getViewToken() { |
... | @@ -76,9 +75,9 @@ | ... | @@ -76,9 +75,9 @@ |
76 | key = whatKey(keyCode), | 75 | key = whatKey(keyCode), |
77 | kh = keyHandler, | 76 | kh = keyHandler, |
78 | gk = kh.globalKeys[key], | 77 | gk = kh.globalKeys[key], |
79 | - gcb = f.isF(gk) || (f.isA(gk) && f.isF(gk[0])), | 78 | + gcb = fs.isF(gk) || (fs.isA(gk) && fs.isF(gk[0])), |
80 | vk = kh.viewKeys[key], | 79 | vk = kh.viewKeys[key], |
81 | - vcb = f.isF(vk) || (f.isA(vk) && f.isF(vk[0])) || f.isF(kh.viewFn), | 80 | + vcb = fs.isF(vk) || (fs.isA(vk) && fs.isF(vk[0])) || fs.isF(kh.viewFn), |
82 | token = getViewToken(); | 81 | token = getViewToken(); |
83 | 82 | ||
84 | d3.event.stopPropagation(); | 83 | d3.event.stopPropagation(); |
... | @@ -137,12 +136,7 @@ | ... | @@ -137,12 +136,7 @@ |
137 | } | 136 | } |
138 | 137 | ||
139 | function toggleTheme(view, key, code, ev) { | 138 | function toggleTheme(view, key, code, ev) { |
140 | - var body = d3.select('body'); | 139 | + ts.toggleTheme(); |
141 | - theme = (theme === 'light') ? 'dark' : 'light'; | ||
142 | - body.classed('light dark', false); | ||
143 | - body.classed(theme, true); | ||
144 | - // TODO: emit theme-change event to current view... | ||
145 | - //theme(view); | ||
146 | return true; | 140 | return true; |
147 | } | 141 | } |
148 | 142 | ||
... | @@ -150,7 +144,7 @@ | ... | @@ -150,7 +144,7 @@ |
150 | var viewKeys, | 144 | var viewKeys, |
151 | masked = []; | 145 | masked = []; |
152 | 146 | ||
153 | - if (f.isF(keyArg)) { | 147 | + if (fs.isF(keyArg)) { |
154 | // set general key handler callback | 148 | // set general key handler callback |
155 | keyHandler.viewFn = keyArg; | 149 | keyHandler.viewFn = keyArg; |
156 | } else { | 150 | } else { |
... | @@ -173,7 +167,7 @@ | ... | @@ -173,7 +167,7 @@ |
173 | var gkeys = d3.map(keyHandler.globalKeys).keys(), | 167 | var gkeys = d3.map(keyHandler.globalKeys).keys(), |
174 | masked = d3.map(keyHandler.maskedKeys).keys(), | 168 | masked = d3.map(keyHandler.maskedKeys).keys(), |
175 | vkeys = d3.map(keyHandler.viewKeys).keys(), | 169 | vkeys = d3.map(keyHandler.viewKeys).keys(), |
176 | - vfn = !!f.isF(keyHandler.viewFn); | 170 | + vfn = !!fs.isF(keyHandler.viewFn); |
177 | 171 | ||
178 | return { | 172 | return { |
179 | globalKeys: gkeys, | 173 | globalKeys: gkeys, |
... | @@ -184,17 +178,17 @@ | ... | @@ -184,17 +178,17 @@ |
184 | } | 178 | } |
185 | 179 | ||
186 | angular.module('onosUtil') | 180 | angular.module('onosUtil') |
187 | - .factory('KeyService', ['$log', 'FnService', function ($l, fs) { | 181 | + .factory('KeyService', ['$log', 'FnService', 'ThemeService', |
188 | - $log = $l; | 182 | + function (_$log_, _fs_, _ts_) { |
189 | - f = fs; | 183 | + $log = _$log_; |
184 | + fs = _fs_; | ||
185 | + ts = _ts_; | ||
186 | + | ||
190 | return { | 187 | return { |
191 | installOn: function (elem) { | 188 | installOn: function (elem) { |
192 | elem.on('keydown', keyIn); | 189 | elem.on('keydown', keyIn); |
193 | setupGlobalKeys(); | 190 | setupGlobalKeys(); |
194 | }, | 191 | }, |
195 | - theme: function () { | ||
196 | - return theme; | ||
197 | - }, | ||
198 | keyBindings: function (x) { | 192 | keyBindings: function (x) { |
199 | if (x === undefined) { | 193 | if (x === undefined) { |
200 | return getKeyBindings(); | 194 | return getKeyBindings(); |
... | @@ -206,7 +200,7 @@ | ... | @@ -206,7 +200,7 @@ |
206 | if (g === undefined) { | 200 | if (g === undefined) { |
207 | return keyHandler.viewGestures; | 201 | return keyHandler.viewGestures; |
208 | } else { | 202 | } else { |
209 | - keyHandler.viewGestures = f.isA(g) || []; | 203 | + keyHandler.viewGestures = fs.isA(g) || []; |
210 | } | 204 | } |
211 | } | 205 | } |
212 | }; | 206 | }; | ... | ... |
web/gui/src/main/webapp/app/fw/util/theme.js
0 → 100644
1 | +/* | ||
2 | + * Copyright 2014 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 -- Util -- Theme Service | ||
19 | + | ||
20 | + @author Simon Hunt | ||
21 | + */ | ||
22 | +(function () { | ||
23 | + 'use strict'; | ||
24 | + | ||
25 | + var $log; | ||
26 | + | ||
27 | + var themes = ['light', 'dark'], | ||
28 | + themeStr = themes.join(' '), | ||
29 | + thidx; | ||
30 | + | ||
31 | + function init() { | ||
32 | + thidx = 0; | ||
33 | + updateBodyClass(); | ||
34 | + } | ||
35 | + | ||
36 | + function getTheme() { | ||
37 | + return themes[thidx]; | ||
38 | + } | ||
39 | + | ||
40 | + function setTheme(t) { | ||
41 | + var idx = themes.indexOf(t); | ||
42 | + if (idx > -1 && idx !== thidx) { | ||
43 | + thidx = idx; | ||
44 | + updateBodyClass(); | ||
45 | + themeEvent('set'); | ||
46 | + } | ||
47 | + } | ||
48 | + | ||
49 | + function toggleTheme() { | ||
50 | + var i = thidx + 1; | ||
51 | + thidx = (i===themes.length) ? 0 : i; | ||
52 | + updateBodyClass(); | ||
53 | + themeEvent('toggle'); | ||
54 | + return getTheme(); | ||
55 | + } | ||
56 | + | ||
57 | + function updateBodyClass() { | ||
58 | + var body = d3.select('body'); | ||
59 | + body.classed(themeStr, false); | ||
60 | + body.classed(getTheme(), true); | ||
61 | + } | ||
62 | + | ||
63 | + function themeEvent(w) { | ||
64 | + // TODO: emit a theme-changed event | ||
65 | + var m = 'Theme-Change-('+w+'): ' + getTheme(); | ||
66 | + $log.debug(m); | ||
67 | + } | ||
68 | + | ||
69 | + // TODO: add hook for theme-change listener | ||
70 | + | ||
71 | + angular.module('onosUtil') | ||
72 | + .factory('ThemeService', ['$log', function (_$log_) { | ||
73 | + $log = _$log_; | ||
74 | + thidx = 0; | ||
75 | + | ||
76 | + return { | ||
77 | + init: init, | ||
78 | + theme: function (x) { | ||
79 | + if (x === undefined) { | ||
80 | + return getTheme(); | ||
81 | + } else { | ||
82 | + setTheme(x); | ||
83 | + } | ||
84 | + }, | ||
85 | + toggleTheme: toggleTheme | ||
86 | + }; | ||
87 | + }]); | ||
88 | + | ||
89 | +}()); |
... | @@ -35,6 +35,7 @@ | ... | @@ -35,6 +35,7 @@ |
35 | 35 | ||
36 | <script src="fw/util/util.js"></script> | 36 | <script src="fw/util/util.js"></script> |
37 | <script src="fw/util/fn.js"></script> | 37 | <script src="fw/util/fn.js"></script> |
38 | + <script src="fw/util/theme.js"></script> | ||
38 | <script src="fw/util/keys.js"></script> | 39 | <script src="fw/util/keys.js"></script> |
39 | 40 | ||
40 | <script src="fw/mast/mast.js"></script> | 41 | <script src="fw/mast/mast.js"></script> | ... | ... |
... | @@ -24,13 +24,15 @@ | ... | @@ -24,13 +24,15 @@ |
24 | 'use strict'; | 24 | 'use strict'; |
25 | 25 | ||
26 | angular.module('onosApp', ['onosUtil', 'onosMast']) | 26 | angular.module('onosApp', ['onosUtil', 'onosMast']) |
27 | - .controller('OnosCtrl', ['$log', 'KeyService', function (_$log_, ks) { | 27 | + .controller('OnosCtrl', ['$log', 'KeyService', 'ThemeService', |
28 | + function (_$log_, ks, ts) { | ||
28 | var $log = _$log_, | 29 | var $log = _$log_, |
29 | self = this; | 30 | self = this; |
30 | 31 | ||
31 | self.version = '1.1.0'; | 32 | self.version = '1.1.0'; |
32 | 33 | ||
33 | // initialize onos (main app) controller here... | 34 | // initialize onos (main app) controller here... |
35 | + ts.init(); | ||
34 | ks.installOn(d3.select('body')); | 36 | ks.installOn(d3.select('body')); |
35 | 37 | ||
36 | $log.log('OnosCtrl has been created'); | 38 | $log.log('OnosCtrl has been created'); | ... | ... |
... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
19 | 19 | ||
20 | @author Simon Hunt | 20 | @author Simon Hunt |
21 | */ | 21 | */ |
22 | -describe('factory: fw/lib/fn.js', function() { | 22 | +describe('factory: fw/util/fn.js', function() { |
23 | var fs, | 23 | var fs, |
24 | someFunction = function () {}, | 24 | someFunction = function () {}, |
25 | someArray = [1, 2, 3], | 25 | someArray = [1, 2, 3], | ... | ... |
... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
19 | 19 | ||
20 | @author Simon Hunt | 20 | @author Simon Hunt |
21 | */ | 21 | */ |
22 | -describe('factory: fw/lib/keys.js', function() { | 22 | +describe('factory: fw/util/keys.js', function() { |
23 | var $log, ks, fs, | 23 | var $log, ks, fs, |
24 | d3Elem, elem, last; | 24 | d3Elem, elem, last; |
25 | 25 | ... | ... |
1 | +/* | ||
2 | + * Copyright 2014 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 -- Util -- Theme Service - Unit Tests | ||
19 | + | ||
20 | + @author Simon Hunt | ||
21 | + */ | ||
22 | +describe('factory: fw/util/theme.js', function() { | ||
23 | + var ts, $log; | ||
24 | + | ||
25 | + beforeEach(module('onosUtil')); | ||
26 | + | ||
27 | + beforeEach(inject(function (ThemeService, _$log_) { | ||
28 | + ts = ThemeService; | ||
29 | + $log = _$log_; | ||
30 | + ts.init(); | ||
31 | + })); | ||
32 | + | ||
33 | + function verifyBodyClass(yes, no) { | ||
34 | + function bodyHasClass(c) { | ||
35 | + return d3.select('body').classed(c); | ||
36 | + } | ||
37 | + expect(bodyHasClass(yes)).toBeTruthy(); | ||
38 | + expect(bodyHasClass(no)).toBeFalsy(); | ||
39 | + } | ||
40 | + | ||
41 | + it('should default to light theme', function () { | ||
42 | + expect(ts.theme()).toEqual('light'); | ||
43 | + }); | ||
44 | + | ||
45 | + it('should toggle to dark, then to light again', function () { | ||
46 | + // Note: re-work this once theme-change listeners are implemented | ||
47 | + spyOn($log, 'debug'); | ||
48 | + | ||
49 | + expect(ts.toggleTheme()).toEqual('dark'); | ||
50 | + expect(ts.theme()).toEqual('dark'); | ||
51 | + expect($log.debug).toHaveBeenCalledWith('Theme-Change-(toggle): dark'); | ||
52 | + verifyBodyClass('dark', 'light'); | ||
53 | + | ||
54 | + expect(ts.toggleTheme()).toEqual('light'); | ||
55 | + expect(ts.theme()).toEqual('light'); | ||
56 | + expect($log.debug).toHaveBeenCalledWith('Theme-Change-(toggle): light'); | ||
57 | + verifyBodyClass('light', 'dark'); | ||
58 | + }); | ||
59 | + | ||
60 | + it('should let us set the theme by name', function () { | ||
61 | + // Note: re-work this once theme-change listeners are implemented | ||
62 | + spyOn($log, 'debug'); | ||
63 | + | ||
64 | + expect(ts.theme()).toEqual('light'); | ||
65 | + ts.theme('dark'); | ||
66 | + expect(ts.theme()).toEqual('dark'); | ||
67 | + expect($log.debug).toHaveBeenCalledWith('Theme-Change-(set): dark'); | ||
68 | + verifyBodyClass('dark', 'light'); | ||
69 | + }); | ||
70 | + | ||
71 | + it('should ignore unknown theme names', function () { | ||
72 | + // Note: re-work this once theme-change listeners are implemented | ||
73 | + spyOn($log, 'debug'); | ||
74 | + | ||
75 | + expect(ts.theme()).toEqual('light'); | ||
76 | + verifyBodyClass('light', 'dark'); | ||
77 | + | ||
78 | + ts.theme('turquoise'); | ||
79 | + expect(ts.theme()).toEqual('light'); | ||
80 | + expect($log.debug).not.toHaveBeenCalled(); | ||
81 | + verifyBodyClass('light', 'dark'); | ||
82 | + }); | ||
83 | +}); |
-
Please register or login to post a comment