OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 document.addEventListener('DOMContentLoaded', function() { | 5 document.addEventListener('DOMContentLoaded', function() { |
6 if (document.location.hash) // File path passed after the #. | 6 if (document.location.hash) // File path passed after the #. |
7 Gallery.openStandalone(decodeURI(document.location.hash.substr(1))); | 7 Gallery.openStandalone(decodeURI(document.location.hash.substr(1))); |
8 }); | 8 }); |
9 | 9 |
10 /** | 10 /** |
(...skipping 10 matching lines...) Expand all Loading... | |
21 * {function(string)} displayStringFunction | 21 * {function(string)} displayStringFunction |
22 * @class | 22 * @class |
23 * @constructor | 23 * @constructor |
24 */ | 24 */ |
25 function Gallery(context) { | 25 function Gallery(context) { |
26 this.container_ = document.querySelector('.gallery'); | 26 this.container_ = document.querySelector('.gallery'); |
27 this.document_ = document; | 27 this.document_ = document; |
28 this.context_ = context; | 28 this.context_ = context; |
29 this.metadataCache_ = context.metadataCache; | 29 this.metadataCache_ = context.metadataCache; |
30 | 30 |
31 this.dataModel_ = new cr.ui.ArrayDataModel([]); | |
32 this.selectionModel_ = new cr.ui.ListSelectionModel(); | |
33 | |
31 var strf = context.displayStringFunction; | 34 var strf = context.displayStringFunction; |
32 this.displayStringFunction_ = function(id, formatArgs) { | 35 this.displayStringFunction_ = function(id, formatArgs) { |
33 var args = Array.prototype.slice.call(arguments); | 36 var args = Array.prototype.slice.call(arguments); |
34 args[0] = 'GALLERY_' + id.toUpperCase(); | 37 args[0] = 'GALLERY_' + id.toUpperCase(); |
35 return strf.apply(null, args); | 38 return strf.apply(null, args); |
36 }; | 39 }; |
37 | 40 |
38 this.initListeners_(); | 41 this.initListeners_(); |
39 this.initDom_(); | 42 this.initDom_(); |
40 } | 43 } |
41 | 44 |
42 /** | 45 /** |
43 * Create and initialize a Gallery object based on a context. | 46 * Create and initialize a Gallery object based on a context. |
44 * | 47 * |
45 * @param {Object} context Gallery context. | 48 * @param {Object} context Gallery context. |
46 * @param {Array.<string>} urls Array of image urls. | 49 * @param {Array.<string>} urls Array of image urls. |
47 * @param {string} selectedUrl Selected url. | 50 * @param {string} selectedUrl Selected url. |
51 * @param {boolean} opt_grid True if open in the grid view. | |
48 */ | 52 */ |
49 Gallery.open = function(context, urls, selectedUrl) { | 53 Gallery.open = function(context, urls, selectedUrl, opt_grid) { |
50 Gallery.instance = new Gallery(context); | 54 Gallery.instance = new Gallery(context); |
51 Gallery.instance.load(urls, selectedUrl); | 55 Gallery.instance.load(urls, selectedUrl, opt_grid); |
52 }; | 56 }; |
53 | 57 |
54 /** | 58 /** |
55 * Create a Gallery object in a tab. | 59 * Create a Gallery object in a tab. |
56 * @param {string} path File system path to a selected file. | 60 * @param {string} path File system path to a selected file. |
57 */ | 61 */ |
58 Gallery.openStandalone = function(path) { | 62 Gallery.openStandalone = function(path) { |
59 ImageUtil.metrics = metrics; | 63 ImageUtil.metrics = metrics; |
60 | 64 |
61 var currentDir; | 65 var currentDir; |
(...skipping 21 matching lines...) Expand all Loading... | |
83 } else if (FileType.isImageOrVideo(entry)) { | 87 } else if (FileType.isImageOrVideo(entry)) { |
84 var url = entry.toURL(); | 88 var url = entry.toURL(); |
85 urls.push(url); | 89 urls.push(url); |
86 if (entry.fullPath == path) | 90 if (entry.fullPath == path) |
87 selectedUrl = url; | 91 selectedUrl = url; |
88 } | 92 } |
89 }); | 93 }); |
90 } | 94 } |
91 | 95 |
92 function onNameChange(name) { | 96 function onNameChange(name) { |
93 window.top.document.title = name; | 97 window.top.document.title = name || currentDir.name; |
94 | 98 |
95 var newPath = currentDir.fullPath + '/' + name; | 99 var newPath = currentDir.fullPath + '/' + name; |
96 var location = document.location.origin + document.location.pathname + | 100 var location = document.location.origin + document.location.pathname + |
97 '#' + encodeURI(newPath); | 101 '#' + encodeURI(newPath); |
98 history.replaceState(undefined, newPath, location); | 102 history.replaceState(undefined, newPath, location); |
99 } | 103 } |
100 | 104 |
101 function onClose() { | 105 function onClose() { |
102 document.location = 'main.html?' + | 106 document.location = 'main.html?' + |
103 JSON.stringify({defaultPath: document.location.hash.substr(1)}); | 107 JSON.stringify({defaultPath: document.location.hash.substr(1)}); |
104 } | 108 } |
105 | 109 |
106 function open() { | 110 function open() { |
111 urls.sort(); | |
107 Gallery.getFileBrowserPrivate().getStrings(function(strings) { | 112 Gallery.getFileBrowserPrivate().getStrings(function(strings) { |
108 loadTimeData.data = strings; | 113 loadTimeData.data = strings; |
109 var context = { | 114 var context = { |
110 readonlyDirName: null, | 115 readonlyDirName: null, |
111 saveDirEntry: currentDir, | 116 saveDirEntry: currentDir, |
112 metadataCache: MetadataCache.createFull(), | 117 metadataCache: MetadataCache.createFull(), |
113 onNameChange: onNameChange, | 118 onNameChange: onNameChange, |
114 onClose: onClose, | 119 onClose: onClose, |
115 displayStringFunction: strf | 120 displayStringFunction: strf |
116 }; | 121 }; |
117 Gallery.open(context, urls, selectedUrl || urls[0]); | 122 Gallery.open(context, urls, selectedUrl, !selectedUrl); |
118 }); | 123 }); |
119 } | 124 } |
120 }; | 125 }; |
121 | 126 |
122 /** | 127 /** |
123 * Tools fade-out timeout im milliseconds. | 128 * Tools fade-out timeout im milliseconds. |
124 * @type {Number} | 129 * @type {Number} |
125 */ | 130 */ |
126 Gallery.FADE_TIMEOUT = 3000; | 131 Gallery.FADE_TIMEOUT = 3000; |
127 | 132 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 this.onFilenameEditBlur_.bind(this)); | 192 this.onFilenameEditBlur_.bind(this)); |
188 this.filenameEdit_.addEventListener('keydown', | 193 this.filenameEdit_.addEventListener('keydown', |
189 this.onFilenameEditKeydown_.bind(this)); | 194 this.onFilenameEditKeydown_.bind(this)); |
190 nameBox.appendChild(this.filenameEdit_); | 195 nameBox.appendChild(this.filenameEdit_); |
191 | 196 |
192 util.createChild(this.toolbar_, 'button-spacer'); | 197 util.createChild(this.toolbar_, 'button-spacer'); |
193 | 198 |
194 this.prompt_ = new ImageEditor.Prompt( | 199 this.prompt_ = new ImageEditor.Prompt( |
195 this.container_, this.displayStringFunction_); | 200 this.container_, this.displayStringFunction_); |
196 | 201 |
197 this.slideMode_ = new SlideMode(this.container_, this.toolbar_, this.prompt_, | 202 this.modeButton_ = util.createChild(this.toolbar_, 'button mode'); |
203 this.modeButton_.addEventListener('click', this.toggleMode_.bind(this, null)); | |
204 | |
205 this.gridMode_ = new GridMode(this.container_, content, | |
206 this.dataModel_, this.selectionModel_, this.metadataCache_, | |
207 this.toggleMode_.bind(this, null)); | |
208 | |
209 this.slideMode_ = new SlideMode(this.container_, content, | |
210 this.toolbar_, this.prompt_, | |
211 this.dataModel_, this.selectionModel_, | |
198 this.context_, this.displayStringFunction_); | 212 this.context_, this.displayStringFunction_); |
199 this.slideMode_.addEventListener('edit', this.onEdit_.bind(this)); | |
200 this.slideMode_.addEventListener('selection', this.onSelection_.bind(this)); | |
201 | 213 |
202 this.shareMode_ = new ShareMode( | 214 var deleteButton = this.document_.createElement('div'); |
203 this.slideMode_.editor_, this.container_, this.toolbar_, | 215 deleteButton.className = 'button delete'; |
204 this.onShare_.bind(this), this.executeWhenReady.bind(this), | 216 deleteButton.title = this.displayStringFunction_('delete'); |
205 this.displayStringFunction_); | 217 deleteButton.addEventListener('click', this.onDelete_.bind(this)); |
218 this.toolbar_.insertBefore( | |
219 deleteButton, this.toolbar_.querySelector('.edit')); | |
220 | |
221 this.shareButton_ = util.createChild(this.toolbar_, 'button share'); | |
222 this.shareButton_.title = this.displayStringFunction_('share'); | |
223 this.shareButton_.addEventListener('click', this.toggleShare_.bind(this)); | |
224 | |
225 this.shareMenu_ = util.createChild(this.container_, 'share-menu'); | |
226 this.shareMenu_.hidden = true; | |
227 util.createChild(this.shareMenu_, 'bubble-point'); | |
206 | 228 |
207 Gallery.getFileBrowserPrivate().isFullscreen(function(fullscreen) { | 229 Gallery.getFileBrowserPrivate().isFullscreen(function(fullscreen) { |
208 this.originalFullscreen_ = fullscreen; | 230 this.originalFullscreen_ = fullscreen; |
209 }.bind(this)); | 231 }.bind(this)); |
232 | |
233 this.slideMode_.addEventListener('button', this.onModeButton_.bind(this)); | |
234 this.slideMode_.addEventListener('content', this.onContentChange_.bind(this)); | |
235 this.slideMode_.addEventListener('rename', this.onSelection_.bind(this)); | |
236 this.selectionModel_.addEventListener('change', this.onSelection_.bind(this)); | |
210 }; | 237 }; |
211 | 238 |
212 /** | 239 /** |
213 * Load the content. | 240 * Load the content. |
214 * | 241 * |
215 * @param {Array.<string>} urls Array of urls. | 242 * @param {Array.<string>} urls Array of urls. |
216 * @param {string} selectedUrl Selected url. | 243 * @param {string} selectedUrl Selected url. |
244 * @param {boolean} opt_grid True if open in the grid view. | |
217 */ | 245 */ |
218 Gallery.prototype.load = function(urls, selectedUrl) { | 246 Gallery.prototype.load = function(urls, selectedUrl, opt_grid) { |
219 this.items_ = []; | 247 var items = []; |
220 for (var index = 0; index < urls.length; ++index) { | 248 for (var index = 0; index < urls.length; ++index) { |
221 this.items_.push(new Gallery.Item(urls[index])); | 249 items.push(new Gallery.Item(urls[index])); |
222 } | 250 } |
251 this.dataModel_.push.apply(this.dataModel_, items); | |
223 | 252 |
224 var selectedIndex = urls.indexOf(selectedUrl); | 253 var selectedIndex = urls.indexOf(selectedUrl); |
225 this.slideMode_.load(this.items_, selectedIndex, function() { | 254 if (selectedIndex >= 0) |
226 // Flash the toolbar briefly to show it is there. | 255 this.selectionModel_.setIndexSelected(selectedIndex, true); |
227 this.inactivityWatcher_.startActivity(); | 256 else |
228 this.inactivityWatcher_.stopActivity(Gallery.FIRST_FADE_TIMEOUT); | 257 this.onSelection_(); |
229 }.bind(this)); | 258 |
259 this.currentMode_ = opt_grid ? this.gridMode_ : this.slideMode_; | |
260 this.currentMode_.enter(function() { | |
261 // Flash the toolbar briefly to show it is there. | |
262 this.inactivityWatcher_.startActivity(); | |
263 this.inactivityWatcher_.stopActivity(Gallery.FIRST_FADE_TIMEOUT); | |
264 }.bind(this)); | |
230 }; | 265 }; |
231 | 266 |
232 /** | 267 /** |
233 * Close the Gallery. | 268 * Close the Gallery. |
234 * @private | 269 * @private |
235 */ | 270 */ |
236 Gallery.prototype.close_ = function() { | 271 Gallery.prototype.close_ = function() { |
237 Gallery.getFileBrowserPrivate().isFullscreen(function(fullscreen) { | 272 Gallery.getFileBrowserPrivate().isFullscreen(function(fullscreen) { |
238 if (this.originalFullscreen_ != fullscreen) { | 273 if (this.originalFullscreen_ != fullscreen) { |
239 Gallery.toggleFullscreen(); | 274 Gallery.toggleFullscreen(); |
240 } | 275 } |
241 this.context_.onClose(); | 276 this.context_.onClose(); |
242 }.bind(this)); | 277 }.bind(this)); |
243 }; | 278 }; |
244 | 279 |
245 /** | 280 /** |
246 * Handle user's 'Close' action (Escape or a click on the X icon). | 281 * Handle user's 'Close' action (Escape or a click on the X icon). |
247 * @private | 282 * @private |
248 */ | 283 */ |
249 Gallery.prototype.onClose_ = function() { | 284 Gallery.prototype.onClose_ = function() { |
250 this.executeWhenReady(this.close_.bind(this)); | 285 this.executeWhenReady(this.close_.bind(this)); |
251 }; | 286 }; |
252 | 287 |
253 /** | 288 /** |
254 * Execute a function when the editor is done with the modifications. | 289 * Execute a function when the editor is done with the modifications. |
255 * @param {function} callback Function to execute. | 290 * @param {function} callback Function to execute. |
256 */ | 291 */ |
257 Gallery.prototype.executeWhenReady = function(callback) { | 292 Gallery.prototype.executeWhenReady = function(callback) { |
258 //TODO(kaznacheev): Execute directly when in grid mode. | 293 if (this.currentMode_ == this.slideMode_) |
259 this.slideMode_.editor_.executeWhenReady(callback); | 294 this.slideMode_.editor_.executeWhenReady(callback); |
295 else | |
296 callback(); | |
260 }; | 297 }; |
261 | 298 |
262 /** | 299 /** |
263 * @return {Object} File browser private API. | 300 * @return {Object} File browser private API. |
264 */ | 301 */ |
265 Gallery.getFileBrowserPrivate = function() { | 302 Gallery.getFileBrowserPrivate = function() { |
266 return chrome.fileBrowserPrivate || window.top.chrome.fileBrowserPrivate; | 303 return chrome.fileBrowserPrivate || window.top.chrome.fileBrowserPrivate; |
267 }; | 304 }; |
268 | 305 |
269 /** | 306 /** |
270 * Switches gallery to fullscreen mode and back. | 307 * Switches gallery to fullscreen mode and back. |
271 */ | 308 */ |
272 Gallery.toggleFullscreen = function() { | 309 Gallery.toggleFullscreen = function() { |
273 Gallery.getFileBrowserPrivate().toggleFullscreen(); | 310 Gallery.getFileBrowserPrivate().toggleFullscreen(); |
274 }; | 311 }; |
275 | 312 |
276 /** | 313 /** |
277 * @return {boolean} True if some tool is currently active. | 314 * @return {boolean} True if some tool is currently active. |
278 */ | 315 */ |
279 Gallery.prototype.hasActiveTool = function() { | 316 Gallery.prototype.hasActiveTool = function() { |
280 return this.slideMode_.isEditing() || this.isSharing_() || this.isRenaming_(); | 317 return this.currentMode_.hasActiveTool() || |
318 this.isSharing_() || this.isRenaming_(); | |
281 }; | 319 }; |
282 | 320 |
283 /** | 321 /** |
284 * Check if the tools are active and notify the inactivity watcher. | 322 * Check if the tools are active and notify the inactivity watcher. |
285 * @private | 323 * @private |
286 */ | 324 */ |
287 Gallery.prototype.checkActivity_ = function() { | 325 Gallery.prototype.checkActivity_ = function() { |
288 if (this.hasActiveTool()) | 326 if (this.hasActiveTool()) |
289 this.inactivityWatcher_.startActivity(); | 327 this.inactivityWatcher_.startActivity(); |
290 else | 328 else |
291 this.inactivityWatcher_.stopActivity(); | 329 this.inactivityWatcher_.stopActivity(); |
292 }; | 330 }; |
293 | 331 |
294 /** | 332 /** |
295 * Edit toggle event handler. | 333 * External button event handler. |
296 * @private | 334 * @private |
297 */ | 335 */ |
298 Gallery.prototype.onEdit_ = function() { | 336 Gallery.prototype.onModeButton_ = function() { |
299 // The user has just clicked on the Edit button. Dismiss the Share menu. | 337 this.closeShareMenu_(); |
300 if (this.isSharing_()) | |
301 this.onShare_(); | |
302 this.checkActivity_(); | 338 this.checkActivity_(); |
303 }; | 339 }; |
304 | 340 |
305 /** | 341 /** |
342 * Mode toggle event handler. | |
343 * @param {function} opt_callback Callback. | |
344 * @private | |
345 */ | |
346 Gallery.prototype.toggleMode_ = function(opt_callback) { | |
347 this.currentMode_.leave(function() { | |
348 if (this.currentMode_ == this.gridMode_) { | |
349 this.currentMode_ = this.slideMode_; | |
350 this.modeButton_.title = this.displayStringFunction_('mosaic'); | |
351 } else { | |
352 this.currentMode_ = this.gridMode_; | |
353 this.modeButton_.title = this.displayStringFunction_('slide'); | |
354 } | |
355 this.currentMode_.enter(opt_callback); | |
356 this.updateFilename_(); | |
357 }.bind(this)); | |
358 }; | |
359 | |
360 /** | |
361 * Delete event handler. | |
362 * @private | |
363 */ | |
364 Gallery.prototype.onDelete_ = function() { | |
365 var indexes = this.selectionModel_.selectedIndexes; | |
366 for (var i = 0; i != indexes.length; i++) | |
367 this.dataModel_.splice(indexes[i], 1); | |
368 | |
369 // TODO: delete actual files. | |
370 }; | |
371 | |
372 /** | |
306 * @return {Array.<Gallery.Item>} Current selection. | 373 * @return {Array.<Gallery.Item>} Current selection. |
307 */ | 374 */ |
308 Gallery.prototype.getSelectedItems = function() { | 375 Gallery.prototype.getSelectedItems = function() { |
309 // TODO(kaznacheev) support multiple selection grid/mosaic mode. | 376 return this.selectionModel_.selectedIndexes.map(function(index) { |
310 return [this.slideMode_.getSelectedItem()]; | 377 return this.dataModel_.item(index); |
dgozman
2012/08/27 13:23:42
You can use
this.dataModel_.item.bind(this.dataMo
Vladislav Kaznacheev
2012/08/27 14:49:08
Done.
| |
378 }.bind(this)); | |
311 }; | 379 }; |
312 | 380 |
313 /** | 381 /** |
314 * @return {Gallery.Item} Current single selection. | 382 * @return {Gallery.Item} Current single selection. |
315 */ | 383 */ |
316 Gallery.prototype.getSingleSelectedItem = function() { | 384 Gallery.prototype.getSingleSelectedItem = function() { |
317 var items = this.getSelectedItems(); | 385 var items = this.getSelectedItems(); |
318 if (items.length > 1) | 386 if (items.length > 1) |
319 throw new Error('Unexpected multiple selection'); | 387 throw new Error('Unexpected multiple selection'); |
320 return items[0]; | 388 return items[0]; |
321 }; | 389 }; |
322 | 390 |
323 /** | 391 /** |
324 * Selection change event handler. | 392 * Selection change event handler. |
325 * @private | 393 * @private |
326 */ | 394 */ |
327 Gallery.prototype.onSelection_ = function() { | 395 Gallery.prototype.onSelection_ = function() { |
328 this.updateFilename_(); | 396 this.updateFilename_(); |
329 this.shareMode_.updateMenu( | 397 this.updateShareMenu_(); |
330 this.getSelectedItems().map(function(item) { return item.getUrl() })); | |
331 }; | 398 }; |
332 | 399 |
333 /** | 400 /** |
401 * Content change event handler. | |
402 * @private | |
403 */ | |
404 Gallery.prototype.onContentChange_ = function() { | |
405 this.updateFilename_(); | |
406 this.gridMode_.updateThumbnail(this.getSingleSelectedItem()); | |
407 }; | |
408 | |
409 /** | |
334 * Keydown handler. | 410 * Keydown handler. |
335 * @param {Event} event Event. | 411 * @param {Event} event Event. |
336 * @private | 412 * @private |
337 */ | 413 */ |
338 Gallery.prototype.onKeyDown_ = function(event) { | 414 Gallery.prototype.onKeyDown_ = function(event) { |
339 if (this.slideMode_.onKeyDown(event)) | 415 this.closeShareMenu_(); |
416 | |
417 if (this.currentMode_.onKeyDown(event)) | |
340 return; | 418 return; |
341 | 419 |
342 switch (util.getKeyModifiers(event) + event.keyIdentifier) { | 420 switch (util.getKeyModifiers(event) + event.keyIdentifier) { |
343 case 'U+0008': // Backspace. | 421 case 'U+0008': // Backspace. |
344 // The default handler would call history.back and close the Gallery. | 422 // The default handler would call history.back and close the Gallery. |
345 event.preventDefault(); | 423 event.preventDefault(); |
346 break; | 424 break; |
347 | 425 |
348 case 'U+001B': // Escape | 426 case 'U+001B': // Escape |
349 if (this.isSharing_()) | 427 if (this.isSharing_()) |
dgozman
2012/08/27 13:23:42
You have just closed share menu at line 415. Why?
Vladislav Kaznacheev
2012/08/27 14:49:08
Good catch! Rewrote.
On 2012/08/27 13:23:42, dgoz
| |
350 this.onShare_(); | 428 this.toggleShare_(); |
351 else | 429 else |
352 this.onClose_(); | 430 this.onClose_(); |
353 break; | 431 break; |
354 } | 432 } |
355 }; | 433 }; |
356 | 434 |
357 // Name box and rename support. | 435 // Name box and rename support. |
358 | 436 |
359 /** | 437 /** |
360 * Update the displayed current item file name. | 438 * Update the displayed current item file name. |
361 * | 439 * |
362 * @private | 440 * @private |
363 */ | 441 */ |
364 Gallery.prototype.updateFilename_ = function() { | 442 Gallery.prototype.updateFilename_ = function() { |
365 var fullName = this.getSingleSelectedItem().getFileName(); | 443 var displayName = ''; |
444 var fullName = ''; | |
366 | 445 |
367 this.context_.onNameChange(fullName); | 446 var selectedItems = this.getSelectedItems(); |
447 if (selectedItems.length == 1) { | |
448 fullName = selectedItems[0].getFileName(); | |
449 displayName = ImageUtil.getFileNameFromFullName(fullName); | |
450 } else if (selectedItems.length > 1) { | |
451 displayName = | |
452 this.displayStringFunction_('ITEMS_SELECTED', selectedItems.length); | |
453 } | |
368 | 454 |
369 var displayName = ImageUtil.getFileNameFromFullName(fullName); | 455 this.context_.onNameChange( |
456 this.currentMode_ == this.slideMode_ ? fullName : ''); | |
457 | |
370 this.filenameEdit_.value = displayName; | 458 this.filenameEdit_.value = displayName; |
371 this.filenameText_.textContent = displayName; | 459 this.filenameText_.textContent = displayName; |
372 }; | 460 }; |
373 | 461 |
374 /** | 462 /** |
375 * Click event handler on filename edit box | 463 * Click event handler on filename edit box |
376 * @private | 464 * @private |
377 */ | 465 */ |
378 Gallery.prototype.onFilenameClick_ = function() { | 466 Gallery.prototype.onFilenameClick_ = function() { |
379 // We can't rename files in readonly directory. | 467 // We can't rename files in readonly directory. |
380 if (this.context_.readonlyDirName) | 468 if (this.context_.readonlyDirName) |
381 return; | 469 return; |
382 | 470 |
471 // We can only rename a single file. | |
472 if (this.getSelectedItems().length != 1) | |
473 return; | |
474 | |
383 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true); | 475 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true); |
384 setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0); | 476 setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0); |
385 this.inactivityWatcher_.startActivity(); | 477 this.inactivityWatcher_.startActivity(); |
386 }; | 478 }; |
387 | 479 |
388 /** | 480 /** |
389 * Blur event handler on filename edit box | 481 * Blur event handler on filename edit box |
390 * @private | 482 * @private |
391 */ | 483 */ |
392 Gallery.prototype.onFilenameEditBlur_ = function() { | 484 Gallery.prototype.onFilenameEditBlur_ = function() { |
393 if (this.filenameEdit_.value && this.filenameEdit_.value[0] == '.') { | 485 if (this.filenameEdit_.value && this.filenameEdit_.value[0] == '.') { |
394 this.prompt_.show('file_hidden_name', 5000); | 486 this.prompt_.show('file_hidden_name', 5000); |
395 this.filenameEdit_.focus(); | 487 this.filenameEdit_.focus(); |
396 return; | 488 return; |
397 } | 489 } |
398 | 490 |
399 var item = this.getSingleSelectedItem(); | 491 var item = this.getSingleSelectedItem(); |
400 var oldUrl = item.getUrl(); | 492 var oldUrl = item.getUrl(); |
401 | 493 |
402 var onFileExists = function() { | 494 var onFileExists = function() { |
403 this.prompt_.show('file_exists', 3000); | 495 this.prompt_.show('file_exists', 3000); |
404 this.filenameEdit_.value = name; | 496 this.filenameEdit_.value = name; |
405 this.onFilenameClick_(); | 497 this.onFilenameClick_(); |
406 }.bind(this); | 498 }.bind(this); |
407 | 499 |
408 var onSuccess = function() { | 500 var onSuccess = function() { |
409 this.slideMode_.updateSelectedUrl_(oldUrl, item.getUrl()); | 501 this.slideMode_.updateSelectedUrl_(oldUrl, item.getUrl()); |
502 this.updateFilename_(); | |
410 }.bind(this); | 503 }.bind(this); |
411 | 504 |
412 if (this.filenameEdit_.value) { | 505 if (this.filenameEdit_.value) { |
413 this.getSingleSelectedItem().rename(this.context_.saveDirEntry, | 506 this.getSingleSelectedItem().rename(this.context_.saveDirEntry, |
414 this.filenameEdit_.value, onSuccess, onFileExists); | 507 this.filenameEdit_.value, onSuccess, onFileExists); |
415 } | 508 } |
416 | 509 |
417 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false); | 510 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false); |
418 this.checkActivity_(); | 511 this.checkActivity_(); |
419 }; | 512 }; |
(...skipping 22 matching lines...) Expand all Loading... | |
442 */ | 535 */ |
443 Gallery.prototype.isRenaming_ = function() { | 536 Gallery.prototype.isRenaming_ = function() { |
444 return this.filenameSpacer_.hasAttribute('renaming'); | 537 return this.filenameSpacer_.hasAttribute('renaming'); |
445 }; | 538 }; |
446 | 539 |
447 /** | 540 /** |
448 * Content area click handler. | 541 * Content area click handler. |
449 * @private | 542 * @private |
450 */ | 543 */ |
451 Gallery.prototype.onContentClick_ = function() { | 544 Gallery.prototype.onContentClick_ = function() { |
545 this.closeShareMenu_(); | |
452 this.filenameEdit_.blur(); | 546 this.filenameEdit_.blur(); |
453 }; | 547 }; |
454 | 548 |
455 // Share button support. | 549 // Share button support. |
456 | 550 |
457 /** | 551 /** |
458 * @return {boolean} True if the Share mode is active. | 552 * @return {boolean} True if the Share menu is active. |
459 * @private | 553 * @private |
460 */ | 554 */ |
461 Gallery.prototype.isSharing_ = function() { | 555 Gallery.prototype.isSharing_ = function() { |
462 return this.shareMode_.isActive(); | 556 return !this.shareMenu_.hidden; |
557 }; | |
558 | |
559 /** | |
560 * Close Share menu if it is open. | |
561 * @private | |
562 */ | |
563 Gallery.prototype.closeShareMenu_ = function() { | |
564 if (this.isSharing_()) | |
565 this.toggleShare_(); | |
463 }; | 566 }; |
464 | 567 |
465 /** | 568 /** |
466 * Share button handler. | 569 * Share button handler. |
467 * @param {Event} event Event. | 570 * @private |
468 * @private | 571 */ |
469 */ | 572 Gallery.prototype.toggleShare_ = function() { |
470 Gallery.prototype.onShare_ = function(event) { | 573 if (!this.shareButton_.hasAttribute('disabled')) |
471 this.shareMode_.toggle(event); | 574 this.shareMenu_.hidden = !this.shareMenu_.hidden; |
472 this.checkActivity_(); | 575 this.checkActivity_(); |
473 }; | 576 }; |
474 | 577 |
475 /** | 578 /** |
476 * | |
477 * @param {ImageEditor} editor Editor. | |
478 * @param {Element} container Container element. | |
479 * @param {Element} toolbar Toolbar element. | |
480 * @param {function} onClick Click handler. | |
481 * @param {function(function())} actionCallback Function to execute the action. | |
482 * @param {function(string):string} displayStringFunction String formatting | |
483 * function. | |
484 * @constructor | |
485 */ | |
486 function ShareMode(editor, container, toolbar, | |
487 onClick, actionCallback, displayStringFunction) { | |
488 ImageEditor.Mode.call(this, 'share'); | |
489 | |
490 this.message_ = null; | |
491 | |
492 var button = util.createChild(toolbar, 'button share'); | |
493 button.textContent = displayStringFunction('share'); | |
494 button.addEventListener('click', onClick); | |
495 this.bind(editor, button); | |
496 | |
497 this.actionCallback_ = actionCallback; | |
498 | |
499 this.menu_ = util.createChild(container, 'share-menu'); | |
500 this.menu_.hidden = true; | |
501 | |
502 util.createChild(this.menu_, 'bubble-point'); | |
503 } | |
504 | |
505 ShareMode.prototype = { __proto__: ImageEditor.Mode.prototype }; | |
506 | |
507 /** | |
508 * Shows share mode UI. | |
509 */ | |
510 ShareMode.prototype.setUp = function() { | |
511 ImageEditor.Mode.prototype.setUp.apply(this, arguments); | |
512 this.menu_.hidden = false; | |
513 ImageUtil.setAttribute(this.button_, 'pressed', false); | |
514 }; | |
515 | |
516 /** | |
517 * Hides share mode UI. | |
518 */ | |
519 ShareMode.prototype.cleanUpUI = function() { | |
520 ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); | |
521 this.menu_.hidden = true; | |
522 }; | |
523 | |
524 /** | |
525 * @return {boolean} True if the menu is currently open. | |
526 */ | |
527 ShareMode.prototype.isActive = function() { | |
528 return !this.menu_.hidden; | |
529 }; | |
530 | |
531 /** | |
532 * Show/hide the menu. | |
533 * @param {Event} event Event. | |
534 */ | |
535 ShareMode.prototype.toggle = function(event) { | |
536 this.editor_.enterMode(this, event); | |
537 }; | |
538 | |
539 /** | |
540 * Update available actions list based on the currently selected urls. | 579 * Update available actions list based on the currently selected urls. |
541 * | 580 * @private. |
542 * @param {Array.<string>} urls Array of urls. | 581 */ |
543 */ | 582 Gallery.prototype.updateShareMenu_ = function() { |
544 ShareMode.prototype.updateMenu = function(urls) { | 583 var urls = |
584 this.getSelectedItems().map(function(item) { return item.getUrl() }); | |
585 | |
545 var internalId = util.getExtensionId(); | 586 var internalId = util.getExtensionId(); |
546 function isShareAction(task) { | 587 function isShareAction(task) { |
547 var task_parts = task.taskId.split('|'); | 588 var task_parts = task.taskId.split('|'); |
548 return task_parts[0] != internalId; | 589 return task_parts[0] != internalId; |
549 } | 590 } |
550 | 591 |
551 var items = this.menu_.querySelectorAll('.item'); | |
552 for (var i = 0; i != items.length; i++) { | |
553 items[i].parentNode.removeChild(items[i]); | |
554 } | |
555 | |
556 var api = Gallery.getFileBrowserPrivate(); | 592 var api = Gallery.getFileBrowserPrivate(); |
557 api.getFileTasks(urls, function(tasks) { | 593 api.getFileTasks(urls, function(tasks) { |
558 for (var i = 0; i != tasks.length; i++) { | 594 var wasHidden = this.shareMenu_.hidden; |
559 var task = tasks[i]; | 595 this.shareMenu_.hidden = true; |
596 var items = this.shareMenu_.querySelectorAll('.item'); | |
597 for (var i = 0; i != items.length; i++) { | |
598 items[i].parentNode.removeChild(items[i]); | |
599 } | |
600 | |
601 for (var t = 0; t != tasks.length; t++) { | |
602 var task = tasks[t]; | |
560 if (!isShareAction(task)) continue; | 603 if (!isShareAction(task)) continue; |
561 | 604 |
562 var item = document.createElement('div'); | 605 var item = util.createChild(this.shareMenu_, 'item'); |
563 item.className = 'item'; | |
564 this.menu_.appendChild(item); | |
565 | |
566 item.textContent = task.title; | 606 item.textContent = task.title; |
567 item.style.backgroundImage = 'url(' + task.iconUrl + ')'; | 607 item.style.backgroundImage = 'url(' + task.iconUrl + ')'; |
568 item.addEventListener('click', this.actionCallback_.bind(null, | 608 item.addEventListener('click', function(taskId) { |
569 api.executeTask.bind(api, task.taskId, urls))); | 609 this.toggleShare_(); // Hide the menu. |
610 this.executeWhenReady(api.executeTask.bind(api, taskId, urls)); | |
611 }.bind(this, task.taskId)); | |
570 } | 612 } |
571 | 613 |
572 if (this.menu_.firstChild) | 614 var empty = this.shareMenu_.querySelector('.item') == null; |
573 this.button_.removeAttribute('disabled'); | 615 ImageUtil.setAttribute(this.shareButton_, 'disabled', empty); |
574 else | 616 this.shareMenu_.hidden = wasHidden || empty; |
575 this.button_.setAttribute('disabled', 'true'); | |
576 }.bind(this)); | 617 }.bind(this)); |
577 }; | 618 }; |
619 | |
620 /** | |
621 * @param {Element} container Main container. | |
622 * @param {Element} content Content container. | |
623 * @param {cr.ui.ArrayDataModel} dataModel Data model. | |
624 * @param {cr.ui.ListSelectionModel} selectionModel Selection model. | |
625 * @param {MetadataCache} metadataCache Metadata cache. | |
626 * @param {function} openSelectedItem Function to open the selected item in the | |
627 * slide mode. | |
628 * @constructor | |
629 */ | |
630 function GridMode(container, content, dataModel, selectionModel, | |
631 metadataCache, openSelectedItem) { | |
632 this.container_ = container; | |
633 this.metadataCache_ = metadataCache; | |
634 this.grid_ = util.createChild(content, 'thumbnail-grid', 'grid'); | |
635 cr.ui.Grid.decorate(this.grid_); | |
636 | |
637 this.grid_.dataModel = dataModel; | |
638 this.grid_.selectionModel = selectionModel; | |
639 this.grid_.itemConstructor = | |
640 GridMode.Item.bind(null, container.ownerDocument, metadataCache); | |
641 | |
642 this.container_.ownerDocument.defaultView.addEventListener( | |
643 'resize', this.redraw_.bind(this)); | |
644 | |
645 this.openSelectedItem_ = openSelectedItem; | |
646 this.grid_.addEventListener('dblclick', this.openSelectedItem_); | |
647 } | |
648 | |
649 /** | |
650 * Enter the mode. | |
651 * @param {function} opt_callback Callback. | |
652 */ | |
653 GridMode.prototype.enter = function(opt_callback) { | |
654 this.container_.setAttribute('mode', 'grid'); | |
655 this.redraw_(); | |
656 if (opt_callback) opt_callback(); | |
657 }; | |
658 | |
659 /** | |
660 * Leave the mode. | |
661 * @param {function} opt_callback Callback. | |
662 */ | |
663 GridMode.prototype.leave = function(opt_callback) { | |
664 if (opt_callback) opt_callback(); | |
665 }; | |
666 | |
667 /** | |
668 * Redraw the grid. | |
669 * @private | |
670 */ | |
671 GridMode.prototype.redraw_ = function() { | |
672 this.grid_.startBatchUpdates(); | |
673 setTimeout(function() { | |
674 this.grid_.columns = 0; | |
675 this.grid_.redraw(); | |
676 this.grid_.endBatchUpdates(); | |
677 }.bind(this), 0); | |
678 }; | |
679 | |
680 /** | |
681 * @param {Gallery.Item} item The updated item. | |
682 */ | |
683 GridMode.prototype.updateThumbnail = function(item) { | |
684 var listItems = this.grid_.querySelectorAll('li'); | |
685 for (var i = 0; i != listItems.length; i++) { | |
686 GridMode.Item.updateThumbnail(listItems[i], this.metadataCache_, item); | |
687 } | |
688 }; | |
689 | |
690 /** | |
691 * @param {Event} event Event. | |
692 * @return {boolean} True if handled. | |
693 */ | |
694 GridMode.prototype.onKeyDown = function(event) { | |
695 switch (util.getKeyModifiers(event) + event.keyIdentifier) { | |
696 case 'Enter': | |
697 this.openSelectedItem_(); | |
dgozman
2012/08/27 13:23:42
Where is this function defined?
Vladislav Kaznacheev
2012/08/27 14:49:08
line 645
On 2012/08/27 13:23:42, dgozman wrote:
| |
698 return true; | |
699 } | |
700 | |
701 return false; | |
702 }; | |
703 | |
704 /** | |
705 * @return {boolean} Always true (no tools fading in the Grid mode). | |
706 */ | |
707 GridMode.prototype.hasActiveTool = function() { | |
708 return true; | |
709 }; | |
710 | |
711 /** | |
712 * @param {Document} document Document. | |
713 * @param {MetadataCache} metadataCache Metadata cache. | |
714 * @param {Gallery.Item} item Item. | |
715 * @return {Element} Newly created grid item. | |
716 * @constructor | |
717 */ | |
718 GridMode.Item = function(document, metadataCache, item) { | |
719 var li = document.createElement('li'); | |
720 li.__proto__ = GridMode.Item.prototype; | |
721 li.className = 'thumbnail-item'; | |
722 li.item = item; | |
723 | |
724 var box = util.createChild(li, 'img-container'); | |
725 | |
726 GridMode.Item.updateThumbnail(li, metadataCache, item); | |
727 return li; | |
728 }; | |
729 | |
730 /** | |
731 * @param {Element} li Grid item. | |
732 * @param {MetadataCache} metadataCache Metadata cache. | |
733 * @param {Gallery.Item} item Gallery item. | |
734 */ | |
735 GridMode.Item.updateThumbnail = function(li, metadataCache, item) { | |
736 if (item != li.item) | |
737 return; | |
738 | |
739 var box = li.querySelector('.img-container'); | |
740 var url = item.getUrl(); | |
741 metadataCache.get(url, Gallery.METADATA_TYPE, | |
742 function(metadata) { | |
743 new ThumbnailLoader(url, metadata).load(box, false /* fit */); | |
744 }); | |
745 }; | |
746 | |
747 GridMode.Item.prototype = { | |
748 __proto__: cr.ui.ListItem.prototype, | |
749 get label() {}, | |
750 set label(value) {} | |
751 }; | |
OLD | NEW |