| 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
|
| deleted file mode 100644
|
| index fe07754df54b104cab0b57dfc8d1a201ee2e0b34..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/resources/file_manager/js/photo/slide_mode.js
|
| +++ /dev/null
|
| @@ -1,1343 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -'use strict';
|
| -
|
| -/**
|
| - * Slide mode displays a single image and has a set of controls to navigate
|
| - * between the images and to edit an image.
|
| - *
|
| - * 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(function())} toggleMode Function to toggle the Gallery mode.
|
| - * @param {function(string):string} displayStringFunction String formatting
|
| - * function.
|
| - * @constructor
|
| - */
|
| -function SlideMode(container, content, toolbar, prompt,
|
| - dataModel, selectionModel, context,
|
| - toggleMode, displayStringFunction) {
|
| - this.container_ = container;
|
| - 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.toggleMode_ = toggleMode;
|
| - this.displayStringFunction_ = displayStringFunction;
|
| -
|
| - this.onSelectionBound_ = this.onSelection_.bind(this);
|
| - this.onSpliceBound_ = this.onSplice_.bind(this);
|
| - this.onContentBound_ = this.onContentChange_.bind(this);
|
| -
|
| - // Unique numeric key, incremented per each load attempt used to discard
|
| - // old attempts. This can happen especially when changing selection fast or
|
| - // Internet connection is slow.
|
| - this.currentUniqueKey_ = 0;
|
| -
|
| - this.initListeners_();
|
| - this.initDom_();
|
| -}
|
| -
|
| -/**
|
| - * SlideMode extends cr.EventTarget.
|
| - */
|
| -SlideMode.prototype.__proto__ = cr.EventTarget.prototype;
|
| -
|
| -/**
|
| - * List of available editor modes.
|
| - * @type {Array.<ImageEditor.Mode>}
|
| - */
|
| -SlideMode.editorModes = [
|
| - new ImageEditor.Mode.InstantAutofix(),
|
| - new ImageEditor.Mode.Crop(),
|
| - new ImageEditor.Mode.Exposure(),
|
| - new ImageEditor.Mode.OneClick(
|
| - 'rotate_left', 'GALLERY_ROTATE_LEFT', new Command.Rotate(-1)),
|
| - new ImageEditor.Mode.OneClick(
|
| - 'rotate_right', 'GALLERY_ROTATE_RIGHT', new Command.Rotate(1))
|
| -];
|
| -
|
| -/**
|
| - * @return {string} Mode name.
|
| - */
|
| -SlideMode.prototype.getName = function() { return 'slide' };
|
| -
|
| -/**
|
| - * @return {string} Mode title.
|
| - */
|
| -SlideMode.prototype.getTitle = function() { return 'GALLERY_SLIDE' };
|
| -
|
| -/**
|
| - * Initialize the listeners.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.initListeners_ = function() {
|
| - window.addEventListener('resize', this.onResize_.bind(this), false);
|
| -};
|
| -
|
| -/**
|
| - * Initialize the UI.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.initDom_ = function() {
|
| - // Container for displayed image or video.
|
| - this.imageContainer_ = util.createChild(
|
| - this.document_.querySelector('.content'), 'image-container');
|
| - this.imageContainer_.addEventListener('click', this.onClick_.bind(this));
|
| -
|
| - this.document_.addEventListener('click', this.onDocumentClick_.bind(this));
|
| -
|
| - // Overwrite options and info bubble.
|
| - this.options_ = util.createChild(
|
| - this.toolbar_.querySelector('.filename-spacer'), 'options');
|
| -
|
| - this.savedLabel_ = util.createChild(this.options_, 'saved');
|
| - this.savedLabel_.textContent = this.displayStringFunction_('GALLERY_SAVED');
|
| -
|
| - var overwriteOriginalBox =
|
| - util.createChild(this.options_, 'overwrite-original');
|
| -
|
| - this.overwriteOriginal_ = util.createChild(
|
| - overwriteOriginalBox, 'common white', 'input');
|
| - this.overwriteOriginal_.type = 'checkbox';
|
| - this.overwriteOriginal_.id = 'overwrite-checkbox';
|
| - util.platform.getPreference(SlideMode.OVERWRITE_KEY, function(value) {
|
| - // Out-of-the box default is 'true'
|
| - this.overwriteOriginal_.checked =
|
| - (typeof value != 'string' || value == 'true');
|
| - }.bind(this));
|
| - this.overwriteOriginal_.addEventListener('click',
|
| - this.onOverwriteOriginalClick_.bind(this));
|
| -
|
| - var overwriteLabel = util.createChild(overwriteOriginalBox, '', 'label');
|
| - overwriteLabel.textContent =
|
| - this.displayStringFunction_('GALLERY_OVERWRITE_ORIGINAL');
|
| - overwriteLabel.setAttribute('for', 'overwrite-checkbox');
|
| -
|
| - this.bubble_ = util.createChild(this.toolbar_, 'bubble');
|
| - this.bubble_.hidden = true;
|
| -
|
| - var bubbleContent = util.createChild(this.bubble_);
|
| - bubbleContent.innerHTML = this.displayStringFunction_(
|
| - 'GALLERY_OVERWRITE_BUBBLE');
|
| -
|
| - util.createChild(this.bubble_, 'pointer bottom', 'span');
|
| -
|
| - var bubbleClose = util.createChild(this.bubble_, 'close-x');
|
| - bubbleClose.addEventListener('click', this.onCloseBubble_.bind(this));
|
| -
|
| - // Video player controls.
|
| - this.mediaSpacer_ =
|
| - util.createChild(this.container_, 'video-controls-spacer');
|
| - this.mediaToolbar_ = util.createChild(this.mediaSpacer_, 'tool');
|
| - this.mediaControls_ = new VideoControls(
|
| - this.mediaToolbar_,
|
| - this.showErrorBanner_.bind(this, 'GALLERY_VIDEO_ERROR'),
|
| - this.displayStringFunction_.bind(this),
|
| - this.toggleFullScreen_.bind(this),
|
| - this.container_);
|
| -
|
| - // Ribbon and related controls.
|
| - this.arrowBox_ = util.createChild(this.container_, 'arrow-box');
|
| -
|
| - this.arrowLeft_ =
|
| - util.createChild(this.arrowBox_, 'arrow left tool dimmable');
|
| - this.arrowLeft_.addEventListener('click',
|
| - this.advanceManually.bind(this, -1));
|
| - util.createChild(this.arrowLeft_);
|
| -
|
| - util.createChild(this.arrowBox_, 'arrow-spacer');
|
| -
|
| - this.arrowRight_ =
|
| - util.createChild(this.arrowBox_, 'arrow right tool dimmable');
|
| - this.arrowRight_.addEventListener('click',
|
| - this.advanceManually.bind(this, 1));
|
| - 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');
|
| - errorWrapper.setAttribute('pos', 'center');
|
| -
|
| - this.errorBanner_ = util.createChild(errorWrapper, 'error-banner');
|
| -
|
| - util.createChild(this.container_, 'spinner');
|
| -
|
| - var slideShowButton = util.createChild(this.toolbar_,
|
| - 'button slideshow', 'button');
|
| - slideShowButton.title = this.displayStringFunction_('GALLERY_SLIDESHOW');
|
| - slideShowButton.addEventListener('click',
|
| - this.startSlideshow.bind(this, SlideMode.SLIDESHOW_INTERVAL_FIRST));
|
| -
|
| - var slideShowToolbar =
|
| - util.createChild(this.container_, 'tool slideshow-toolbar');
|
| - util.createChild(slideShowToolbar, 'slideshow-play').
|
| - addEventListener('click', this.toggleSlideshowPause_.bind(this));
|
| - util.createChild(slideShowToolbar, 'slideshow-end').
|
| - addEventListener('click', this.stopSlideshow_.bind(this));
|
| -
|
| - // Editor.
|
| -
|
| - this.editButton_ = util.createChild(this.toolbar_, 'button edit', 'button');
|
| - this.editButton_.title = this.displayStringFunction_('GALLERY_EDIT');
|
| - this.editButton_.setAttribute('disabled', ''); // Disabled by default.
|
| - this.editButton_.addEventListener('click', this.toggleEditor.bind(this));
|
| -
|
| - this.printButton_ = util.createChild(this.toolbar_, 'button print', 'button');
|
| - this.printButton_.title = this.displayStringFunction_('GALLERY_PRINT');
|
| - this.printButton_.setAttribute('disabled', ''); // Disabled by default.
|
| - this.printButton_.addEventListener('click', this.print_.bind(this));
|
| -
|
| - this.editBarSpacer_ = util.createChild(this.toolbar_, 'edit-bar-spacer');
|
| - this.editBarMain_ = util.createChild(this.editBarSpacer_, 'edit-main');
|
| -
|
| - this.editBarMode_ = util.createChild(this.container_, 'edit-modal');
|
| - this.editBarModeWrapper_ = util.createChild(
|
| - this.editBarMode_, 'edit-modal-wrapper');
|
| - this.editBarModeWrapper_.hidden = true;
|
| -
|
| - // Objects supporting image display and editing.
|
| - this.viewport_ = new Viewport();
|
| -
|
| - this.imageView_ = new ImageView(
|
| - this.imageContainer_,
|
| - this.viewport_,
|
| - this.metadataCache_);
|
| -
|
| - this.editor_ = new ImageEditor(
|
| - this.viewport_,
|
| - this.imageView_,
|
| - this.prompt_,
|
| - {
|
| - root: this.container_,
|
| - image: this.imageContainer_,
|
| - toolbar: this.editBarMain_,
|
| - mode: this.editBarModeWrapper_
|
| - },
|
| - SlideMode.editorModes,
|
| - this.displayStringFunction_);
|
| -
|
| - this.editor_.getBuffer().addOverlay(
|
| - new SwipeOverlay(this.advanceManually.bind(this)));
|
| -};
|
| -
|
| -/**
|
| - * Load items, display the selected item.
|
| - * @param {Rect} zoomFromRect Rectangle for zoom effect.
|
| - * @param {function} displayCallback Called when the image is displayed.
|
| - * @param {function} loadCallback Called when the image is displayed.
|
| - */
|
| -SlideMode.prototype.enter = function(
|
| - zoomFromRect, displayCallback, loadCallback) {
|
| - this.sequenceDirection_ = 0;
|
| - this.sequenceLength_ = 0;
|
| -
|
| - var loadDone = function(loadType, delay) {
|
| - this.active_ = true;
|
| -
|
| - this.selectionModel_.addEventListener('change', this.onSelectionBound_);
|
| - this.dataModel_.addEventListener('splice', this.onSpliceBound_);
|
| - this.dataModel_.addEventListener('content', this.onContentBound_);
|
| -
|
| - ImageUtil.setAttribute(this.arrowBox_, 'active', this.getItemCount_() > 1);
|
| - this.ribbon_.enable();
|
| -
|
| - // Wait 1000ms after the animation is done, then prefetch the next image.
|
| - this.requestPrefetch(1, delay + 1000);
|
| -
|
| - if (loadCallback) loadCallback();
|
| - }.bind(this);
|
| -
|
| - // The latest |leave| call might have left the image animating. Remove it.
|
| - this.unloadImage_();
|
| -
|
| - if (this.getItemCount_() == 0) {
|
| - this.displayedIndex_ = -1;
|
| - //TODO(kaznacheev) Show this message in the grid mode too.
|
| - this.showErrorBanner_('GALLERY_NO_IMAGES');
|
| - loadDone();
|
| - } else {
|
| - // Remember the selection if it is empty or multiple. It will be restored
|
| - // in |leave| if the user did not changing the selection manually.
|
| - var currentSelection = this.selectionModel_.selectedIndexes;
|
| - if (currentSelection.length == 1)
|
| - this.savedSelection_ = null;
|
| - else
|
| - this.savedSelection_ = currentSelection;
|
| -
|
| - // Ensure valid single selection.
|
| - // Note that the SlideMode object is not listening to selection change yet.
|
| - this.select(Math.max(0, this.getSelectedIndex()));
|
| - 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,
|
| - zoomFromRect && this.imageView_.createZoomEffect(zoomFromRect),
|
| - displayCallback, loadDone);
|
| - }.bind(this));
|
| -
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Leave the mode.
|
| - * @param {Rect} zoomToRect Rectangle for zoom effect.
|
| - * @param {function} callback Called when the image is committed and
|
| - * the zoom-out animation has started.
|
| - */
|
| -SlideMode.prototype.leave = function(zoomToRect, callback) {
|
| - var commitDone = function() {
|
| - this.stopEditing_();
|
| - this.stopSlideshow_();
|
| - ImageUtil.setAttribute(this.arrowBox_, 'active', false);
|
| - this.selectionModel_.removeEventListener(
|
| - 'change', this.onSelectionBound_);
|
| - this.dataModel_.removeEventListener('splice', this.onSpliceBound_);
|
| - this.dataModel_.removeEventListener('content', this.onContentBound_);
|
| - this.ribbon_.disable();
|
| - this.active_ = false;
|
| - if (this.savedSelection_)
|
| - this.selectionModel_.selectedIndexes = this.savedSelection_;
|
| - this.unloadImage_(zoomToRect);
|
| - callback();
|
| - }.bind(this);
|
| -
|
| - if (this.getItemCount_() == 0) {
|
| - this.showErrorBanner_(false);
|
| - commitDone();
|
| - } else {
|
| - this.commitItem_(commitDone);
|
| - }
|
| -
|
| - // Disable the slide-mode only buttons when leaving.
|
| - this.editButton_.setAttribute('disabled', '');
|
| - this.printButton_.setAttribute('disabled', '');
|
| -};
|
| -
|
| -
|
| -/**
|
| - * Execute an action when the editor is not busy.
|
| - *
|
| - * @param {function} action Function to execute.
|
| - */
|
| -SlideMode.prototype.executeWhenReady = function(action) {
|
| - this.editor_.executeWhenReady(action);
|
| -};
|
| -
|
| -/**
|
| - * @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.getItemCount_ = function() {
|
| - return this.dataModel_.length;
|
| -};
|
| -
|
| -/**
|
| - * @param {number} index Index.
|
| - * @return {Gallery.Item} Item.
|
| - */
|
| -SlideMode.prototype.getItem = function(index) {
|
| - return this.dataModel_.item(index);
|
| -};
|
| -
|
| -/**
|
| - * @return {Gallery.Item} Selected index.
|
| - */
|
| -SlideMode.prototype.getSelectedIndex = function() {
|
| - return this.selectionModel_.selectedIndex;
|
| -};
|
| -
|
| -/**
|
| - * @return {Rect} Screen rectangle of the selected image.
|
| - */
|
| -SlideMode.prototype.getSelectedImageRect = function() {
|
| - if (this.getSelectedIndex() < 0)
|
| - return null;
|
| - else
|
| - return this.viewport_.getScreenClipped();
|
| -};
|
| -
|
| -/**
|
| - * @return {Gallery.Item} Selected item.
|
| - */
|
| -SlideMode.prototype.getSelectedItem = function() {
|
| - return this.getItem(this.getSelectedIndex());
|
| -};
|
| -
|
| -/**
|
| - * Toggles the full screen mode.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.toggleFullScreen_ = function() {
|
| - util.toggleFullScreen(this.context_.appWindow,
|
| - !util.isFullScreen(this.context_.appWindow));
|
| -};
|
| -
|
| -/**
|
| - * Selection change handler.
|
| - *
|
| - * Commits the current image and displays the newly selected image.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onSelection_ = function() {
|
| - if (this.selectionModel_.selectedIndexes.length == 0)
|
| - return; // Temporary empty selection.
|
| -
|
| - // Forget the saved selection if the user changed the selection manually.
|
| - if (!this.isSlideshowOn_())
|
| - this.savedSelection_ = null;
|
| -
|
| - if (this.getSelectedIndex() == this.displayedIndex_)
|
| - return; // Do not reselect.
|
| -
|
| - this.commitItem_(this.loadSelectedItem_.bind(this));
|
| -};
|
| -
|
| -/**
|
| - * Change the selection.
|
| - *
|
| - * @param {number} index New selected index.
|
| - * @param {number=} opt_slideHint Slide animation direction (-1|1).
|
| - */
|
| -SlideMode.prototype.select = function(index, opt_slideHint) {
|
| - this.slideHint_ = opt_slideHint;
|
| - this.selectionModel_.selectedIndex = index;
|
| - this.selectionModel_.leadIndex = index;
|
| -};
|
| -
|
| -/**
|
| - * Load the selected item.
|
| - *
|
| - * @private
|
| - */
|
| -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 = slideHint || (index - this.displayedIndex_);
|
| -
|
| - if (Math.abs(step) != 1) {
|
| - // Long leap, the sequence is broken, we have no good prefetch candidate.
|
| - this.sequenceDirection_ = 0;
|
| - this.sequenceLength_ = 0;
|
| - } else if (this.sequenceDirection_ == step) {
|
| - // Keeping going in sequence.
|
| - this.sequenceLength_++;
|
| - } else {
|
| - // Reversed the direction. Reset the counter.
|
| - this.sequenceDirection_ = step;
|
| - this.sequenceLength_ = 1;
|
| - }
|
| -
|
| - if (this.sequenceLength_ <= 1) {
|
| - // We have just broke the sequence. Touch the current image so that it stays
|
| - // in the cache longer.
|
| - this.imageView_.prefetch(this.imageView_.contentID_);
|
| - }
|
| -
|
| - this.displayedIndex_ = index;
|
| -
|
| - function shouldPrefetch(loadType, step, sequenceLength) {
|
| - // Never prefetch when selecting out of sequence.
|
| - if (Math.abs(step) != 1)
|
| - return false;
|
| -
|
| - // Never prefetch after a video load (decoding the next image can freeze
|
| - // the UI for a second or two).
|
| - if (loadType == ImageView.LOAD_TYPE_VIDEO_FILE)
|
| - return false;
|
| -
|
| - // Always prefetch if the previous load was from cache.
|
| - if (loadType == ImageView.LOAD_TYPE_CACHED_FULL)
|
| - return true;
|
| -
|
| - // Prefetch if we have been going in the same direction for long enough.
|
| - return sequenceLength >= 3;
|
| - }
|
| -
|
| - var selectedItem = this.getSelectedItem();
|
| - this.currentUniqueKey_++;
|
| - var selectedUniqueKey = this.currentUniqueKey_;
|
| - var onMetadata = function(metadata) {
|
| - // Discard, since another load has been invoked after this one.
|
| - if (selectedUniqueKey != this.currentUniqueKey_) return;
|
| - this.loadItem_(selectedItem.getUrl(), metadata,
|
| - new ImageView.Effect.Slide(step, this.isSlideshowPlaying_()),
|
| - function() {} /* no displayCallback */,
|
| - function(loadType, delay) {
|
| - // Discard, since another load has been invoked after this one.
|
| - if (selectedUniqueKey != this.currentUniqueKey_) return;
|
| - if (shouldPrefetch(loadType, step, this.sequenceLength_)) {
|
| - this.requestPrefetch(step, delay);
|
| - }
|
| - if (this.isSlideshowPlaying_())
|
| - this.scheduleNextSlide_();
|
| - }.bind(this));
|
| - }.bind(this);
|
| - this.metadataCache_.get(
|
| - selectedItem.getUrl(), Gallery.METADATA_TYPE, onMetadata);
|
| -};
|
| -
|
| -/**
|
| - * Unload the current image.
|
| - *
|
| - * @param {Rect} zoomToRect Rectangle for zoom effect.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.unloadImage_ = function(zoomToRect) {
|
| - this.imageView_.unload(zoomToRect);
|
| - this.container_.removeAttribute('video');
|
| -};
|
| -
|
| -/**
|
| - * Data model 'splice' event handler.
|
| - * @param {Event} event Event.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onSplice_ = function(event) {
|
| - ImageUtil.setAttribute(this.arrowBox_, 'active', this.getItemCount_() > 1);
|
| -
|
| - // Splice invalidates saved indices, drop the saved selection.
|
| - this.savedSelection_ = null;
|
| -
|
| - 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_ so that loadSelectedItem_ does not think
|
| - // we are re-selecting the same item (and does right-to-left slide-in
|
| - // animation).
|
| - 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_('GALLERY_NO_IMAGES');
|
| - }.bind(this));
|
| - }
|
| - }.bind(this), 0);
|
| -};
|
| -
|
| -/**
|
| - * @param {number} direction -1 for left, 1 for right.
|
| - * @return {number} Next index in the given direction, with wrapping.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.getNextSelectedIndex_ = function(direction) {
|
| - function advance(index, limit) {
|
| - index += (direction > 0 ? 1 : -1);
|
| - if (index < 0)
|
| - return limit - 1;
|
| - if (index == limit)
|
| - return 0;
|
| - return index;
|
| - }
|
| -
|
| - // If the saved selection is multiple the Slideshow should cycle through
|
| - // the saved selection.
|
| - if (this.isSlideshowOn_() &&
|
| - this.savedSelection_ && this.savedSelection_.length > 1) {
|
| - var pos = advance(this.savedSelection_.indexOf(this.getSelectedIndex()),
|
| - this.savedSelection_.length);
|
| - return this.savedSelection_[pos];
|
| - } else {
|
| - return advance(this.getSelectedIndex(), this.getItemCount_());
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Advance the selection based on the pressed key ID.
|
| - * @param {string} keyID Key identifier.
|
| - */
|
| -SlideMode.prototype.advanceWithKeyboard = function(keyID) {
|
| - this.advanceManually(keyID == 'Up' || keyID == 'Left' ? -1 : 1);
|
| -};
|
| -
|
| -/**
|
| - * Advance the selection as a result of a user action (as opposed to an
|
| - * automatic change in the slideshow mode).
|
| - * @param {number} direction -1 for left, 1 for right.
|
| - */
|
| -SlideMode.prototype.advanceManually = function(direction) {
|
| - if (this.isSlideshowPlaying_()) {
|
| - this.pauseSlideshow_();
|
| - cr.dispatchSimpleEvent(this, 'useraction');
|
| - }
|
| - this.selectNext(direction);
|
| -};
|
| -
|
| -/**
|
| - * Select the next item.
|
| - * @param {number} direction -1 for left, 1 for right.
|
| - */
|
| -SlideMode.prototype.selectNext = function(direction) {
|
| - this.select(this.getNextSelectedIndex_(direction), direction);
|
| -};
|
| -
|
| -/**
|
| - * Select the first item.
|
| - */
|
| -SlideMode.prototype.selectFirst = function() {
|
| - this.select(0);
|
| -};
|
| -
|
| -/**
|
| - * Select the last item.
|
| - */
|
| -SlideMode.prototype.selectLast = function() {
|
| - this.select(this.getItemCount_() - 1);
|
| -};
|
| -
|
| -// Loading/unloading
|
| -
|
| -/**
|
| - * Load and display an item.
|
| - *
|
| - * @param {string} url Item url.
|
| - * @param {Object} metadata Item metadata.
|
| - * @param {Object} effect Transition effect object.
|
| - * @param {function} displayCallback Called when the image is displayed
|
| - * (which can happen before the image load due to caching).
|
| - * @param {function} loadCallback Called when the image is fully loaded.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.loadItem_ = function(
|
| - url, metadata, effect, displayCallback, loadCallback) {
|
| - this.selectedImageMetadata_ = MetadataCache.cloneMetadata(metadata);
|
| -
|
| - this.showSpinner_(true);
|
| -
|
| - var loadDone = function(loadType, delay, error) {
|
| - var video = this.isShowingVideo_();
|
| - ImageUtil.setAttribute(this.container_, 'video', video);
|
| -
|
| - this.showSpinner_(false);
|
| - if (loadType == ImageView.LOAD_TYPE_ERROR) {
|
| - // if we have a specific error, then display it
|
| - if (error) {
|
| - this.showErrorBanner_('GALLERY_' + error);
|
| - } else {
|
| - // otherwise try to infer general error
|
| - this.showErrorBanner_(
|
| - video ? 'GALLERY_VIDEO_ERROR' : 'GALLERY_IMAGE_ERROR');
|
| - }
|
| - } else if (loadType == ImageView.LOAD_TYPE_OFFLINE) {
|
| - this.showErrorBanner_(
|
| - video ? 'GALLERY_VIDEO_OFFLINE' : 'GALLERY_IMAGE_OFFLINE');
|
| - }
|
| -
|
| - if (video) {
|
| - // 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 {
|
| - ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('View'));
|
| -
|
| - var toMillions = function(number) {
|
| - return Math.round(number / (1000 * 1000));
|
| - };
|
| -
|
| - ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MB'),
|
| - toMillions(metadata.filesystem.size));
|
| -
|
| - var canvas = this.imageView_.getCanvas();
|
| - ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MPix'),
|
| - toMillions(canvas.width * canvas.height));
|
| -
|
| - var extIndex = url.lastIndexOf('.');
|
| - var ext = extIndex < 0 ? '' : url.substr(extIndex + 1).toLowerCase();
|
| - if (ext == 'jpeg') ext = 'jpg';
|
| - ImageUtil.metrics.recordEnum(
|
| - ImageUtil.getMetricName('FileType'), ext, ImageUtil.FILE_TYPES);
|
| - }
|
| -
|
| - // Enable or disable buttons for editing and printing.
|
| - if (video || error) {
|
| - this.editButton_.setAttribute('disabled', '');
|
| - this.printButton_.setAttribute('disabled', '');
|
| - } else {
|
| - this.editButton_.removeAttribute('disabled');
|
| - this.printButton_.removeAttribute('disabled');
|
| - }
|
| -
|
| - // For once edited image, disallow the 'overwrite' setting change.
|
| - ImageUtil.setAttribute(this.options_, 'saved',
|
| - !this.getSelectedItem().isOriginal());
|
| -
|
| - util.platform.getPreference(SlideMode.OVERWRITE_BUBBLE_KEY,
|
| - function(value) {
|
| - var times = typeof value == 'string' ? parseInt(value, 10) : 0;
|
| - if (times < SlideMode.OVERWRITE_BUBBLE_MAX_TIMES) {
|
| - this.bubble_.hidden = false;
|
| - if (this.isEditing()) {
|
| - util.platform.setPreference(
|
| - SlideMode.OVERWRITE_BUBBLE_KEY, times + 1);
|
| - }
|
| - }
|
| - }.bind(this));
|
| -
|
| - loadCallback(loadType, delay);
|
| - }.bind(this);
|
| -
|
| - var displayDone = function() {
|
| - cr.dispatchSimpleEvent(this, 'image-displayed');
|
| - displayCallback();
|
| - }.bind(this);
|
| -
|
| - this.editor_.openSession(url, metadata, effect,
|
| - this.saveCurrentImage_.bind(this), displayDone, loadDone);
|
| -};
|
| -
|
| -/**
|
| - * Commit changes to the current item and reset all messages/indicators.
|
| - *
|
| - * @param {function} callback Callback.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.commitItem_ = function(callback) {
|
| - this.showSpinner_(false);
|
| - this.showErrorBanner_(false);
|
| - this.editor_.getPrompt().hide();
|
| -
|
| - // Detach any media attached to the controls.
|
| - if (this.mediaControls_.getMedia())
|
| - this.mediaControls_.detachMedia();
|
| -
|
| - // If showing the video, then pause it. Note, that it may not be attached
|
| - // to the media controls yet.
|
| - if (this.isShowingVideo_()) {
|
| - this.imageView_.getVideo().pause();
|
| - // Force stop downloading, if uncached on Drive.
|
| - this.imageView_.getVideo().src = '';
|
| - this.imageView_.getVideo().load();
|
| - }
|
| -
|
| - this.editor_.closeSession(callback);
|
| -};
|
| -
|
| -/**
|
| - * Request a prefetch for the next image.
|
| - *
|
| - * @param {number} direction -1 or 1.
|
| - * @param {number} delay Delay in ms. Used to prevent the CPU-heavy image
|
| - * loading from disrupting the animation that might be still in progress.
|
| - */
|
| -SlideMode.prototype.requestPrefetch = function(direction, delay) {
|
| - if (this.getItemCount_() <= 1) return;
|
| -
|
| - var index = this.getNextSelectedIndex_(direction);
|
| - var nextItemUrl = this.getItem(index).getUrl();
|
| - this.imageView_.prefetch(nextItemUrl, delay);
|
| -};
|
| -
|
| -// Event handlers.
|
| -
|
| -/**
|
| - * Unload handler, to be called from the top frame.
|
| - * @param {boolean} exiting True if the app is exiting.
|
| - */
|
| -SlideMode.prototype.onUnload = function(exiting) {
|
| - if (this.isShowingVideo_() && this.mediaControls_.isPlaying()) {
|
| - this.mediaControls_.savePosition(exiting);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * beforeunload handler, to be called from the top frame.
|
| - * @return {string} Message to show if there are unsaved changes.
|
| - */
|
| -SlideMode.prototype.onBeforeUnload = function() {
|
| - if (this.editor_.isBusy())
|
| - return this.displayStringFunction_('GALLERY_UNSAVED_CHANGES');
|
| - return null;
|
| -};
|
| -
|
| -/**
|
| - * Click handler for the image container.
|
| - *
|
| - * @param {Event} event Mouse click event.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onClick_ = function(event) {
|
| - if (!this.isShowingVideo_() || !this.mediaControls_.getMedia())
|
| - return;
|
| - if (event.ctrlKey) {
|
| - this.mediaControls_.toggleLoopedModeWithFeedback(true);
|
| - if (!this.mediaControls_.isPlaying())
|
| - this.mediaControls_.togglePlayStateWithFeedback();
|
| - } else {
|
| - this.mediaControls_.togglePlayStateWithFeedback();
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Click handler for the entire document.
|
| - * @param {Event} e Mouse click event.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onDocumentClick_ = function(e) {
|
| - // Close the bubble if clicked outside of it and if it is visible.
|
| - if (!this.bubble_.contains(e.target) &&
|
| - !this.editButton_.contains(e.target) &&
|
| - !this.arrowLeft_.contains(e.target) &&
|
| - !this.arrowRight_.contains(e.target) &&
|
| - !this.bubble_.hidden) {
|
| - this.bubble_.hidden = true;
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Keydown handler.
|
| - *
|
| - * @param {Event} event Event.
|
| - * @return {boolean} True if handled.
|
| - */
|
| -SlideMode.prototype.onKeyDown = function(event) {
|
| - var keyID = util.getKeyModifiers(event) + event.keyIdentifier;
|
| -
|
| - if (this.isSlideshowOn_()) {
|
| - switch (keyID) {
|
| - case 'U+001B': // Escape exits the slideshow.
|
| - this.stopSlideshow_(event);
|
| - break;
|
| -
|
| - case 'U+0020': // Space pauses/resumes the slideshow.
|
| - this.toggleSlideshowPause_();
|
| - break;
|
| -
|
| - case 'Up':
|
| - case 'Down':
|
| - case 'Left':
|
| - case 'Right':
|
| - this.advanceWithKeyboard(keyID);
|
| - break;
|
| - }
|
| - return true; // Consume all keystrokes in the slideshow mode.
|
| - }
|
| -
|
| - if (this.isEditing() && this.editor_.onKeyDown(event))
|
| - return true;
|
| -
|
| - switch (keyID) {
|
| - case 'U+0020': // Space toggles the video playback.
|
| - if (this.isShowingVideo_() && this.mediaControls_.getMedia())
|
| - this.mediaControls_.togglePlayStateWithFeedback();
|
| - break;
|
| -
|
| - case 'Ctrl-U+0050': // Ctrl+'p' prints the current image.
|
| - if (!this.printButton_.hasAttribute('disabled'))
|
| - this.print_();
|
| - break;
|
| -
|
| - case 'U+0045': // 'e' toggles the editor.
|
| - if (!this.editButton_.hasAttribute('disabled'))
|
| - this.toggleEditor(event);
|
| - break;
|
| -
|
| - case 'U+001B': // Escape
|
| - if (!this.isEditing())
|
| - return false; // Not handled.
|
| - this.toggleEditor(event);
|
| - break;
|
| -
|
| - case 'Home':
|
| - this.selectFirst();
|
| - break;
|
| - case 'End':
|
| - this.selectLast();
|
| - break;
|
| - case 'Up':
|
| - case 'Down':
|
| - case 'Left':
|
| - case 'Right':
|
| - this.advanceWithKeyboard(keyID);
|
| - break;
|
| -
|
| - default: return false;
|
| - }
|
| -
|
| - return true;
|
| -};
|
| -
|
| -/**
|
| - * Resize handler.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onResize_ = function() {
|
| - this.viewport_.sizeByFrameAndFit(this.container_);
|
| - this.viewport_.repaint();
|
| -};
|
| -
|
| -/**
|
| - * Update thumbnails.
|
| - */
|
| -SlideMode.prototype.updateThumbnails = function() {
|
| - this.ribbon_.reset();
|
| - if (this.active_)
|
| - this.ribbon_.redraw();
|
| -};
|
| -
|
| -// Saving
|
| -
|
| -/**
|
| - * Save the current image to a file.
|
| - *
|
| - * @param {function} callback Callback.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.saveCurrentImage_ = function(callback) {
|
| - var item = this.getSelectedItem();
|
| - var oldUrl = item.getUrl();
|
| - var canvas = this.imageView_.getCanvas();
|
| -
|
| - this.showSpinner_(true);
|
| - var metadataEncoder = ImageEncoder.encodeMetadata(
|
| - this.selectedImageMetadata_.media, canvas, 1 /* quality */);
|
| -
|
| - this.selectedImageMetadata_ = ContentProvider.ConvertContentMetadata(
|
| - metadataEncoder.getMetadata(), this.selectedImageMetadata_);
|
| -
|
| - item.saveToFile(
|
| - this.context_.saveDirEntry,
|
| - this.shouldOverwriteOriginal_(),
|
| - canvas,
|
| - metadataEncoder,
|
| - function(success) {
|
| - // TODO(kaznacheev): Implement write error handling.
|
| - // Until then pretend that the save succeeded.
|
| - this.showSpinner_(false);
|
| - this.flashSavedLabel_();
|
| -
|
| - var e = new Event('content');
|
| - e.item = item;
|
| - e.oldUrl = oldUrl;
|
| - e.metadata = this.selectedImageMetadata_;
|
| - this.dataModel_.dispatchEvent(e);
|
| -
|
| - // Allow changing the 'Overwrite original' setting only if the user
|
| - // used Undo to restore the original image AND it is not a copy.
|
| - // Otherwise lock the setting in its current state.
|
| - var mayChangeOverwrite = !this.editor_.canUndo() && item.isOriginal();
|
| - ImageUtil.setAttribute(this.options_, 'saved', !mayChangeOverwrite);
|
| -
|
| - if (this.imageView_.getContentRevision() == 1) { // First edit.
|
| - ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit'));
|
| - }
|
| -
|
| - if (oldUrl != item.getUrl()) {
|
| - this.dataModel_.splice(
|
| - this.getSelectedIndex(), 0, new Gallery.Item(oldUrl));
|
| - // The ribbon will ignore the splice above and redraw after the
|
| - // select call below (while being obscured by the Editor toolbar,
|
| - // so there is no need for nice animation here).
|
| - // SlideMode will ignore the selection change as the displayed item
|
| - // index has not changed.
|
| - this.select(++this.displayedIndex_);
|
| - }
|
| - callback();
|
| - cr.dispatchSimpleEvent(this, 'image-saved');
|
| - }.bind(this));
|
| -};
|
| -
|
| -/**
|
| - * Update caches when the selected item url has changed.
|
| - *
|
| - * @param {Event} event Event.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onContentChange_ = function(event) {
|
| - var newUrl = event.item.getUrl();
|
| - if (newUrl != event.oldUrl) {
|
| - this.imageView_.changeUrl(newUrl);
|
| - }
|
| - this.metadataCache_.clear(event.oldUrl, Gallery.METADATA_TYPE);
|
| -};
|
| -
|
| -/**
|
| - * Flash 'Saved' label briefly to indicate that the image has been saved.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.flashSavedLabel_ = function() {
|
| - var setLabelHighlighted =
|
| - ImageUtil.setAttribute.bind(null, this.savedLabel_, 'highlighted');
|
| - setTimeout(setLabelHighlighted.bind(null, true), 0);
|
| - setTimeout(setLabelHighlighted.bind(null, false), 300);
|
| -};
|
| -
|
| -/**
|
| - * Local storage key for the 'Overwrite original' setting.
|
| - * @type {string}
|
| - */
|
| -SlideMode.OVERWRITE_KEY = 'gallery-overwrite-original';
|
| -
|
| -/**
|
| - * Local storage key for the number of times that
|
| - * the overwrite info bubble has been displayed.
|
| - * @type {string}
|
| - */
|
| -SlideMode.OVERWRITE_BUBBLE_KEY = 'gallery-overwrite-bubble';
|
| -
|
| -/**
|
| - * Max number that the overwrite info bubble is shown.
|
| - * @type {number}
|
| - */
|
| -SlideMode.OVERWRITE_BUBBLE_MAX_TIMES = 5;
|
| -
|
| -/**
|
| - * @return {boolean} True if 'Overwrite original' is set.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.shouldOverwriteOriginal_ = function() {
|
| - return this.overwriteOriginal_.checked;
|
| -};
|
| -
|
| -/**
|
| - * 'Overwrite original' checkbox handler.
|
| - * @param {Event} event Event.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onOverwriteOriginalClick_ = function(event) {
|
| - util.platform.setPreference(SlideMode.OVERWRITE_KEY, event.target.checked);
|
| -};
|
| -
|
| -/**
|
| - * Overwrite info bubble close handler.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.onCloseBubble_ = function() {
|
| - this.bubble_.hidden = true;
|
| - util.platform.setPreference(SlideMode.OVERWRITE_BUBBLE_KEY,
|
| - SlideMode.OVERWRITE_BUBBLE_MAX_TIMES);
|
| -};
|
| -
|
| -// Slideshow
|
| -
|
| -/**
|
| - * Slideshow interval in ms.
|
| - */
|
| -SlideMode.SLIDESHOW_INTERVAL = 5000;
|
| -
|
| -/**
|
| - * 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;
|
| -
|
| -/**
|
| - * Empirically determined duration of the fullscreen toggle animation.
|
| - */
|
| -SlideMode.FULLSCREEN_TOGGLE_DELAY = 500;
|
| -
|
| -/**
|
| - * @return {boolean} True if the slideshow is on.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.isSlideshowOn_ = function() {
|
| - return this.container_.hasAttribute('slideshow');
|
| -};
|
| -
|
| -/**
|
| - * Start the slideshow.
|
| - * @param {number=} opt_interval First interval in ms.
|
| - * @param {Event=} opt_event Event.
|
| - */
|
| -SlideMode.prototype.startSlideshow = function(opt_interval, opt_event) {
|
| - // Set the attribute early to prevent the toolbar from flashing when
|
| - // the slideshow is being started from the mosaic view.
|
| - this.container_.setAttribute('slideshow', 'playing');
|
| -
|
| - if (this.active_) {
|
| - this.stopEditing_();
|
| - } else {
|
| - // We are in the Mosaic mode. Toggle the mode but remember to return.
|
| - this.leaveAfterSlideshow_ = true;
|
| - this.toggleMode_(this.startSlideshow.bind(
|
| - this, SlideMode.SLIDESHOW_INTERVAL, opt_event));
|
| - return;
|
| - }
|
| -
|
| - if (opt_event) // Caused by user action, notify the Gallery.
|
| - cr.dispatchSimpleEvent(this, 'useraction');
|
| -
|
| - this.fullscreenBeforeSlideshow_ = util.isFullScreen(this.context_.appWindow);
|
| - if (!this.fullscreenBeforeSlideshow_) {
|
| - // Wait until the zoom animation from the mosaic mode is done.
|
| - setTimeout(this.toggleFullScreen_.bind(this),
|
| - ImageView.ZOOM_ANIMATION_DURATION);
|
| - opt_interval = (opt_interval || SlideMode.SLIDESHOW_INTERVAL) +
|
| - SlideMode.FULLSCREEN_TOGGLE_DELAY;
|
| - }
|
| -
|
| - this.resumeSlideshow_(opt_interval);
|
| -};
|
| -
|
| -/**
|
| - * Stop the slideshow.
|
| - * @param {Event=} opt_event Event.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.stopSlideshow_ = function(opt_event) {
|
| - if (!this.isSlideshowOn_())
|
| - return;
|
| -
|
| - if (opt_event) // Caused by user action, notify the Gallery.
|
| - cr.dispatchSimpleEvent(this, 'useraction');
|
| -
|
| - this.pauseSlideshow_();
|
| - this.container_.removeAttribute('slideshow');
|
| -
|
| - // Do not restore fullscreen if we exited fullscreen while in slideshow.
|
| - var fullscreen = util.isFullScreen(this.context_.appWindow);
|
| - var toggleModeDelay = 0;
|
| - if (!this.fullscreenBeforeSlideshow_ && fullscreen) {
|
| - this.toggleFullScreen_();
|
| - toggleModeDelay = SlideMode.FULLSCREEN_TOGGLE_DELAY;
|
| - }
|
| - if (this.leaveAfterSlideshow_) {
|
| - this.leaveAfterSlideshow_ = false;
|
| - setTimeout(this.toggleMode_.bind(this), toggleModeDelay);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * @return {boolean} True if the slideshow is playing (not paused).
|
| - * @private
|
| - */
|
| -SlideMode.prototype.isSlideshowPlaying_ = function() {
|
| - return this.container_.getAttribute('slideshow') == 'playing';
|
| -};
|
| -
|
| -/**
|
| - * Pause/resume the slideshow.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.toggleSlideshowPause_ = function() {
|
| - cr.dispatchSimpleEvent(this, 'useraction'); // Show the tools.
|
| - if (this.isSlideshowPlaying_()) {
|
| - this.pauseSlideshow_();
|
| - } else {
|
| - this.resumeSlideshow_(SlideMode.SLIDESHOW_INTERVAL_FIRST);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * @param {number=} opt_interval Slideshow interval in ms.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.scheduleNextSlide_ = function(opt_interval) {
|
| - console.assert(this.isSlideshowPlaying_(), 'Inconsistent slideshow state');
|
| -
|
| - if (this.slideShowTimeout_)
|
| - clearTimeout(this.slideShowTimeout_);
|
| -
|
| - this.slideShowTimeout_ = setTimeout(function() {
|
| - this.slideShowTimeout_ = null;
|
| - this.selectNext(1);
|
| - }.bind(this),
|
| - opt_interval || SlideMode.SLIDESHOW_INTERVAL);
|
| -};
|
| -
|
| -/**
|
| - * Resume the slideshow.
|
| - * @param {number=} opt_interval Slideshow interval in ms.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.resumeSlideshow_ = function(opt_interval) {
|
| - this.container_.setAttribute('slideshow', 'playing');
|
| - this.scheduleNextSlide_(opt_interval);
|
| -};
|
| -
|
| -/**
|
| - * Pause the slideshow.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.pauseSlideshow_ = function() {
|
| - this.container_.setAttribute('slideshow', 'paused');
|
| - if (this.slideShowTimeout_) {
|
| - clearTimeout(this.slideShowTimeout_);
|
| - this.slideShowTimeout_ = null;
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * @return {boolean} True if the editor is active.
|
| - */
|
| -SlideMode.prototype.isEditing = function() {
|
| - return this.container_.hasAttribute('editing');
|
| -};
|
| -
|
| -/**
|
| - * Stop editing.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.stopEditing_ = function() {
|
| - if (this.isEditing())
|
| - this.toggleEditor();
|
| -};
|
| -
|
| -/**
|
| - * Activate/deactivate editor.
|
| - * @param {Event=} opt_event Event.
|
| - */
|
| -SlideMode.prototype.toggleEditor = function(opt_event) {
|
| - if (opt_event) // Caused by user action, notify the Gallery.
|
| - cr.dispatchSimpleEvent(this, 'useraction');
|
| -
|
| - if (!this.active_) {
|
| - this.toggleMode_(this.toggleEditor.bind(this));
|
| - return;
|
| - }
|
| -
|
| - this.stopSlideshow_();
|
| - if (!this.isEditing() && this.isShowingVideo_())
|
| - return; // No editing for videos.
|
| -
|
| - ImageUtil.setAttribute(this.container_, 'editing', !this.isEditing());
|
| -
|
| - if (this.isEditing()) { // isEditing has just been flipped to a new value.
|
| - if (this.context_.readonlyDirName) {
|
| - this.editor_.getPrompt().showAt(
|
| - 'top', 'readonly_warning', 0, this.context_.readonlyDirName);
|
| - }
|
| - } else {
|
| - this.editor_.getPrompt().hide();
|
| - this.editor_.leaveModeGently();
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * Prints the current item.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.print_ = function() {
|
| - cr.dispatchSimpleEvent(this, 'useraction');
|
| - window.print();
|
| -};
|
| -
|
| -/**
|
| - * Display the error banner.
|
| - * @param {string} message Message.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.showErrorBanner_ = function(message) {
|
| - if (message) {
|
| - this.errorBanner_.textContent = this.displayStringFunction_(message);
|
| - }
|
| - ImageUtil.setAttribute(this.container_, 'error', !!message);
|
| -};
|
| -
|
| -/**
|
| - * Show/hide the busy spinner.
|
| - *
|
| - * @param {boolean} on True if show, false if hide.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.showSpinner_ = function(on) {
|
| - if (this.spinnerTimer_) {
|
| - clearTimeout(this.spinnerTimer_);
|
| - this.spinnerTimer_ = null;
|
| - }
|
| -
|
| - if (on) {
|
| - this.spinnerTimer_ = setTimeout(function() {
|
| - this.spinnerTimer_ = null;
|
| - ImageUtil.setAttribute(this.container_, 'spinner', true);
|
| - }.bind(this), 1000);
|
| - } else {
|
| - ImageUtil.setAttribute(this.container_, 'spinner', false);
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * @return {boolean} True if the current item is a video.
|
| - * @private
|
| - */
|
| -SlideMode.prototype.isShowingVideo_ = function() {
|
| - return !!this.imageView_.getVideo();
|
| -};
|
| -
|
| -/**
|
| - * Overlay that handles swipe gestures. Changes to the next or previous file.
|
| - * @param {function(number)} callback A callback accepting the swipe direction
|
| - * (1 means left, -1 right).
|
| - * @constructor
|
| - * @implements {ImageBuffer.Overlay}
|
| - */
|
| -function SwipeOverlay(callback) {
|
| - this.callback_ = callback;
|
| -}
|
| -
|
| -/**
|
| - * Inherit ImageBuffer.Overlay.
|
| - */
|
| -SwipeOverlay.prototype.__proto__ = ImageBuffer.Overlay.prototype;
|
| -
|
| -/**
|
| - * @param {number} x X pointer position.
|
| - * @param {number} y Y pointer position.
|
| - * @param {boolean} touch True if dragging caused by touch.
|
| - * @return {function} The closure to call on drag.
|
| - */
|
| -SwipeOverlay.prototype.getDragHandler = function(x, y, touch) {
|
| - if (!touch)
|
| - return null;
|
| - var origin = x;
|
| - var done = false;
|
| - return function(x, y) {
|
| - if (!done && origin - x > SwipeOverlay.SWIPE_THRESHOLD) {
|
| - this.callback_(1);
|
| - done = true;
|
| - } else if (!done && x - origin > SwipeOverlay.SWIPE_THRESHOLD) {
|
| - this.callback_(-1);
|
| - done = true;
|
| - }
|
| - }.bind(this);
|
| -};
|
| -
|
| -/**
|
| - * If the user touched the image and moved the finger more than SWIPE_THRESHOLD
|
| - * horizontally it's considered as a swipe gesture (change the current image).
|
| - */
|
| -SwipeOverlay.SWIPE_THRESHOLD = 100;
|
|
|