Committed by
Gerrit Code Review
GUI -- Refactored Button Service.
Change-Id: I194af8f44aae4d6905bbe564d3aaae6599d20e92
Showing
2 changed files
with
145 additions
and
94 deletions
... | @@ -27,7 +27,15 @@ | ... | @@ -27,7 +27,15 @@ |
27 | var btnSize = 25, | 27 | var btnSize = 25, |
28 | btnPadding = 4; | 28 | btnPadding = 4; |
29 | 29 | ||
30 | - function noop() {} | 30 | + |
31 | + // === Helper Functions | ||
32 | + | ||
33 | + function divExists(div, msg) { | ||
34 | + if (!div) { | ||
35 | + $log.warn('div undefined (' + msg + ')'); | ||
36 | + } | ||
37 | + return !!div; | ||
38 | + } | ||
31 | 39 | ||
32 | function createDiv(div, cls, id) { | 40 | function createDiv(div, cls, id) { |
33 | return div.append('div') | 41 | return div.append('div') |
... | @@ -35,11 +43,22 @@ | ... | @@ -35,11 +43,22 @@ |
35 | .attr('id', id); | 43 | .attr('id', id); |
36 | } | 44 | } |
37 | 45 | ||
46 | + function noop() {} | ||
47 | + | ||
48 | + function buttonWidth() { | ||
49 | + return btnSize + 2 * btnPadding; | ||
50 | + } | ||
51 | + | ||
52 | + | ||
53 | + // === BUTTON ================================================= | ||
54 | + | ||
55 | + // div is where to put the button (d3.selection of a DIV element) | ||
56 | + // id should be globally unique | ||
57 | + // gid is glyph ID (from Glyph Service) | ||
58 | + // cb is callback function on click | ||
59 | + // tooltip is text for tooltip | ||
38 | function button(div, id, gid, cb, tooltip) { | 60 | function button(div, id, gid, cb, tooltip) { |
39 | - if (!div) { | 61 | + if (!divExists(div, 'button')) return null; |
40 | - $log.warn('Button cannot append to div'); | ||
41 | - return null; | ||
42 | - } | ||
43 | 62 | ||
44 | var btnDiv = createDiv(div, 'button', id), | 63 | var btnDiv = createDiv(div, 'button', id), |
45 | cbFnc = fs.isF(cb) || noop; | 64 | cbFnc = fs.isF(cb) || noop; |
... | @@ -50,16 +69,21 @@ | ... | @@ -50,16 +69,21 @@ |
50 | 69 | ||
51 | return { | 70 | return { |
52 | id: id, | 71 | id: id, |
53 | - click: cbFnc, | 72 | + width: buttonWidth |
54 | - el: btnDiv | ||
55 | } | 73 | } |
56 | } | 74 | } |
57 | 75 | ||
76 | + | ||
77 | + // === TOGGLE BUTTON ========================================== | ||
78 | + | ||
79 | + // div is where to put the button (d3.selection of a DIV element) | ||
80 | + // id should be globally unique | ||
81 | + // gid is glyph ID (from Glyph Service) | ||
82 | + // initState is whether the toggle is on or not to begin | ||
83 | + // cb is callback function on click | ||
84 | + // tooltip is text for tooltip | ||
58 | function toggle(div, id, gid, initState, cb, tooltip) { | 85 | function toggle(div, id, gid, initState, cb, tooltip) { |
59 | - if (!div) { | 86 | + if (!divExists(div, 'toggle button')) return null; |
60 | - $log.warn('Toggle cannot append to div'); | ||
61 | - return null; | ||
62 | - } | ||
63 | 87 | ||
64 | var sel = !!initState, | 88 | var sel = !!initState, |
65 | togDiv = createDiv(div, 'toggleButton', id), | 89 | togDiv = createDiv(div, 'toggleButton', id), |
... | @@ -69,116 +93,144 @@ | ... | @@ -69,116 +93,144 @@ |
69 | togDiv.classed('selected', sel); | 93 | togDiv.classed('selected', sel); |
70 | 94 | ||
71 | function _toggle(b) { | 95 | function _toggle(b) { |
72 | - if (b === undefined) { | 96 | + sel = (b === undefined) ? !sel : !!b; |
73 | - sel = !sel; | ||
74 | - } else { | ||
75 | - sel = !!b; | ||
76 | - } | ||
77 | - cbFnc(sel); | ||
78 | togDiv.classed('selected', sel); | 97 | togDiv.classed('selected', sel); |
98 | + cbFnc(sel); | ||
79 | } | 99 | } |
80 | 100 | ||
81 | togDiv.on('click', _toggle); | 101 | togDiv.on('click', _toggle); |
82 | 102 | ||
83 | return { | 103 | return { |
84 | id: id, | 104 | id: id, |
85 | - el: togDiv, | 105 | + width: buttonWidth, |
86 | selected: function () { return sel; }, | 106 | selected: function () { return sel; }, |
87 | toggle: _toggle | 107 | toggle: _toggle |
88 | } | 108 | } |
89 | } | 109 | } |
90 | 110 | ||
111 | + | ||
112 | + // === RADIO BUTTON SET ======================================= | ||
113 | + | ||
114 | + | ||
115 | + // div is where to put the button (d3.selection of a DIV element) | ||
116 | + // id should be globally unique | ||
117 | + // rset is an array of button descriptors of the following form: | ||
118 | + // { | ||
119 | + // gid: glyphId, | ||
120 | + // tooltip: tooltipText, | ||
121 | + // cb: callbackFunction | ||
122 | + // } | ||
91 | function radioSet(div, id, rset) { | 123 | function radioSet(div, id, rset) { |
92 | - if (!div) { | 124 | + if (!divExists(div, 'radio button set')) return null; |
93 | - $log.warn('Radio buttons cannot append to div'); | 125 | + |
94 | - return null; | 126 | + if (!fs.isA(rset) || !rset.length) { |
95 | - } | 127 | + $log.warn('invalid array (radio button set)'); |
96 | - if (!fs.isA(rset)) { | ||
97 | - $log.warn('Radio button set is not an array'); | ||
98 | - return null; | ||
99 | - } | ||
100 | - if (rset.length === 0) { | ||
101 | - $log.warn('Cannot create radio button set from empty array'); | ||
102 | return null; | 128 | return null; |
103 | } | 129 | } |
104 | - var rDiv = div.append('div').classed('radioSet', true), | 130 | + |
131 | + var rDiv = createDiv(div, 'radioSet', id), | ||
105 | rads = [], | 132 | rads = [], |
106 | - sel; | 133 | + idxByKey = {}, |
107 | - | 134 | + currIdx = 0; |
108 | - function _selected(s) { | 135 | + |
109 | - var curr = d3.select(this), | 136 | + function rsetWidth() { |
110 | - currId = curr.attr('id'), | 137 | + return ((btnSize + btnPadding) * rads.length) + btnPadding; |
111 | - selIndex = _getIndex(), | ||
112 | - currIndex = _getIndex(currId); | ||
113 | - | ||
114 | - // I have it going by id's because I couldn't think of a way | ||
115 | - // to get the radio button's index from the div element | ||
116 | - // We could look at the end of the radio button id for its number | ||
117 | - // but I didn't know how to get the end of the string's number | ||
118 | - if (!s) { | ||
119 | - if (sel !== currId) { | ||
120 | - rads[selIndex].el.classed('selected', false); | ||
121 | - curr.classed('selected', true); | ||
122 | - rads[currIndex].cb(); | ||
123 | - sel = currId; | ||
124 | - } | ||
125 | - } else { | ||
126 | - if (!rads[s].el.classed('selected')) { | ||
127 | - rads[selIndex].el.classed('selected', false); | ||
128 | - rads[s].el.classed('selected', true); | ||
129 | - rads[s].cb(); | ||
130 | - sel = rads[s].id; | ||
131 | - } | ||
132 | - } | ||
133 | } | 138 | } |
134 | 139 | ||
135 | - // given the id, will get the index of element | 140 | + function rbclick() { |
136 | - // without the id, will get the index of sel | 141 | + var id = d3.select(this).attr('id'), |
137 | - function _getIndex(id) { | 142 | + m = /^.*-(\d+)$/.exec(id), |
138 | - if (!id) { | 143 | + idx = Number(m[1]); |
139 | - for (var i = 0; i < rads.length; i++) { | 144 | + |
140 | - if (rads[i].id === sel) { return i; } | 145 | + if (idx !== currIdx) { |
141 | - } | 146 | + rads[currIdx].el.classed('selected', false); |
142 | - } else { | 147 | + currIdx = idx; |
143 | - for (var j = 0; j < rads.length; j++) { | 148 | + rads[currIdx].el.classed('selected', true); |
144 | - if (rads[j].id === id) { return j; } | 149 | + invokeCurrent(); |
145 | - } | ||
146 | } | 150 | } |
147 | } | 151 | } |
148 | 152 | ||
153 | + // { | ||
154 | + // gid: gid, | ||
155 | + // tooltip: ..., (optional) | ||
156 | + // key: ..., (optional) | ||
157 | + // cb: cb | ||
158 | + // id: ... (added by us) | ||
159 | + // index: ... (added by us) | ||
160 | + // } | ||
161 | + | ||
149 | rset.forEach(function (btn, index) { | 162 | rset.forEach(function (btn, index) { |
150 | - var rid = {id: id + '-' + index}, | ||
151 | - rbtn = angular.extend({}, btn, rid), | ||
152 | - istate = (index === 0), | ||
153 | - rBtnDiv = createDiv(rDiv, 'radioButton', rbtn.id); | ||
154 | 163 | ||
155 | - if (istate) { rBtnDiv.classed('selected', true); } | 164 | + if (!fs.isO(btn)) { |
156 | - is.loadIcon(rBtnDiv, rbtn.gid, btnSize, true); | 165 | + $log.warn('radio button descriptor at index ' + index + |
157 | - rbtn.el = rBtnDiv; | 166 | + ' not an object'); |
158 | - rbtn.cb = fs.isF(rbtn.cb) || noop; | 167 | + return; |
168 | + } | ||
159 | 169 | ||
160 | - rBtnDiv.on('click', _selected); | 170 | + var rid = id + '-' + index, |
171 | + initSel = (index === 0), | ||
172 | + rbdiv = createDiv(rDiv, 'radioButton', rid); | ||
173 | + | ||
174 | + rbdiv.classed('selected', initSel); | ||
175 | + rbdiv.on('click', rbclick); | ||
176 | + is.loadIcon(rbdiv, btn.gid, btnSize, true); | ||
177 | + angular.extend(btn, { | ||
178 | + el: rbdiv, | ||
179 | + id: rid, | ||
180 | + cb: fs.isF(btn.cb) || noop, | ||
181 | + index: index | ||
182 | + }); | ||
183 | + | ||
184 | + if (btn.key) { | ||
185 | + idxByKey[btn.key] = index; | ||
186 | + } | ||
161 | 187 | ||
162 | - rads.push(rbtn); | 188 | + rads.push(btn); |
163 | }); | 189 | }); |
164 | - sel = rads[0].id; | ||
165 | - rads[0].cb(); | ||
166 | 190 | ||
167 | - return { | 191 | + |
168 | - rads: rads, | 192 | + function invokeCurrent() { |
169 | - width: (((btnSize + btnPadding) * rads.length) + btnPadding), | 193 | + var curr = rads[currIdx]; |
170 | - selected: function (i) { | 194 | + curr.cb(curr.index, curr.key); |
171 | - if (i === undefined) { _getIndex(); } | 195 | + } |
172 | - else { _selected(i); } | 196 | + |
197 | + function selected(x) { | ||
198 | + var curr = rads[currIdx], | ||
199 | + idx; | ||
200 | + | ||
201 | + if (x === undefined) { | ||
202 | + return curr.key || curr.index; | ||
203 | + } else { | ||
204 | + idx = idxByKey[x]; | ||
205 | + if (idx === undefined) { | ||
206 | + $log.warn('no radio button with key "' + x + '"'); | ||
207 | + } else { | ||
208 | + selectedIndex(idx); | ||
209 | + } | ||
173 | } | 210 | } |
174 | } | 211 | } |
175 | - } | ||
176 | 212 | ||
177 | - function width(s) { | 213 | + function selectedIndex(x) { |
178 | - if (s) { btnSize = s; } | 214 | + if (x === undefined) { |
179 | - return btnSize; | 215 | + return currIdx; |
216 | + } else { | ||
217 | + if (x >= 0 && x < rads.length) { | ||
218 | + currIdx = x; | ||
219 | + invokeCurrent(); | ||
220 | + } else { | ||
221 | + $log.warn('invalid radio button index', x); | ||
222 | + } | ||
223 | + } | ||
224 | + } | ||
225 | + | ||
226 | + return { | ||
227 | + width: rsetWidth, | ||
228 | + selected: selected, | ||
229 | + selectedIndex: selectedIndex | ||
230 | + } | ||
180 | } | 231 | } |
181 | 232 | ||
233 | + | ||
182 | angular.module('onosWidget') | 234 | angular.module('onosWidget') |
183 | .factory('ButtonService', | 235 | .factory('ButtonService', |
184 | ['$log', 'FnService', 'IconService', | 236 | ['$log', 'FnService', 'IconService', |
... | @@ -191,8 +243,7 @@ | ... | @@ -191,8 +243,7 @@ |
191 | return { | 243 | return { |
192 | button: button, | 244 | button: button, |
193 | toggle: toggle, | 245 | toggle: toggle, |
194 | - radioSet: radioSet, | 246 | + radioSet: radioSet |
195 | - width: width | ||
196 | }; | 247 | }; |
197 | }]); | 248 | }]); |
198 | 249 | ... | ... |
... | @@ -88,7 +88,7 @@ | ... | @@ -88,7 +88,7 @@ |
88 | if (!validId(btnId, 'addButton')) { return null; } | 88 | if (!validId(btnId, 'addButton')) { return null; } |
89 | ids.push(btnId); | 89 | ids.push(btnId); |
90 | button = bns.button(tbarDiv, btnId, gid, cb, tooltip); | 90 | button = bns.button(tbarDiv, btnId, gid, cb, tooltip); |
91 | - if (button) { addToWidth(bns.width()); } | 91 | + if (button) { addToWidth(button.width()); } |
92 | displayTools(); | 92 | displayTools(); |
93 | return button; | 93 | return button; |
94 | } | 94 | } |
... | @@ -99,7 +99,7 @@ | ... | @@ -99,7 +99,7 @@ |
99 | if (!validId(togId, 'addToggle')) { return null; } | 99 | if (!validId(togId, 'addToggle')) { return null; } |
100 | ids.push(togId); | 100 | ids.push(togId); |
101 | toggle = bns.toggle(tbarDiv, togId, gid, initState, cb, tooltip); | 101 | toggle = bns.toggle(tbarDiv, togId, gid, initState, cb, tooltip); |
102 | - if (toggle) { addToWidth(bns.width()); } | 102 | + if (toggle) { addToWidth(toggle.width()); } |
103 | displayTools(); | 103 | displayTools(); |
104 | return toggle; | 104 | return toggle; |
105 | } | 105 | } |
... | @@ -110,7 +110,7 @@ | ... | @@ -110,7 +110,7 @@ |
110 | if (!validId(radId, 'addRadioSet')) { return null; } | 110 | if (!validId(radId, 'addRadioSet')) { return null; } |
111 | ids.push(radId); | 111 | ids.push(radId); |
112 | radios = bns.radioSet(tbarDiv, radId, rset); | 112 | radios = bns.radioSet(tbarDiv, radId, rset); |
113 | - if (radios) { addToWidth(radios.width); } | 113 | + if (radios) { addToWidth(radios.width()); } |
114 | displayTools(); | 114 | displayTools(); |
115 | return radios; | 115 | return radios; |
116 | } | 116 | } | ... | ... |
-
Please register or login to post a comment