OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 /** | |
6 * @file | |
7 * The stamp panel object. This object manages the UI connections for various | |
8 * elements of the stamp editor panel, and makes the dynamic parts of the | |
9 * panel's DOM. | |
10 */ | |
11 | |
12 | |
13 goog.provide('stamp'); | |
14 goog.provide('stamp.StampPanel'); | |
15 | |
16 goog.require('goog.Disposable'); | |
17 goog.require('goog.dom'); | |
18 goog.require('goog.editor.Table'); | |
19 goog.require('goog.events'); | |
20 goog.require('goog.style'); | |
21 goog.require('goog.ui.Zippy'); | |
22 | |
23 goog.require('stamp.Editor'); | |
24 | |
25 /** | |
26 * Manages the data and interface for the stamp editor. | |
27 * @param {!Element} editorContainer The element under which DOM nodes for | |
28 * the stamp editor should be added. | |
29 * @constructor | |
30 * @extends {goog.events.EventTarget} | |
31 */ | |
32 stamp.StampPanel = function(editorContainer) { | |
33 goog.events.EventTarget.call(this); | |
34 this.parent_ = editorContainer; | |
35 }; | |
36 goog.inherits(stamp.StampPanel, goog.events.EventTarget); | |
37 | |
38 /** | |
39 * A dictionary of all the DOM elements used by the stamp editor. | |
40 * @type {Object<Element>} | |
41 * @private | |
42 */ | |
43 stamp.StampPanel.prototype.domElements_ = {}; | |
44 | |
45 /** | |
46 * The minimum number of rows and columns in the stamp editor table. | |
47 */ | |
48 stamp.StampPanel.prototype.MIN_ROW_COUNT = 3; | |
49 stamp.StampPanel.prototype.MIN_COLUMN_COUNT = 3; | |
50 | |
51 /** | |
52 * The ids used for elements in the DOM. The stamp editor expects these | |
53 * elements to exist. | |
54 * @enum {string} | |
55 */ | |
56 stamp.StampPanel.DomIds = { | |
57 ADD_COLUMN_BUTTON: 'add_column_button', | |
58 ADD_ROW_BUTTON: 'add_row_button', | |
59 CANCEL_BUTTON: 'cancel_button', | |
60 OK_BUTTON: 'ok_button', | |
61 REMOVE_COLUMN_BUTTON: 'remove_column_button', | |
62 REMOVE_ROW_BUTTON: 'remove_row_button', | |
63 STAMP_EDITOR_BUTTON: 'stamp_editor_button', | |
64 STAMP_EDITOR_CONTAINER: 'stamp_editor_container', | |
65 STAMP_EDITOR_PANEL: 'stamp_editor_panel' | |
66 }; | |
67 | |
68 /** | |
69 * Panel events. These are dispatched on the stamp editor container object | |
70 * (usually a button that opens the panel), and indicate things like when the | |
71 * panel is about to open, or when it has been closed using specific buttons. | |
72 * @enum {string} | |
73 */ | |
74 stamp.StampPanel.Events = { | |
75 PANEL_DID_CANCEL: 'panel_did_cancel', // The Cancel button was clicked. | |
76 PANEL_DID_SAVE: 'panel_did_save', // The OK button was clicked. | |
77 // Sent right before the editor panel will collapse. Note that it is possible | |
78 // for the event to be sent, but the panel will not actually close. This can | |
79 // happen, for example, if the panel open button gets a mouse-down, but does | |
80 // not get a complete click event (no corresponding mouse-up). | |
81 PANEL_WILL_CLOSE: 'panel_will_close', | |
82 // Sent right before the editor panel will expand. Note that it is possible | |
83 // for the event to be sent, but the panel will not actually open. This can | |
84 // happen, for example, if the panel open button gets a mouse-down, but does | |
85 // not get a complete click event (no corresponding mouse-up). | |
86 PANEL_WILL_OPEN: 'panel_will_open' | |
87 }; | |
88 | |
89 /** | |
90 * Attributes added to cells to cache certain parameters like aliveState. | |
91 * @enum {string} | |
92 * @private | |
93 */ | |
94 stamp.StampPanel.CellAttributes_ = { | |
95 ENABLED_OPACITY: '1', | |
96 DISABLED_OPACITY: '0.5' | |
97 }; | |
98 | |
99 /** | |
100 * Characters used to encode the stamp as a string. | |
101 * @enum {string} | |
102 * @private | |
103 */ | |
104 stamp.Editor.StringEncoding_ = { | |
105 DEAD_CELL: '.', | |
106 END_OF_ROW: '\n', | |
107 LIVE_CELL: '*' | |
108 }; | |
109 | |
110 /** | |
111 * Override of disposeInternal() to dispose of retained objects and unhook all | |
112 * events. | |
113 * @override | |
114 */ | |
115 stamp.StampPanel.prototype.disposeInternal = function() { | |
116 for (elt in this.domElements_) { | |
117 goog.events.removeAll(elt); | |
118 } | |
119 goog.events.removeAll(this.parent_); | |
120 this.panel_ = null; | |
121 this.parent_ = null; | |
122 this.stampEditor_ = null; | |
123 stamp.StampPanel.superClass_.disposeInternal.call(this); | |
124 } | |
125 | |
126 /** | |
127 * Respond to a MOUSEDOWN event on the parent element. This dispatches a | |
128 * a PANEL_WILL* event based on the expanded state of the panel. | |
129 * @param {!goog.events.Event} mousedownEvent The MOUSEDOWN event that | |
130 * triggered this handler. | |
131 */ | |
132 stamp.StampPanel.prototype.handleParentMousedown_ = function(mousedownEvent) { | |
133 mousedownEvent.stopPropagation(); | |
134 var eventType; | |
135 if (this.panel_.isExpanded()) { | |
136 // About to close the panel. | |
137 eventType = stamp.StampPanel.Events.PANEL_WILL_CLOSE; | |
138 } else { | |
139 eventType = stamp.StampPanel.Events.PANEL_WILL_OPEN; | |
140 } | |
141 this.dispatchEvent(new goog.events.Event(eventType)); | |
142 } | |
143 | |
144 /** | |
145 * Return the current stamp expressed as a string. | |
146 * @return {!string} The stamp currently in the editor. | |
147 */ | |
148 stamp.StampPanel.prototype.getStampAsString = function() { | |
149 return this.stampEditor_.getStampAsString(); | |
150 } | |
151 | |
152 /** | |
153 * Sets the current stamp based on the stamp encoding in |stampString|. | |
154 * @param {!string} stampString The encoded stamp string. | |
155 */ | |
156 stamp.StampPanel.prototype.setStampFromString = function(stampString) { | |
157 this.stampEditor_.setStampFromString(stampString); | |
158 this.refreshUI_(); | |
159 } | |
160 | |
161 /** | |
162 * Creates the DOM structure for the stamp editor panel and adds it to the | |
163 * document. The panel is built into the mainPanel DOM element. The expected | |
164 * DOM elements are keys in the |stampEditorElements| object: | |
165 * mainPanel The main panel element. | |
166 * editorContainer: A container for a TABLE element that impelements the | |
167 * stamp editor. | |
168 * addColumnButton: An element that becomes the button used to add a column to | |
169 * the stamp editor. An onclick listener is attached to this element. | |
170 * removeColumnButton: An element that becomes the button used to remove a | |
171 * column from the stamp editor. An onclick listener is attached to this | |
172 * element. | |
173 * addRowButton: An element that becomes the button used to add a row to | |
174 * the stamp editor. An onclick listener is attached to this element. | |
175 * removeRowButton: An element that becomes the button used to remove a | |
176 * row from the stamp editor. An onclick listener is attached to this | |
177 * element. | |
178 * cancelButton: An element that becomes the button used to close the panel | |
179 * without changing the current stamp. An onclick listener is attached | |
180 * to this element. Dispatches the "panel did close" event. | |
181 * okButton: An element that becomes the button used to close the panel | |
182 * and update the current stamp. An onclick listener is attached | |
183 * to this element. Dispatches the "panel did close" event. | |
184 * @param {!Object<Element>} stampEditorElements A dictionary of DOM elements | |
185 * required by the stamp editor panel. | |
186 * @return {!goog.ui.Zippy} The Zippy element representing the entire stamp | |
187 * panel with enclosed editor. | |
188 */ | |
189 stamp.StampPanel.prototype.makeStampEditorPanel = | |
190 function(stampEditorElements) { | |
191 if (!stampEditorElements) { | |
192 return null; | |
193 } | |
194 for (elt in stampEditorElements) { | |
195 this.domElements_[elt] = stampEditorElements[elt]; | |
196 } | |
197 // Create DOM structure to represent the stamp editor panel. This panel | |
198 // contains all the UI elements of the stamp editor: the stamp editor | |
199 // itself, add/remove column and row buttons, a legend and a title string. | |
200 // The layout of the panel is described in the markup; this code wires up | |
201 // the button and editor behaviours. | |
202 this.domElements_.panelHeader = goog.dom.createDom('div', | |
203 {'style': 'background-color:#EEE', | |
204 'class': 'panel-container'}, 'Stamp Editor...'); | |
205 this.domElements_.panelContainer = stampEditorElements.mainPanel; | |
206 goog.style.setPosition(this.domElements_.panelContainer, 0, | |
207 goog.style.getSize(this.parent_).height); | |
208 this.domElements_.panelContainer.style.display = 'block'; | |
209 var newEditor = goog.dom.createDom('div', null, | |
210 this.domElements_.panelHeader, this.domElements_.panelContainer); | |
211 | |
212 // Create the editable stamp representation within the editor panel. | |
213 this.stampEditor_ = new stamp.Editor(); | |
214 this.stampEditor_.makeStampEditorDom(stampEditorElements.editorContainer); | |
215 | |
216 goog.events.listen(this.parent_, goog.events.EventType.MOUSEDOWN, | |
217 this.handleParentMousedown_, false, this); | |
218 | |
219 // Wire up the add/remove column and row buttons. | |
220 goog.events.listen(stampEditorElements.addColumnButton, | |
221 goog.events.EventType.CLICK, | |
222 this.addColumn_, false, this); | |
223 goog.events.listen(stampEditorElements.removeColumnButton, | |
224 goog.events.EventType.CLICK, | |
225 this.removeColumn_, false, this); | |
226 goog.events.listen(stampEditorElements.addRowButton, | |
227 goog.events.EventType.CLICK, | |
228 this.addRow_, false, this); | |
229 goog.events.listen(stampEditorElements.removeRowButton, | |
230 goog.events.EventType.CLICK, | |
231 this.removeRow_, false, this); | |
232 goog.events.listen(stampEditorElements.cancelButton, | |
233 goog.events.EventType.CLICK, | |
234 this.closePanelAndCancel_, false, this); | |
235 goog.events.listen(stampEditorElements.okButton, | |
236 goog.events.EventType.CLICK, | |
237 this.closePanelAndSave_, false, this); | |
238 | |
239 // Add the panel's DOM structure to the document. | |
240 goog.dom.appendChild(this.parent_, newEditor); | |
241 this.panel_ = new goog.ui.Zippy(this.domElements_.panelHeader, | |
242 this.domElements_.panelContainer); | |
243 return this.panel_; | |
244 }; | |
245 | |
246 /** | |
247 * Respond to a CLICK event on the "add column" button. Update the display | |
248 * to reflect whether columns can be removed or not. | |
249 * @param {!goog.events.Event} clickEvent The CLICK event that triggered this | |
250 * handler. | |
251 */ | |
252 stamp.StampPanel.prototype.addColumn_ = function(clickEvent) { | |
253 clickEvent.stopPropagation(); | |
254 this.stampEditor_.appendColumn(); | |
255 this.refreshUI_(); | |
256 } | |
257 | |
258 /** | |
259 * Respond to a CLICK event on the "remove column" button. | |
260 * @param {!goog.events.Event} clickEvent The CLICK event that triggered this | |
261 * handler. | |
262 */ | |
263 stamp.StampPanel.prototype.removeColumn_ = function(clickEvent) { | |
264 clickEvent.stopPropagation(); | |
265 this.stampEditor_.removeLastColumn(); | |
266 this.refreshUI_(); | |
267 } | |
268 | |
269 /** | |
270 * Respond to a CLICK event on the "add row" button. | |
271 * @param {!goog.events.Event} clickEvent The CLICK event that triggered this | |
272 * handler. | |
273 */ | |
274 stamp.StampPanel.prototype.addRow_ = function(clickEvent) { | |
275 clickEvent.stopPropagation(); | |
276 this.stampEditor_.appendRow(); | |
277 this.refreshUI_(); | |
278 } | |
279 | |
280 /** | |
281 * Respond to a CLICK event on the "remove row" button. | |
282 * @param {!goog.events.Event} clickEvent The CLICK event that triggered this | |
283 * handler. | |
284 * @private | |
285 */ | |
286 stamp.StampPanel.prototype.removeRow_ = function(clickEvent) { | |
287 clickEvent.stopPropagation(); | |
288 this.stampEditor_.removeLastRow(); | |
289 this.refreshUI_(); | |
290 } | |
291 | |
292 /** | |
293 * Update the UI to reflect thing like "remove column" button to be enabled if | |
294 * there are column that can be removed. | |
295 * @private | |
296 */ | |
297 stamp.StampPanel.prototype.refreshUI_ = function() { | |
298 if (this.stampEditor_.rowCount() > this.MIN_ROW_COUNT) { | |
299 goog.style.setStyle(this.domElements_.removeRowButton, | |
300 { 'opacity': stamp.StampPanel.CellAttributes_.ENABLED_OPACITY }); | |
301 } else { | |
302 goog.style.setStyle(this.domElements_.removeRowButton, | |
303 { 'opacity': stamp.StampPanel.CellAttributes_.DISABLED_OPACITY }); | |
304 } | |
305 if (this.stampEditor_.columnCount() > this.MIN_COLUMN_COUNT) { | |
306 goog.style.setStyle(this.domElements_.removeColumnButton, | |
307 { 'opacity': stamp.StampPanel.CellAttributes_.ENABLED_OPACITY }); | |
308 } else { | |
309 goog.style.setStyle(this.domElements_.removeColumnButton, | |
310 { 'opacity': stamp.StampPanel.CellAttributes_.DISABLED_OPACITY }); | |
311 } | |
312 } | |
313 | |
314 /** | |
315 * Respond to a CLICK event on the "cancel" button. | |
316 * @param {!goog.events.Event} clickEvent The CLICK event that triggered this | |
317 * handler. | |
318 * @private | |
319 */ | |
320 stamp.StampPanel.prototype.closePanelAndCancel_ = function(clickEvent) { | |
321 if (this.panel_.isExpanded()) | |
322 this.panel_.collapse(); | |
323 // Dispatch two events: PANEL_WILL_CLOSE and PANEL_DID_CANCEL. | |
324 this.dispatchEvent( | |
325 new goog.events.Event(stamp.StampPanel.Events.PANEL_WILL_CLOSE)); | |
326 this.dispatchEvent( | |
327 new goog.events.Event(stamp.StampPanel.Events.PANEL_DID_CANCEL)); | |
328 } | |
329 | |
330 /** | |
331 * Respond to a CLICK event on the "ok" button. | |
332 * @param {!goog.events.Event} clickEvent The CLICK event that triggered this | |
333 * handler. | |
334 * @private | |
335 */ | |
336 stamp.StampPanel.prototype.closePanelAndSave_ = function(clickEvent) { | |
337 if (this.panel_.isExpanded()) | |
338 this.panel_.collapse(); | |
339 // Dispatch two events: PANEL_WILL_CLOSE and PANEL_DID_SAVE. | |
340 this.dispatchEvent( | |
341 new goog.events.Event(stamp.StampPanel.Events.PANEL_WILL_CLOSE)); | |
342 this.dispatchEvent( | |
343 new goog.events.Event(stamp.StampPanel.Events.PANEL_DID_SAVE)); | |
344 } | |
OLD | NEW |