OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * Data model for gallery. |
| 7 * |
| 8 * @param {!MetadataCache} metadataCache Metadata cache. |
| 9 * @param {!EntryListWatcher=} opt_watcher Entry list watcher. |
| 10 * @constructor |
| 11 * @extends {cr.ui.ArrayDataModel} |
| 12 */ |
| 13 function GalleryDataModel(metadataCache, opt_watcher) { |
| 14 cr.ui.ArrayDataModel.call(this, []); |
| 15 |
| 16 /** |
| 17 * Metadata cache. |
| 18 * @type {!MetadataCache} |
| 19 * @private |
| 20 */ |
| 21 this.metadataCache_ = metadataCache; |
| 22 |
| 23 /** |
| 24 * Directory where the image is saved if the image is located in a read-only |
| 25 * volume. |
| 26 * @type {DirectoryEntry} |
| 27 */ |
| 28 this.fallbackSaveDirectory = null; |
| 29 |
| 30 // Start to watch file system entries. |
| 31 var watcher = opt_watcher ? opt_watcher : new EntryListWatcher(this); |
| 32 watcher.getEntry = function(item) { return item.getEntry(); }; |
| 33 } |
| 34 |
| 35 /** |
| 36 * Maximum number of full size image cache. |
| 37 * @type {number} |
| 38 * @const |
| 39 * @private |
| 40 */ |
| 41 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3; |
| 42 |
| 43 /** |
| 44 * Maximum number of screen size image cache. |
| 45 * @type {number} |
| 46 * @const |
| 47 * @private |
| 48 */ |
| 49 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5; |
| 50 |
| 51 GalleryDataModel.prototype = { |
| 52 __proto__: cr.ui.ArrayDataModel.prototype |
| 53 }; |
| 54 |
| 55 /** |
| 56 * Saves new image. |
| 57 * |
| 58 * @param {!VolumeManager} volumeManager Volume manager instance. |
| 59 * @param {!Gallery.Item} item Original gallery item. |
| 60 * @param {!HTMLCanvasElement} canvas Canvas containing new image. |
| 61 * @param {boolean} overwrite Whether to overwrite the image to the item or not. |
| 62 * @return {!Promise} Promise to be fulfilled with when the operation completes. |
| 63 */ |
| 64 GalleryDataModel.prototype.saveItem = function( |
| 65 volumeManager, item, canvas, overwrite) { |
| 66 var oldEntry = item.getEntry(); |
| 67 var oldMetadata = item.getMetadata(); |
| 68 var oldLocationInfo = item.getLocationInfo(); |
| 69 return new Promise(function(fulfill, reject) { |
| 70 item.saveToFile( |
| 71 volumeManager, |
| 72 this.fallbackSaveDirectory, |
| 73 overwrite, |
| 74 canvas, |
| 75 function(success) { |
| 76 if (!success) { |
| 77 reject('Failed to save the image.'); |
| 78 return; |
| 79 } |
| 80 |
| 81 // Current entry is updated. |
| 82 // Dispatch an event. |
| 83 var event = new Event('content'); |
| 84 event.item = item; |
| 85 event.oldEntry = oldEntry; |
| 86 event.metadata = item.getMetadata(); |
| 87 this.dispatchEvent(event); |
| 88 |
| 89 if (!util.isSameEntry(oldEntry, item.getEntry())) { |
| 90 // New entry is added and the item now tracks it. |
| 91 // Add another item for the old entry. |
| 92 var anotherItem = new Gallery.Item( |
| 93 oldEntry, |
| 94 oldLocationInfo, |
| 95 oldMetadata, |
| 96 this.metadataCache_, |
| 97 item.isOriginal()); |
| 98 // The item must be added behind the existing item so that it does |
| 99 // not change the index of the existing item. |
| 100 // TODO(hirono): Update the item index of the selection model |
| 101 // correctly. |
| 102 this.splice(this.indexOf(item) + 1, 0, anotherItem); |
| 103 } |
| 104 |
| 105 fulfill(); |
| 106 }.bind(this)); |
| 107 }.bind(this)); |
| 108 }; |
| 109 |
| 110 /** |
| 111 * Evicts image caches in the items. |
| 112 */ |
| 113 GalleryDataModel.prototype.evictCache = function() { |
| 114 // Sort the item by the last accessed date. |
| 115 var sorted = this.slice().sort(function(a, b) { |
| 116 return b.getLastAccessedDate() - a.getLastAccessedDate(); |
| 117 }); |
| 118 |
| 119 // Evict caches. |
| 120 var contentCacheCount = 0; |
| 121 var screenCacheCount = 0; |
| 122 for (var i = 0; i < sorted.length; i++) { |
| 123 if (sorted[i].contentImage) { |
| 124 if (++contentCacheCount > GalleryDataModel.MAX_FULL_IMAGE_CACHE_) { |
| 125 if (sorted[i].contentImage.parentNode) { |
| 126 console.error('The content image has a parent node.'); |
| 127 } else { |
| 128 // Force to free the buffer of the canvas by assigning zero size. |
| 129 sorted[i].contentImage.width = 0; |
| 130 sorted[i].contentImage.height = 0; |
| 131 sorted[i].contentImage = null; |
| 132 } |
| 133 } |
| 134 } |
| 135 if (sorted[i].screenImage) { |
| 136 if (++screenCacheCount > GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_) { |
| 137 if (sorted[i].screenImage.parentNode) { |
| 138 console.error('The screen image has a parent node.'); |
| 139 } else { |
| 140 // Force to free the buffer of the canvas by assigning zero size. |
| 141 sorted[i].screenImage.width = 0; |
| 142 sorted[i].screenImage.height = 0; |
| 143 sorted[i].screenImage = null; |
| 144 } |
| 145 } |
| 146 } |
| 147 } |
| 148 }; |
OLD | NEW |