| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 /** | 5 /** |
| 6 * Slide mode displays a single image and has a set of controls to navigate | 6 * Slide mode displays a single image and has a set of controls to navigate |
| 7 * between the images and to edit an image. | 7 * between the images and to edit an image. |
| 8 * | 8 * |
| 9 * @param {!HTMLElement} container Main container element. | 9 * @param {!HTMLElement} container Main container element. |
| 10 * @param {!HTMLElement} content Content container element. | 10 * @param {!HTMLElement} content Content container element. |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 */ | 151 */ |
| 152 this.sequenceLength_ = 0; | 152 this.sequenceLength_ = 0; |
| 153 | 153 |
| 154 /** | 154 /** |
| 155 * @type {Array.<number>} | 155 * @type {Array.<number>} |
| 156 * @private | 156 * @private |
| 157 */ | 157 */ |
| 158 this.savedSelection_ = null; | 158 this.savedSelection_ = null; |
| 159 | 159 |
| 160 /** | 160 /** |
| 161 * @type {number} | 161 * @type {Gallery.Item} |
| 162 * @private | 162 * @private |
| 163 */ | 163 */ |
| 164 this.displayedIndex_ = -1; | 164 this.displayedItem_ = null; |
| 165 | 165 |
| 166 /** | 166 /** |
| 167 * @type {?number} | 167 * @type {?number} |
| 168 * @private | 168 * @private |
| 169 */ | 169 */ |
| 170 this.slideHint_ = null; | 170 this.slideHint_ = null; |
| 171 | 171 |
| 172 /** | 172 /** |
| 173 * @type {boolean} | 173 * @type {boolean} |
| 174 * @private | 174 * @private |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 529 |
| 530 if (loadCallback) loadCallback(); | 530 if (loadCallback) loadCallback(); |
| 531 }.bind(this); | 531 }.bind(this); |
| 532 | 532 |
| 533 // The latest |leave| call might have left the image animating. Remove it. | 533 // The latest |leave| call might have left the image animating. Remove it. |
| 534 this.unloadImage_(); | 534 this.unloadImage_(); |
| 535 | 535 |
| 536 new Promise(function(fulfill) { | 536 new Promise(function(fulfill) { |
| 537 // If the items are empty, just show the error message. | 537 // If the items are empty, just show the error message. |
| 538 if (this.getItemCount_() === 0) { | 538 if (this.getItemCount_() === 0) { |
| 539 this.displayedIndex_ = -1; | 539 this.displayedItem_ = null; |
| 540 //TODO(hirono) Show this message in the grid mode too. | 540 //TODO(hirono) Show this message in the grid mode too. |
| 541 this.errorBanner_.show('GALLERY_NO_IMAGES'); | 541 this.errorBanner_.show('GALLERY_NO_IMAGES'); |
| 542 fulfill(); | 542 fulfill(); |
| 543 return; | 543 return; |
| 544 } | 544 } |
| 545 | 545 |
| 546 // Remember the selection if it is empty or multiple. It will be restored | 546 // Remember the selection if it is empty or multiple. It will be restored |
| 547 // in |leave| if the user did not changing the selection manually. | 547 // in |leave| if the user did not changing the selection manually. |
| 548 var currentSelection = this.selectionModel_.selectedIndexes; | 548 var currentSelection = this.selectionModel_.selectedIndexes; |
| 549 if (currentSelection.length === 1) | 549 if (currentSelection.length === 1) |
| 550 this.savedSelection_ = null; | 550 this.savedSelection_ = null; |
| 551 else | 551 else |
| 552 this.savedSelection_ = currentSelection; | 552 this.savedSelection_ = currentSelection; |
| 553 | 553 |
| 554 // Ensure valid single selection. | 554 // Ensure valid single selection. |
| 555 // Note that the SlideMode object is not listening to selection change yet. | 555 // Note that the SlideMode object is not listening to selection change yet. |
| 556 this.select(Math.max(0, this.getSelectedIndex())); | 556 this.select(Math.max(0, this.getSelectedIndex())); |
| 557 this.displayedIndex_ = this.getSelectedIndex(); | |
| 558 | 557 |
| 559 // Show the selected item ASAP, then complete the initialization | 558 // Show the selected item ASAP, then complete the initialization |
| 560 // (loading the ribbon thumbnails can take some time). | 559 // (loading the ribbon thumbnails can take some time). |
| 561 var selectedItem = this.getSelectedItem(); | 560 var selectedItem = this.getSelectedItem(); |
| 561 this.displayedItem_ = selectedItem; |
| 562 | 562 |
| 563 // Load the image of the item. | 563 // Load the image of the item. |
| 564 this.loadItem_( | 564 this.loadItem_( |
| 565 selectedItem, | 565 selectedItem, |
| 566 zoomFromRect ? | 566 zoomFromRect ? |
| 567 this.imageView_.createZoomEffect(zoomFromRect) : | 567 this.imageView_.createZoomEffect(zoomFromRect) : |
| 568 new ImageView.Effect.None(), | 568 new ImageView.Effect.None(), |
| 569 displayCallback, | 569 displayCallback, |
| 570 function(loadType, delay) { | 570 function(loadType, delay) { |
| 571 fulfill(delay); | 571 fulfill(delay); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 * @private | 705 * @private |
| 706 */ | 706 */ |
| 707 SlideMode.prototype.onSelection_ = function() { | 707 SlideMode.prototype.onSelection_ = function() { |
| 708 if (this.selectionModel_.selectedIndexes.length === 0) | 708 if (this.selectionModel_.selectedIndexes.length === 0) |
| 709 return; // Ignore temporary empty selection. | 709 return; // Ignore temporary empty selection. |
| 710 | 710 |
| 711 // Forget the saved selection if the user changed the selection manually. | 711 // Forget the saved selection if the user changed the selection manually. |
| 712 if (!this.isSlideshowOn_()) | 712 if (!this.isSlideshowOn_()) |
| 713 this.savedSelection_ = null; | 713 this.savedSelection_ = null; |
| 714 | 714 |
| 715 if (this.getSelectedIndex() === this.displayedIndex_) | 715 if (this.getSelectedItem() === this.displayedItem_) |
| 716 return; // Do not reselect. | 716 return; // Do not reselect. |
| 717 | 717 |
| 718 this.commitItem_(this.loadSelectedItem_.bind(this)); | 718 this.commitItem_(this.loadSelectedItem_.bind(this)); |
| 719 }; | 719 }; |
| 720 | 720 |
| 721 /** | 721 /** |
| 722 * Handles changes in tools visibility, and if the header is dimmed, then | 722 * Handles changes in tools visibility, and if the header is dimmed, then |
| 723 * requests disabling the draggable app region. | 723 * requests disabling the draggable app region. |
| 724 * | 724 * |
| 725 * @private | 725 * @private |
| (...skipping 18 matching lines...) Expand all Loading... |
| 744 | 744 |
| 745 /** | 745 /** |
| 746 * Load the selected item. | 746 * Load the selected item. |
| 747 * | 747 * |
| 748 * @private | 748 * @private |
| 749 */ | 749 */ |
| 750 SlideMode.prototype.loadSelectedItem_ = function() { | 750 SlideMode.prototype.loadSelectedItem_ = function() { |
| 751 var slideHint = this.slideHint_; | 751 var slideHint = this.slideHint_; |
| 752 this.slideHint_ = null; | 752 this.slideHint_ = null; |
| 753 | 753 |
| 754 var index = this.getSelectedIndex(); | 754 if (this.getSelectedItem() === this.displayedItem_) |
| 755 if (index === this.displayedIndex_) | |
| 756 return; // Do not reselect. | 755 return; // Do not reselect. |
| 757 | 756 |
| 758 var step = slideHint || (index - this.displayedIndex_); | 757 var index = this.getSelectedIndex(); |
| 758 var displayedIndex = this.dataModel_.indexOf(this.displayedItem_); |
| 759 var step = |
| 760 slideHint || (displayedIndex > 0 ? index - displayedIndex : 1); |
| 759 | 761 |
| 760 if (Math.abs(step) != 1) { | 762 if (Math.abs(step) != 1) { |
| 761 // Long leap, the sequence is broken, we have no good prefetch candidate. | 763 // Long leap, the sequence is broken, we have no good prefetch candidate. |
| 762 this.sequenceDirection_ = 0; | 764 this.sequenceDirection_ = 0; |
| 763 this.sequenceLength_ = 0; | 765 this.sequenceLength_ = 0; |
| 764 } else if (this.sequenceDirection_ === step) { | 766 } else if (this.sequenceDirection_ === step) { |
| 765 // Keeping going in sequence. | 767 // Keeping going in sequence. |
| 766 this.sequenceLength_++; | 768 this.sequenceLength_++; |
| 767 } else { | 769 } else { |
| 768 // Reversed the direction. Reset the counter. | 770 // Reversed the direction. Reset the counter. |
| 769 this.sequenceDirection_ = step; | 771 this.sequenceDirection_ = step; |
| 770 this.sequenceLength_ = 1; | 772 this.sequenceLength_ = 1; |
| 771 } | 773 } |
| 772 | 774 |
| 773 this.displayedIndex_ = index; | 775 this.displayedItem_ = this.getSelectedItem(); |
| 774 var selectedItem = assertInstanceof(this.getSelectedItem(), Gallery.Item); | 776 var selectedItem = assertInstanceof(this.getSelectedItem(), Gallery.Item); |
| 775 | 777 |
| 776 if (this.sequenceLength_ <= 1) { | 778 if (this.sequenceLength_ <= 1) { |
| 777 // We have just broke the sequence. Touch the current image so that it stays | 779 // We have just broke the sequence. Touch the current image so that it stays |
| 778 // in the cache longer. | 780 // in the cache longer. |
| 779 this.imageView_.prefetch(selectedItem); | 781 this.imageView_.prefetch(selectedItem); |
| 780 } | 782 } |
| 781 | 783 |
| 782 function shouldPrefetch(loadType, step, sequenceLength) { | 784 function shouldPrefetch(loadType, step, sequenceLength) { |
| 783 // Never prefetch when selecting out of sequence. | 785 // Never prefetch when selecting out of sequence. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 ImageUtil.setAttribute(this.arrowBox_, 'active', this.getItemCount_() > 1); | 836 ImageUtil.setAttribute(this.arrowBox_, 'active', this.getItemCount_() > 1); |
| 835 | 837 |
| 836 // Splice invalidates saved indices, drop the saved selection. | 838 // Splice invalidates saved indices, drop the saved selection. |
| 837 this.savedSelection_ = null; | 839 this.savedSelection_ = null; |
| 838 | 840 |
| 839 if (event.removed.length != 1) | 841 if (event.removed.length != 1) |
| 840 return; | 842 return; |
| 841 | 843 |
| 842 // Delay the selection to let the ribbon splice handler work first. | 844 // Delay the selection to let the ribbon splice handler work first. |
| 843 setTimeout(function() { | 845 setTimeout(function() { |
| 846 var displayedItemNotRemvoed = event.removed.every(function(item) { |
| 847 return item !== this.displayedItem_; |
| 848 }.bind(this)); |
| 849 if (displayedItemNotRemvoed) |
| 850 return; |
| 851 var nextIndex; |
| 844 if (event.index < this.dataModel_.length) { | 852 if (event.index < this.dataModel_.length) { |
| 845 // There is the next item, select it. | 853 // There is the next item, select it. |
| 846 // The next item is now at the same index as the removed one, so we need | 854 // The next item is now at the same index as the removed one, so we need |
| 847 // to correct displayIndex_ so that loadSelectedItem_ does not think | 855 // to correct displayIndex_ so that loadSelectedItem_ does not think |
| 848 // we are re-selecting the same item (and does right-to-left slide-in | 856 // we are re-selecting the same item (and does right-to-left slide-in |
| 849 // animation). | 857 // animation). |
| 850 this.displayedIndex_ = event.index - 1; | 858 nextIndex = event.index; |
| 851 this.select(event.index); | |
| 852 } else if (this.dataModel_.length) { | 859 } else if (this.dataModel_.length) { |
| 853 // Removed item is the rightmost, but there are more items. | 860 // Removed item is the rightmost, but there are more items. |
| 854 this.select(event.index - 1); // Select the new last index. | 861 nextIndex = event.index - 1; // Select the new last index. |
| 855 } else { | 862 } else { |
| 856 // No items left. Unload the image, disable edit and print button, and | 863 // No items left. Unload the image, disable edit and print button, and |
| 857 // show the banner. | 864 // show the banner. |
| 858 this.commitItem_(function() { | 865 this.commitItem_(function() { |
| 859 this.unloadImage_(); | 866 this.unloadImage_(); |
| 860 this.printButton_.disabled = true; | 867 this.printButton_.disabled = true; |
| 861 this.editButton_.disabled = true; | 868 this.editButton_.disabled = true; |
| 862 this.errorBanner_.show('GALLERY_NO_IMAGES'); | 869 this.errorBanner_.show('GALLERY_NO_IMAGES'); |
| 863 }.bind(this)); | 870 }.bind(this)); |
| 871 return; |
| 864 } | 872 } |
| 873 // To force to dispatch a selection change event, clear selection before. |
| 874 this.selectionModel_.clear(); |
| 875 this.select(nextIndex); |
| 865 }.bind(this), 0); | 876 }.bind(this), 0); |
| 866 }; | 877 }; |
| 867 | 878 |
| 868 /** | 879 /** |
| 869 * @param {number} direction -1 for left, 1 for right. | 880 * @param {number} direction -1 for left, 1 for right. |
| 870 * @return {number} Next index in the given direction, with wrapping. | 881 * @return {number} Next index in the given direction, with wrapping. |
| 871 * @private | 882 * @private |
| 872 */ | 883 */ |
| 873 SlideMode.prototype.getNextSelectedIndex_ = function(direction) { | 884 SlideMode.prototype.getNextSelectedIndex_ = function(direction) { |
| 874 function advance(index, limit) { | 885 function advance(index, limit) { |
| (...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 var event = assertInstanceof(event, MouseEvent); | 1865 var event = assertInstanceof(event, MouseEvent); |
| 1855 var viewport = this.slideMode_.getViewport(); | 1866 var viewport = this.slideMode_.getViewport(); |
| 1856 if (!this.enabled_ || !viewport.isZoomed()) | 1867 if (!this.enabled_ || !viewport.isZoomed()) |
| 1857 return; | 1868 return; |
| 1858 this.stopOperation(); | 1869 this.stopOperation(); |
| 1859 viewport.setOffset( | 1870 viewport.setOffset( |
| 1860 viewport.getOffsetX() + event.wheelDeltaX, | 1871 viewport.getOffsetX() + event.wheelDeltaX, |
| 1861 viewport.getOffsetY() + event.wheelDeltaY); | 1872 viewport.getOffsetY() + event.wheelDeltaY); |
| 1862 this.slideMode_.applyViewportChange(); | 1873 this.slideMode_.applyViewportChange(); |
| 1863 }; | 1874 }; |
| OLD | NEW |