Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6226)

Unified Diff: chrome/browser/resources/file_manager/js/photo/slide_mode.js

Issue 10829421: First cut of the updated Photo Editor UI (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Small fix Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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');
};
/**

Powered by Google App Engine
This is Rietveld 408576698