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

Side by Side Diff: ui/file_manager/gallery/js/mosaic_mode.js

Issue 853653004: Gallery: Add items to GalleryDataModel before loading their metadata. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed. Created 5 years, 8 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 unified diff | Download patch
OLDNEW
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 * @param {!Element} container Content container. 6 * @param {!Element} container Content container.
7 * @param {!ErrorBanner} errorBanner Error banner. 7 * @param {!ErrorBanner} errorBanner Error banner.
8 * @param {!cr.ui.ArrayDataModel} dataModel Data model. 8 * @param {!cr.ui.ArrayDataModel} dataModel Data model.
9 * @param {!cr.ui.ListSelectionModel} selectionModel Selection model. 9 * @param {!cr.ui.ListSelectionModel} selectionModel Selection model.
10 * @param {!VolumeManagerWrapper} volumeManager Volume manager. 10 * @param {!VolumeManagerWrapper} volumeManager Volume manager.
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 517
518 // No items left, show the banner. 518 // No items left, show the banner.
519 if (this.getItemCount_() === 0) 519 if (this.getItemCount_() === 0)
520 this.errorBanner_.show('GALLERY_NO_IMAGES'); 520 this.errorBanner_.show('GALLERY_NO_IMAGES');
521 521
522 this.scheduleLayout(Mosaic.LAYOUT_DELAY); 522 this.scheduleLayout(Mosaic.LAYOUT_DELAY);
523 } 523 }
524 524
525 if (event.added.length) { 525 if (event.added.length) {
526 var newTiles = []; 526 var newTiles = [];
527 for (var t = 0; t !== event.added.length; t++) 527 for (var t = 0; t !== event.added.length; t++) {
528 newTiles.push(new Mosaic.Tile(this, 528 newTiles.push(new Mosaic.Tile(
529 assertInstanceof(this.dataModel_.item(index + t), Gallery.Item))); 529 this,
530 assertInstanceof(this.dataModel_.item(index + t),
531 Gallery.Item)));
532 }
530 533
531 this.tiles_.splice.apply(this.tiles_, [index, 0].concat(newTiles)); 534 this.tiles_.splice.apply(this.tiles_, [index, 0].concat(newTiles));
532 this.initTiles_(newTiles); 535 this.initTiles_(newTiles);
533 this.scheduleLayout(Mosaic.LAYOUT_DELAY); 536 this.scheduleLayout(Mosaic.LAYOUT_DELAY);
534 } 537 }
535 538
536 if (this.tiles_.length !== this.dataModel_.length) 539 if (this.tiles_.length !== this.dataModel_.length)
537 console.error('Mosaic is out of sync'); 540 console.error('Mosaic is out of sync');
538 }; 541 };
539 542
540 /** 543 /**
541 * Content change handler. 544 * Content change handler.
542 * 545 *
543 * @param {!Event} event Event. 546 * @param {!Event} event Event.
544 * @private 547 * @private
545 */ 548 */
546 Mosaic.prototype.onContentChange_ = function(event) { 549 Mosaic.prototype.onContentChange_ = function(event) {
547 if (!this.tiles_) 550 if (!this.tiles_)
548 return; 551 return;
549 552
550 if (!event.thumbnailChanged) 553 if (!event.thumbnailChanged)
551 return; // Thumbnail unchanged, nothing to do. 554 return; // Thumbnail unchanged, nothing to do.
552 555
553 var index = this.dataModel_.indexOf(event.item); 556 var index = this.dataModel_.indexOf(event.item);
554 if (index !== this.selectionModel_.selectedIndex)
555 console.error('Content changed for unselected item');
556
557 this.layoutModel_.invalidateFromTile_(index); 557 this.layoutModel_.invalidateFromTile_(index);
558 this.tiles_[index].init(); 558 this.tiles_[index].init();
559 this.tiles_[index].unload(); 559 this.tiles_[index].unload();
560 this.tiles_[index].load( 560 this.tiles_[index].load(
561 Mosaic.Tile.LoadMode.HIGH_DPI, 561 Mosaic.Tile.LoadMode.HIGH_DPI,
562 this.scheduleLayout.bind(this, Mosaic.LAYOUT_DELAY)); 562 this.scheduleLayout.bind(this, Mosaic.LAYOUT_DELAY));
563 }; 563 };
564 564
565 /** 565 /**
566 * Keydown event handler. 566 * Keydown event handler.
(...skipping 1486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 * Initializes the thumbnail in the tile. Does not load an image, but sets 2053 * Initializes the thumbnail in the tile. Does not load an image, but sets
2054 * target dimensions using metadata. 2054 * target dimensions using metadata.
2055 */ 2055 */
2056 Mosaic.Tile.prototype.init = function() { 2056 Mosaic.Tile.prototype.init = function() {
2057 this.markUnloaded(); 2057 this.markUnloaded();
2058 this.left_ = null; // Mark as not laid out. 2058 this.left_ = null; // Mark as not laid out.
2059 2059
2060 // Set higher priority for the selected elements to load them first. 2060 // Set higher priority for the selected elements to load them first.
2061 var priority = this.getAttribute('selected') ? 2 : 3; 2061 var priority = this.getAttribute('selected') ? 2 : 3;
2062 2062
2063 // Use embedded thumbnails on Drive, since they have higher resolution. 2063 if (this.getItem().getThumbnailMetadataItem()) {
2064 this.thumbnailLoader_ = new ThumbnailLoader( 2064 // Use embedded thumbnails on Drive, since they have higher resolution.
2065 this.getItem().getEntry(), 2065 this.thumbnailLoader_ = new ThumbnailLoader(
2066 ThumbnailLoader.LoaderType.CANVAS,
2067 this.getItem().getThumbnailMetadataItem(),
2068 undefined, // Media type.
2069 [
2070 ThumbnailLoader.LoadTarget.EXTERNAL_METADATA,
2071 ThumbnailLoader.LoadTarget.FILE_ENTRY
2072 ]);
2073
2074 // If no hidpi embedded thumbnail available, then use the low resolution
2075 // for preloading.
2076 if (this.thumbnailLoader_.getLoadTarget() ===
2077 ThumbnailLoader.LoadTarget.FILE_ENTRY) {
2078 this.thumbnailPreloader_ = new ThumbnailLoader(
2079 this.getItem().getEntry(), 2066 this.getItem().getEntry(),
2080 ThumbnailLoader.LoaderType.CANVAS, 2067 ThumbnailLoader.LoaderType.CANVAS,
2081 this.getItem().getThumbnailMetadataItem(), 2068 this.getItem().getThumbnailMetadataItem(),
2082 undefined, // Media type. 2069 undefined, // Media type.
2083 [ 2070 [
2084 ThumbnailLoader.LoadTarget.CONTENT_METADATA 2071 ThumbnailLoader.LoadTarget.EXTERNAL_METADATA,
2085 ], 2072 ThumbnailLoader.LoadTarget.FILE_ENTRY
2086 // Preloaders have always higher priotity, so the preload images 2073 ]);
2087 // are loaded as soon as possible. 2074
2088 2); 2075 // If no hidpi embedded thumbnail available, then use the low resolution
2089 if (!this.thumbnailPreloader_.getLoadTarget()) 2076 // for preloading.
2090 this.thumbnailPreloader_ = null; 2077 if (this.thumbnailLoader_.getLoadTarget() ===
2078 ThumbnailLoader.LoadTarget.FILE_ENTRY) {
2079 this.thumbnailPreloader_ = new ThumbnailLoader(
2080 this.getItem().getEntry(),
2081 ThumbnailLoader.LoaderType.CANVAS,
2082 this.getItem().getThumbnailMetadataItem(),
2083 undefined, // Media type.
2084 [
2085 ThumbnailLoader.LoadTarget.CONTENT_METADATA
2086 ],
2087 // Preloaders have always higher priotity, so the preload images
2088 // are loaded as soon as possible.
2089 2);
2090 if (!this.thumbnailPreloader_.getLoadTarget())
2091 this.thumbnailPreloader_ = null;
2092 }
2091 } 2093 }
2092 2094
2093 // Dimensions are always acquired from the metadata. For local files, it is 2095 // Dimensions are always acquired from the metadata. For local files, it is
2094 // extracted from headers. For Drive files, it is received via the Drive API. 2096 // extracted from headers. For Drive files, it is received via the Drive API.
2095 // If the dimensions are not available, then the fallback dimensions will be 2097 // If the dimensions are not available, then the fallback dimensions will be
2096 // used (same as for the generic icon). 2098 // used (same as for the generic icon).
2097 var metadataItem = this.getItem().getMetadataItem(); 2099 var metadataItem = this.getItem().getMetadataItem();
2098 var width; 2100 var width;
2099 var height; 2101 var height;
2100 if (metadataItem.imageWidth && metadataItem.imageHeight) { 2102 if (metadataItem && metadataItem.imageWidth && metadataItem.imageHeight) {
2101 width = metadataItem.imageWidth; 2103 width = metadataItem.imageWidth;
2102 height = metadataItem.imageHeight; 2104 height = metadataItem.imageHeight;
2103 } else { 2105 } else {
2104 // No dimensions in metadata, then use the generic dimensions. 2106 // No dimensions in metadata, then use the generic dimensions.
2105 width = Mosaic.Tile.GENERIC_ICON_SIZE; 2107 width = Mosaic.Tile.GENERIC_ICON_SIZE;
2106 height = Mosaic.Tile.GENERIC_ICON_SIZE; 2108 height = Mosaic.Tile.GENERIC_ICON_SIZE;
2107 } 2109 }
2108 2110
2109 if (width > height) { 2111 if (width > height) {
2110 if (width > Mosaic.Tile.MAX_CONTENT_SIZE) { 2112 if (width > Mosaic.Tile.MAX_CONTENT_SIZE) {
(...skipping 29 matching lines...) Expand all
2140 // Attaches the image to the tile and finalizes loading process for the 2142 // Attaches the image to the tile and finalizes loading process for the
2141 // specified loader. 2143 // specified loader.
2142 var finalizeLoader = function(mode, success, loader) { 2144 var finalizeLoader = function(mode, success, loader) {
2143 if (success && this.wrapper_) { 2145 if (success && this.wrapper_) {
2144 // Show the fade-in animation only when previously there was no image 2146 // Show the fade-in animation only when previously there was no image
2145 // attached in this tile. 2147 // attached in this tile.
2146 if (!this.imageLoaded_ && !this.imagePreloaded_) 2148 if (!this.imageLoaded_ && !this.imagePreloaded_)
2147 this.wrapper_.classList.add('animated'); 2149 this.wrapper_.classList.add('animated');
2148 else 2150 else
2149 this.wrapper_.classList.remove('animated'); 2151 this.wrapper_.classList.remove('animated');
2152
2153 // Add debug mode classes.
2154 this.wrapper_.classList.remove('load-target-content-metadata');
2155 this.wrapper_.classList.remove('load-target-external-metadata');
2156 this.wrapper_.classList.remove('load-target-file-entry');
2157 switch (loader.getLoadTarget()) {
2158 case ThumbnailLoader.LoadTarget.CONTENT_METADATA:
2159 this.wrapper_.classList.add('load-target-content-metadata');
2160 break;
2161 case ThumbnailLoader.LoadTarget.EXTERNAL_METADATA:
2162 this.wrapper_.classList.add('load-target-external-metadata');
2163 break;
2164 case ThumbnailLoader.LoadTarget.FILE_ENTRY:
2165 this.wrapper_.classList.add('load-target-file-entry');
2166 break;
2167 }
2168
2169 loader.attachImage(this.wrapper_, ThumbnailLoader.FillMode.OVER_FILL);
2150 } 2170 }
2151 2171
2152 // Add debug mode classes.
2153 this.wrapper_.classList.remove('load-target-content-metadata');
2154 this.wrapper_.classList.remove('load-target-external-metadata');
2155 this.wrapper_.classList.remove('load-target-file-entry');
2156 switch (loader.getLoadTarget()) {
2157 case ThumbnailLoader.LoadTarget.CONTENT_METADATA:
2158 this.wrapper_.classList.add('load-target-content-metadata');
2159 break;
2160 case ThumbnailLoader.LoadTarget.EXTERNAL_METADATA:
2161 this.wrapper_.classList.add('load-target-external-metadata');
2162 break;
2163 case ThumbnailLoader.LoadTarget.FILE_ENTRY:
2164 this.wrapper_.classList.add('load-target-file-entry');
2165 break;
2166 }
2167 loader.attachImage(this.wrapper_, ThumbnailLoader.FillMode.OVER_FILL);
2168 onImageLoaded(success); 2172 onImageLoaded(success);
2169 2173
2170 switch (mode) { 2174 switch (mode) {
2171 case Mosaic.Tile.LoadMode.LOW_DPI: 2175 case Mosaic.Tile.LoadMode.LOW_DPI:
2172 this.imagePreloading_ = false; 2176 this.imagePreloading_ = false;
2173 this.imagePreloaded_ = true; 2177 this.imagePreloaded_ = true;
2174 break; 2178 break;
2175 case Mosaic.Tile.LoadMode.HIGH_DPI: 2179 case Mosaic.Tile.LoadMode.HIGH_DPI:
2176 this.imageLoading_ = false; 2180 this.imageLoading_ = false;
2177 this.imageLoaded_ = true; 2181 this.imageLoaded_ = true;
(...skipping 10 matching lines...) Expand all
2188 if (this.imageLoaded_) 2192 if (this.imageLoaded_)
2189 return; 2193 return;
2190 finalizeLoader(Mosaic.Tile.LoadMode.LOW_DPI, 2194 finalizeLoader(Mosaic.Tile.LoadMode.LOW_DPI,
2191 success, 2195 success,
2192 this.thumbnailPreloader_); 2196 this.thumbnailPreloader_);
2193 }.bind(this)); 2197 }.bind(this));
2194 } 2198 }
2195 2199
2196 // Load the high-dpi image only when it is requested, or the low-dpi is not 2200 // Load the high-dpi image only when it is requested, or the low-dpi is not
2197 // available. 2201 // available.
2198 if (!this.imageLoading_ && 2202 if (!this.imageLoading_ && this.thumbnailLoader_ &&
2199 (loadMode === Mosaic.Tile.LoadMode.HIGH_DPI || !this.imagePreloading_)) { 2203 (loadMode === Mosaic.Tile.LoadMode.HIGH_DPI || !this.imagePreloading_)) {
2200 this.imageLoading_ = true; 2204 this.imageLoading_ = true;
2201 this.thumbnailLoader_.loadDetachedImage(function(success) { 2205 this.thumbnailLoader_.loadDetachedImage(function(success) {
2202 // Cancel preloading, since the hi-dpi image is ready. 2206 // Cancel preloading, since the hi-dpi image is ready.
2203 if (this.thumbnailPreloader_) 2207 if (this.thumbnailPreloader_)
2204 this.thumbnailPreloader_.cancel(); 2208 this.thumbnailPreloader_.cancel();
2205 finalizeLoader(Mosaic.Tile.LoadMode.HIGH_DPI, 2209 finalizeLoader(Mosaic.Tile.LoadMode.HIGH_DPI,
2206 success, 2210 success,
2207 this.thumbnailLoader_); 2211 this.thumbnailLoader_);
2208 }.bind(this)); 2212 }.bind(this));
2209 } 2213 }
2210 }; 2214 };
2211 2215
2212 /** 2216 /**
2213 * Unloads an image from the tile. 2217 * Unloads an image from the tile.
2214 */ 2218 */
2215 Mosaic.Tile.prototype.unload = function() { 2219 Mosaic.Tile.prototype.unload = function() {
2216 this.thumbnailLoader_.cancel(); 2220 if (this.thumbnailLoader_)
2221 this.thumbnailLoader_.cancel();
2217 if (this.thumbnailPreloader_) 2222 if (this.thumbnailPreloader_)
2218 this.thumbnailPreloader_.cancel(); 2223 this.thumbnailPreloader_.cancel();
2219 this.imagePreloaded_ = false; 2224 this.imagePreloaded_ = false;
2220 this.imageLoaded_ = false; 2225 this.imageLoaded_ = false;
2221 this.imagePreloading_ = false; 2226 this.imagePreloading_ = false;
2222 this.imageLoading_ = false; 2227 this.imageLoading_ = false;
2223 this.wrapper_.innerText = ''; 2228 if (this.wrapper_)
2229 this.wrapper_.innerText = '';
2224 }; 2230 };
2225 2231
2226 /** 2232 /**
2227 * Selects/unselects the tile. 2233 * Selects/unselects the tile.
2228 * 2234 *
2229 * @param {boolean} on True if selected. 2235 * @param {boolean} on True if selected.
2230 */ 2236 */
2231 Mosaic.Tile.prototype.select = function(on) { 2237 Mosaic.Tile.prototype.select = function(on) {
2232 if (on) 2238 if (on)
2233 this.setAttribute('selected', true); 2239 this.setAttribute('selected', true);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2309 return new ImageRect(this.left_ - this.container_.scrollLeft, this.top_, 2315 return new ImageRect(this.left_ - this.container_.scrollLeft, this.top_,
2310 this.width_, this.height_).inflate(-margin, -margin); 2316 this.width_, this.height_).inflate(-margin, -margin);
2311 }; 2317 };
2312 2318
2313 /** 2319 /**
2314 * @return {number} X coordinate of the tile center. 2320 * @return {number} X coordinate of the tile center.
2315 */ 2321 */
2316 Mosaic.Tile.prototype.getCenterX = function() { 2322 Mosaic.Tile.prototype.getCenterX = function() {
2317 return this.left_ + Math.round(this.width_ / 2); 2323 return this.left_ + Math.round(this.width_ / 2);
2318 }; 2324 };
OLDNEW
« no previous file with comments | « ui/file_manager/gallery/js/image_editor/image_util.js ('k') | ui/file_manager/gallery/js/ribbon.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698