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 |