Index: chrome/browser/resources/file_manager/js/photo/slide_mode.js |
diff --git a/chrome/browser/resources/file_manager/js/photo/slide_mode.js b/chrome/browser/resources/file_manager/js/photo/slide_mode.js |
index ceb026f463e640c4435db9dfde0e7c77c51ddf4b..90e049055ef79bab545ac8b977697452c47a8833 100644 |
--- a/chrome/browser/resources/file_manager/js/photo/slide_mode.js |
+++ b/chrome/browser/resources/file_manager/js/photo/slide_mode.js |
@@ -6,23 +6,36 @@ |
* Slide mode displays a single image and has a set of controls to navigate |
* between the images and to edit an image. |
* |
- * @param {Element} container Container element. |
+ * TODO(kaznacheev): Introduce a parameter object. |
+ * |
+ * @param {Element} container Main container element. |
+ * @param {Element} content Content container element. |
* @param {Element} toolbar Toolbar element. |
* @param {ImageEditor.Prompt} prompt Prompt. |
+ * @param {cr.ui.ArrayDataModel} dataModel Data model. |
+ * @param {cr.ui.ListSelectionModel} selectionModel Selection model. |
* @param {Object} context Context. |
* @param {function(string):string} displayStringFunction String formatting |
* function. |
* @constructor |
*/ |
-function SlideMode(container, toolbar, prompt, context, displayStringFunction) { |
+function SlideMode(container, content, toolbar, prompt, |
+ dataModel, selectionModel, |
+ context, displayStringFunction) { |
this.container_ = container; |
- this.toolbar_ = toolbar; |
this.document_ = container.ownerDocument; |
+ this.content = content; |
+ this.toolbar_ = toolbar; |
this.prompt_ = prompt; |
+ this.dataModel_ = dataModel; |
+ this.selectionModel_ = selectionModel; |
this.context_ = context; |
this.metadataCache_ = context.metadataCache; |
this.displayStringFunction_ = displayStringFunction; |
+ this.onSelectionBound_ = this.onSelection_.bind(this); |
+ this.onSpliceBound_ = this.onSplice_.bind(this); |
+ |
this.initListeners_(); |
this.initDom_(); |
} |
@@ -136,6 +149,9 @@ SlideMode.prototype.initDom_ = function() { |
util.createChild(this.arrowRight_); |
this.ribbonSpacer_ = util.createChild(this.toolbar_, 'ribbon-spacer'); |
+ this.ribbon_ = new Ribbon(this.document_, |
+ this.metadataCache_, this.dataModel_, this.selectionModel_); |
+ this.ribbonSpacer_.appendChild(this.ribbon_); |
// Error indicator. |
var errorWrapper = util.createChild(this.container_, 'prompt-wrapper'); |
@@ -145,12 +161,16 @@ SlideMode.prototype.initDom_ = function() { |
util.createChild(this.container_, 'spinner'); |
+ this.slideShowButton_ = util.createChild(this.toolbar_, 'button slideshow'); |
+ this.slideShowButton_.title = this.displayStringFunction_('slideshow'); |
+ this.slideShowButton_.addEventListener('click', |
+ this.toggleSlideshow_.bind(this, SlideMode.SLIDESHOW_INTERVAL_FIRST)); |
- this.editButton_ = util.createChild(this.toolbar_, 'button edit'); |
- this.editButton_.textContent = this.displayStringFunction_('edit'); |
- this.editButton_.addEventListener('click', this.onEdit_.bind(this)); |
+ // Editor. |
- // Editor toolbar. |
+ this.editButton_ = util.createChild(this.toolbar_, 'button edit'); |
+ this.editButton_.title = this.displayStringFunction_('edit'); |
+ this.editButton_.addEventListener('click', this.toggleEditor_.bind(this)); |
this.editBar_ = util.createChild(this.toolbar_, 'edit-bar'); |
this.editBarMain_ = util.createChild(this.editBar_, 'edit-main'); |
@@ -168,8 +188,6 @@ SlideMode.prototype.initDom_ = function() { |
this.viewport_, |
this.metadataCache_); |
- this.imageView_.addContentCallback(this.onImageContentChanged_.bind(this)); |
- |
this.editor_ = new ImageEditor( |
this.viewport_, |
this.imageView_, |
@@ -190,109 +208,164 @@ SlideMode.prototype.initDom_ = function() { |
/** |
* Load items, display the selected item. |
* |
- * @param {Array.<Gallery.Item>} items Array of items. |
- * @param {number} selectedIndex Selected index. |
- * @param {function} callback Callback. |
+ * @param {function} opt_callback Callback. |
*/ |
-SlideMode.prototype.load = function(items, selectedIndex, callback) { |
- var selectedItem = items[selectedIndex]; |
- if (!selectedItem) { |
- this.showErrorBanner_('IMAGE_ERROR'); |
- return; |
- } |
+SlideMode.prototype.enter = function(opt_callback) { |
+ this.container_.setAttribute('mode', 'slide'); |
+ |
+ this.sequenceDirection_ = 0; |
+ this.sequenceLength_ = 0; |
var loadDone = function() { |
- this.items_ = items; |
- this.setSelectedIndex_(selectedIndex); |
- this.setupNavigation_(); |
- setTimeout(this.requestPrefetch.bind(this, 1 /* Next item */), 1000); |
- callback(); |
+ this.active_ = true; |
+ |
+ this.selectionModel_.addEventListener('change', this.onSelectionBound_); |
+ this.dataModel_.addEventListener('splice', this.onSpliceBound_); |
+ |
+ this.ribbon_.enable(); |
+ |
+ this.prefetchTimer_ = setTimeout(function() { |
+ this.prefetchTimer_ = null; |
+ this.requestPrefetch(1); // Prefetch the next image. |
+ }.bind(this), 1000); |
+ if (opt_callback) opt_callback(); |
}.bind(this); |
- var selectedUrl = selectedItem.getUrl(); |
- // Show the selected item ASAP, then complete the initialization |
- // (loading the ribbon thumbnails can take some time). |
- this.metadataCache_.get(selectedUrl, Gallery.METADATA_TYPE, |
- function(metadata) { |
- this.loadItem_(selectedUrl, metadata, 0, loadDone); |
- }.bind(this)); |
+ if (this.getItemCount_() == 0) { |
+ this.displayedIndex_ = -1; |
+ //TODO(kaznacheev) Show this message in the grid mode too. |
+ this.showErrorBanner_('NO_IMAGES'); |
+ loadDone(); |
+ } else { |
+ // Ensure valid single selection. |
+ // Note that the SlideMode object is not listening to selection change yet. |
+ this.select(Math.max(0, this.getSelectedIndex())); |
+ cr.dispatchSimpleEvent(this, 'namechange'); // Update name in the UI. |
+ this.displayedIndex_ = this.getSelectedIndex(); |
+ |
+ var selectedItem = this.getSelectedItem(); |
+ var selectedUrl = selectedItem.getUrl(); |
+ // Show the selected item ASAP, then complete the initialization |
+ // (loading the ribbon thumbnails can take some time). |
+ this.metadataCache_.get(selectedUrl, Gallery.METADATA_TYPE, |
+ function(metadata) { |
+ this.loadItem_(selectedUrl, metadata, 0, loadDone); |
+ }.bind(this)); |
+ |
+ } |
+}; |
+ |
+/** |
+ * Leave the mode. |
+ * @param {function} opt_callback Callback. |
+ */ |
+SlideMode.prototype.leave = function(opt_callback) { |
+ if (this.prefetchTimer_) { |
+ clearTimeout(this.prefetchTimer_); |
+ this.prefetchTimer_ = null; |
+ } |
+ |
+ var commitDone = function() { |
+ this.stopEditing_(); |
+ this.stopSlideshow_(); |
+ this.unloadImage_(); |
+ this.selectionModel_.removeEventListener( |
+ 'change', this.onSelectionBound_); |
+ this.dataModel_.removeEventListener('splice', this.onSpliceBound_); |
+ this.ribbon_.disable(); |
+ this.active_ = false; |
+ if (opt_callback) opt_callback(); |
+ }.bind(this); |
+ |
+ if (this.getItemCount_() == 0) { |
+ this.showErrorBanner_(false); |
+ commitDone(); |
+ } else { |
+ this.commitItem_(commitDone); |
+ } |
}; |
/** |
- * Setup navigation controls. |
+ * @return {boolean} True if the mode has active tools (that should not fade). |
+ */ |
+SlideMode.prototype.hasActiveTool = function() { |
+ return this.isEditing(); |
+}; |
+ |
+/** |
+ * @return {number} Item count. |
* @private |
*/ |
-SlideMode.prototype.setupNavigation_ = function() { |
- this.sequenceDirection_ = 0; |
- this.sequenceLength_ = 0; |
+SlideMode.prototype.getItemCount_ = function() { |
+ return this.dataModel_.length; |
+}; |
- ImageUtil.setAttribute(this.arrowLeft_, 'active', this.items_.length > 1); |
- ImageUtil.setAttribute(this.arrowRight_, 'active', this.items_.length > 1); |
+/** |
+ * @param {number} index Index. |
+ * @return {Gallery.Item} Item. |
+ */ |
+SlideMode.prototype.getItem = function(index) { |
+ return this.dataModel_.item(index); |
+}; |
- this.ribbon_ = new Ribbon( |
- this.document_, this.metadataCache_, this.select.bind(this)); |
- this.ribbonSpacer_.appendChild(this.ribbon_); |
- this.ribbon_.update(this.items_, this.selectedIndex_); |
+/** |
+ * @return {Gallery.Item} Selected index. |
+ */ |
+SlideMode.prototype.getSelectedIndex = function() { |
+ return this.selectionModel_.selectedIndexes.length ? |
+ this.selectionModel_.selectedIndexes[0] : |
+ -1; |
}; |
/** |
* @return {Gallery.Item} Selected item |
*/ |
SlideMode.prototype.getSelectedItem = function() { |
- return this.items_ && this.items_[this.selectedIndex_]; |
+ return this.getItem(this.getSelectedIndex()); |
}; |
/** |
- * Change the selection. |
- * |
- * Commits the current image and changes the selection. |
+ * Selection change handler. |
* |
- * @param {number} index New selected index. |
- * @param {number} opt_slideDir Slide animation direction (-1|0|1). |
- * Derived from the new and the old selected indices if omitted. |
- * @param {function} opt_callback Callback. |
+ * Commits the current image and displays the newly selected image. |
+ * @private |
*/ |
-SlideMode.prototype.select = function(index, opt_slideDir, opt_callback) { |
- if (!this.items_) |
- return; // Not fully initialized, still loading the first image. |
+SlideMode.prototype.onSelection_ = function() { |
+ if (this.selectionModel_.selectedIndexes.length == 0) |
+ return; // Temporary empty selection. |
- if (index == this.selectedIndex_) |
+ if (this.getSelectedIndex() == this.displayedIndex_) |
return; // Do not reselect. |
- this.commitItem_( |
- this.doSelect_.bind(this, index, opt_slideDir, opt_callback)); |
+ this.commitItem_(this.loadSelectedItem_.bind(this)); |
}; |
/** |
- * Set the new selected index value. |
+ * Change the selection. |
+ * |
* @param {number} index New selected index. |
- * @private |
+ * @param {number} opt_slideHint Slide animation direction (-1|1). |
*/ |
-SlideMode.prototype.setSelectedIndex_ = function(index) { |
- this.selectedIndex_ = index; |
- cr.dispatchSimpleEvent(this, 'selection'); |
- |
- // For once edited image, disallow the 'overwrite' setting change. |
- ImageUtil.setAttribute(this.options_, 'saved', |
- !this.getSelectedItem().isOriginal()); |
+SlideMode.prototype.select = function(index, opt_slideHint) { |
+ this.slideHint_ = opt_slideHint; |
+ this.selectionModel_.unselectAll(); |
+ this.selectionModel_.setIndexSelected(index, true); |
}; |
/** |
- * Perform the actual selection change. |
+ * Load the selected item. |
* |
- * @param {number} index New selected index. |
- * @param {number} opt_slideDir Slide animation direction (-1|0|1). |
- * Derived from the new and the old selected indices if omitted. |
- * @param {function} opt_callback Callback. |
* @private |
*/ |
-SlideMode.prototype.doSelect_ = function(index, opt_slideDir, opt_callback) { |
- if (index == this.selectedIndex_) |
- return; // Do not reselect |
+SlideMode.prototype.loadSelectedItem_ = function() { |
+ var slideHint = this.slideHint_; |
+ this.slideHint_ = undefined; |
+ |
+ var index = this.getSelectedIndex(); |
+ if (index == this.displayedIndex_) |
+ return; // Do not reselect. |
- var step = opt_slideDir != undefined ? |
- opt_slideDir : |
- (index - this.selectedIndex_); |
+ var step = slideHint || (index - this.displayedIndex_); |
if (Math.abs(step) != 1) { |
// Long leap, the sequence is broken, we have no good prefetch candidate. |
@@ -310,13 +383,10 @@ SlideMode.prototype.doSelect_ = function(index, opt_slideDir, opt_callback) { |
if (this.sequenceLength_ <= 1) { |
// We have just broke the sequence. Touch the current image so that it stays |
// in the cache longer. |
- this.editor_.prefetchImage(this.getSelectedItem().getUrl()); |
+ this.imageView_.prefetch(this.imageView_.contentID_); |
} |
- this.setSelectedIndex_(index); |
- |
- if (this.ribbon_) |
- this.ribbon_.update(this.items_, this.selectedIndex_); |
+ this.displayedIndex_ = index; |
function shouldPrefetch(loadType, step, sequenceLength) { |
// Never prefetch when selecting out of sequence. |
@@ -345,7 +415,8 @@ SlideMode.prototype.doSelect_ = function(index, opt_slideDir, opt_callback) { |
if (shouldPrefetch(loadType, step, this.sequenceLength_)) { |
this.requestPrefetch(step); |
} |
- if (opt_callback) opt_callback(); |
+ if (this.isSlideshowOn_()) |
+ this.scheduleNextSlide_(); |
}.bind(this)); |
}.bind(this); |
this.metadataCache_.get( |
@@ -353,24 +424,65 @@ SlideMode.prototype.doSelect_ = function(index, opt_slideDir, opt_callback) { |
}; |
/** |
+ * Unload the current image. |
+ * @private |
+ */ |
+SlideMode.prototype.unloadImage_ = function() { |
+ this.imageView_.unload(); |
+ this.container_.removeAttribute('video'); |
+}; |
+ |
+/** |
+ * Data model 'splice' event handler. |
+ * @param {Event} event Event. |
+ * @private |
+ */ |
+SlideMode.prototype.onSplice_ = function(event) { |
+ ImageUtil.setAttribute(this.arrowLeft_, 'active', this.getItemCount_() > 1); |
+ ImageUtil.setAttribute(this.arrowRight_, 'active', this.getItemCount_() > 1); |
+ |
+ if (event.removed.length != 1) |
+ return; |
+ |
+ // Delay the selection to let the ribbon splice handler work first. |
+ setTimeout(function() { |
+ if (event.index < this.dataModel_.length) { |
+ // There is the next item, select it. |
+ // The next item is now at the same index as the removed one, so we need |
+ // to correct displayIndex_. |
dgozman
2012/08/27 15:07:43
I think, this is done for nice animation? Needs a
|
+ this.displayedIndex_ = event.index - 1; |
+ this.select(event.index); |
+ } else if (this.dataModel_.length) { |
+ // Removed item is the rightmost, but there are more items. |
+ this.select(event.index - 1); // Select the new last index. |
+ } else { |
+ // No items left. Unload the image and show the banner. |
+ this.commitItem_(function() { |
+ this.unloadImage_(); |
+ this.showErrorBanner_('NO_IMAGES'); |
+ }.bind(this)); |
+ } |
+ }.bind(this), 0); |
+}; |
+ |
+/** |
* @param {number} direction -1 for left, 1 for right. |
* @return {number} Next index in the gived direction, with wrapping. |
* @private |
*/ |
SlideMode.prototype.getNextSelectedIndex_ = function(direction) { |
- var index = this.selectedIndex_ + (direction > 0 ? 1 : -1); |
- if (index == -1) return this.items_.length - 1; |
- if (index == this.items_.length) return 0; |
+ var index = this.getSelectedIndex() + (direction > 0 ? 1 : -1); |
+ if (index == -1) return this.getItemCount_() - 1; |
+ if (index == this.getItemCount_()) return 0; |
return index; |
}; |
/** |
* Select the next item. |
* @param {number} direction -1 for left, 1 for right. |
- * @param {function} opt_callback Callback. |
*/ |
-SlideMode.prototype.selectNext = function(direction, opt_callback) { |
- this.select(this.getNextSelectedIndex_(direction), direction, opt_callback); |
+SlideMode.prototype.selectNext = function(direction) { |
+ this.select(this.getNextSelectedIndex_(direction), direction); |
}; |
/** |
@@ -384,7 +496,7 @@ SlideMode.prototype.selectFirst = function() { |
* Select the last item. |
*/ |
SlideMode.prototype.selectLast = function() { |
- this.select(this.items_.length - 1); |
+ this.select(this.getItemCount_() - 1); |
}; |
// Loading/unloading |
@@ -415,10 +527,8 @@ SlideMode.prototype.loadItem_ = function(url, metadata, slide, callback) { |
} |
if (video) { |
- if (this.isEditing()) { |
- // The editor toolbar does not make sense for video, hide it. |
- this.onEdit_(); |
- } |
+ // The editor toolbar does not make sense for video, hide it. |
+ this.stopEditing_(); |
this.mediaControls_.attachMedia(this.imageView_.getVideo()); |
//TODO(kaznacheev): Add metrics for video playback. |
} else { |
@@ -440,6 +550,19 @@ SlideMode.prototype.loadItem_ = function(url, metadata, slide, callback) { |
ImageUtil.getMetricName('FileType'), ext, ImageUtil.FILE_TYPES); |
} |
+ // For once edited image, disallow the 'overwrite' setting change. |
+ ImageUtil.setAttribute(this.options_, 'saved', |
+ !this.getSelectedItem().isOriginal()); |
+ |
+ var times = SlideMode.OVERWRITE_BUBBLE_KEY in localStorage ? |
+ parseInt(localStorage[SlideMode.OVERWRITE_BUBBLE_KEY], 10) : 0; |
+ if (times < SlideMode.OVERWRITE_BUBBLE_MAX_TIMES) { |
+ this.bubble_.hidden = false; |
+ if (this.isEditing()) { |
+ localStorage[SlideMode.OVERWRITE_BUBBLE_KEY] = times + 1; |
+ } |
+ } |
+ |
callback(loadType); |
}.bind(this); |
@@ -470,10 +593,10 @@ SlideMode.prototype.commitItem_ = function(callback) { |
* @param {number} direction -1 or 1. |
*/ |
SlideMode.prototype.requestPrefetch = function(direction) { |
- if (this.items_.length <= 1) return; |
+ if (this.getItemCount_() <= 1) return; |
var index = this.getNextSelectedIndex_(direction); |
- var nextItemUrl = this.items_[index].getUrl(); |
+ var nextItemUrl = this.getItem(index).getUrl(); |
var selectedItem = this.getSelectedItem(); |
this.metadataCache_.get(nextItemUrl, Gallery.METADATA_TYPE, |
@@ -541,17 +664,17 @@ SlideMode.prototype.onKeyDown = function(event) { |
break; |
case 'U+0045': // 'e' toggles the editor |
- this.onEdit_(); |
+ this.toggleEditor_(); |
break; |
case 'U+001B': // Escape |
if (!this.isEditing()) |
return false; // Not handled. |
- this.onEdit_(); |
+ this.toggleEditor_(); |
break; |
- case 'Ctrl-U+00DD': // Ctrl+] (cryptic on purpose). |
- this.toggleSlideshow_(); |
+ case 'Ctrl-U+00DD': // Ctrl+]. TODO(kaznacheev): Find a non-cryptic key. |
+ this.toggleSlideshow_(SlideMode.SLIDESHOW_INTERVAL_FIRST); |
break; |
case 'Home': |
@@ -614,8 +737,24 @@ SlideMode.prototype.saveCurrentImage_ = function(callback) { |
this.flashSavedLabel_(); |
var newUrl = item.getUrl(); |
this.updateSelectedUrl_(oldUrl, newUrl); |
- this.ribbon_.updateThumbnail( |
- this.selectedIndex_, newUrl, this.selectedImageMetadata_); |
+ this.ribbon_.updateThumbnail(newUrl, this.selectedImageMetadata_); |
+ cr.dispatchSimpleEvent(this, 'content'); |
+ |
+ if (this.imageView_.getContentRevision() == 1) { // First edit. |
+ // Lock the 'Overwrite original' checkbox for this item. |
+ ImageUtil.setAttribute(this.options_, 'saved', true); |
+ ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit')); |
+ } |
+ |
+ if (oldUrl != newUrl) { |
+ this.displayedIndex_++; |
+ // This splice call will change the selection change event. SlideMode |
+ // will ignore it as the selected item is the same. |
+ // The ribbon will redraw while being obscured by the Editor toolbar, |
+ // so there is no need for nice animation here. |
+ this.dataModel_.splice( |
+ this.getSelectedIndex(), 0, new Gallery.Item(oldUrl)); |
+ } |
callback(); |
}.bind(this)); |
}; |
@@ -635,9 +774,6 @@ SlideMode.prototype.updateSelectedUrl_ = function(oldUrl, newUrl) { |
this.imageView_.changeUrl(newUrl); |
this.ribbon_.remapCache(oldUrl, newUrl); |
- |
- // Let the gallery know that the selected item url has changed. |
- cr.dispatchSimpleEvent(this, 'selection'); |
}; |
/** |
@@ -698,52 +834,85 @@ SlideMode.prototype.onCloseBubble_ = function() { |
SlideMode.OVERWRITE_BUBBLE_MAX_TIMES; |
}; |
+// Slideshow |
+ |
/** |
- * Callback called when the image is edited. |
- * @private |
+ * Slideshow interval in ms. |
*/ |
-SlideMode.prototype.onImageContentChanged_ = function() { |
- var revision = this.imageView_.getContentRevision(); |
- if (revision == 0) { |
- // Just loaded. |
- var times = SlideMode.OVERWRITE_BUBBLE_KEY in localStorage ? |
- parseInt(localStorage[SlideMode.OVERWRITE_BUBBLE_KEY], 10) : 0; |
- if (times < SlideMode.OVERWRITE_BUBBLE_MAX_TIMES) { |
- this.bubble_.hidden = false; |
- if (this.isEditing()) { |
- localStorage[SlideMode.OVERWRITE_BUBBLE_KEY] = times + 1; |
- } |
- } |
- } |
+SlideMode.SLIDESHOW_INTERVAL = 5000; |
- if (revision == 1) { |
- // First edit. |
- ImageUtil.setAttribute(this.options_, 'saved', true); |
- ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit')); |
- } |
+/** |
+ * First slideshow interval in ms. It should be shorter so that the user |
+ * is not guessing whether the button worked. |
+ */ |
+SlideMode.SLIDESHOW_INTERVAL_FIRST = 1000; |
+ |
+/** |
+ * @return {boolean} True if the slideshow is on. |
+ * @private |
+ */ |
+SlideMode.prototype.isSlideshowOn_ = function() { |
+ return this.container_.hasAttribute('slideshow'); |
}; |
-// Misc |
+/** |
+ * Stop the slideshow if it is on. |
+ * @private |
+ */ |
+SlideMode.prototype.stopSlideshow_ = function() { |
+ if (this.isSlideshowOn_()) |
+ this.toggleSlideshow_(); |
+}; |
/** |
- * Start/stop the slide show. |
+ * Start/stop the slideshow. |
+ * |
+ * @param {number} opt_interval First interval in ms. |
+ * @param {Event} opt_event Event. |
* @private |
*/ |
-SlideMode.prototype.toggleSlideshow_ = function() { |
- if (this.slideShowTimeout_) { |
- clearInterval(this.slideShowTimeout_); |
- this.slideShowTimeout_ = null; |
+ |
+SlideMode.prototype.toggleSlideshow_ = function(opt_interval, opt_event) { |
+ if (opt_event) // Caused by user action, notify the Gallery. |
+ cr.dispatchSimpleEvent(this, 'useraction'); |
+ |
+ if (!this.active_) { |
+ // Enter the slide mode. Show the first image for the full interval. |
+ this.enter(this.toggleSlideshow_.bind(this, SlideMode.SLIDESHOW_INTERVAL)); |
+ return; |
+ } |
+ |
+ this.stopEditing_(); |
+ ImageUtil.setAttribute(this.container_, 'slideshow', !this.isSlideshowOn_()); |
+ ImageUtil.setAttribute( |
+ this.slideShowButton_, 'pressed', this.isSlideshowOn_()); |
+ |
+ if (this.isSlideshowOn_()) { |
+ this.scheduleNextSlide_(opt_interval); |
} else { |
- var self = this; |
- function nextSlide() { |
- self.selectNext(1, |
- function() { self.slideShowTimeout_ = setTimeout(nextSlide, 5000) }); |
+ if (this.slideShowTimeout_) { |
+ clearInterval(this.slideShowTimeout_); |
+ this.slideShowTimeout_ = null; |
} |
- nextSlide(); |
} |
}; |
/** |
+ * @param {number} opt_interval Slideshow interval in ms. |
+ * @private |
+ */ |
+SlideMode.prototype.scheduleNextSlide_ = function(opt_interval) { |
+ if (this.slideShowTimeout_) |
+ clearTimeout(this.slideShowTimeout_); |
+ |
+ this.slideShowTimeout_ = setTimeout(function() { |
+ this.slideShowTimeout_ = null; |
+ this.selectNext(1); |
+ }.bind(this), |
+ opt_interval || SlideMode.SLIDESHOW_INTERVAL); |
+}; |
+ |
+/** |
* @return {boolean} True if the editor is active. |
*/ |
SlideMode.prototype.isEditing = function() { |
@@ -751,10 +920,29 @@ SlideMode.prototype.isEditing = function() { |
}; |
/** |
+ * Stop editing. |
+ * @private |
+ */ |
+SlideMode.prototype.stopEditing_ = function() { |
+ if (this.isEditing()) |
+ this.toggleEditor_(); |
+}; |
+ |
+/** |
* Activate/deactivate editor. |
+ * @param {Event} opt_event Event. |
* @private |
*/ |
-SlideMode.prototype.onEdit_ = function() { |
+SlideMode.prototype.toggleEditor_ = function(opt_event) { |
+ if (opt_event) // Caused by user action, notify the Gallery. |
+ cr.dispatchSimpleEvent(this, 'useraction'); |
+ |
+ if (!this.active_) { |
+ this.enter(this.toggleEditor_.bind(this)); |
+ return; |
+ } |
+ |
+ this.stopSlideshow_(); |
if (!this.isEditing() && this.isShowingVideo_()) |
return; // No editing for videos. |
@@ -770,8 +958,6 @@ SlideMode.prototype.onEdit_ = function() { |
} |
ImageUtil.setAttribute(this.editButton_, 'pressed', this.isEditing()); |
- |
- cr.dispatchSimpleEvent(this, 'edit'); |
}; |
/** |