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

Side by Side Diff: chrome/browser/resources/file_manager/foreground/js/file_grid.js

Issue 247123002: Move Files.app files to ui/file_manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix the test failure on non-chromeos Created 6 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 'use strict';
6
7 /**
8 * FileGrid constructor.
9 *
10 * Represents grid for the Grid View in the File Manager.
11 * @constructor
12 * @extends {cr.ui.Grid}
13 */
14
15 function FileGrid() {
16 throw new Error('Use FileGrid.decorate');
17 }
18
19 /**
20 * Thumbnail quality.
21 * @enum {number}
22 */
23 FileGrid.ThumbnailQuality = {
24 LOW: 0,
25 HIGH: 1
26 };
27
28 /**
29 * Inherits from cr.ui.Grid.
30 */
31 FileGrid.prototype.__proto__ = cr.ui.Grid.prototype;
32
33 /**
34 * Decorates an HTML element to be a FileGrid.
35 * @param {HTMLElement} self The grid to decorate.
36 * @param {MetadataCache} metadataCache Metadata cache to find entries
37 * metadata.
38 * @param {VolumeManagerWrapper} volumeManager Volume manager instance.
39 */
40 FileGrid.decorate = function(self, metadataCache, volumeManager) {
41 cr.ui.Grid.decorate(self);
42 self.__proto__ = FileGrid.prototype;
43 self.metadataCache_ = metadataCache;
44 self.volumeManager_ = volumeManager;
45
46 self.scrollBar_ = new MainPanelScrollBar();
47 self.scrollBar_.initialize(self.parentNode, self);
48 self.setBottomMarginForPanel(0);
49
50 self.itemConstructor = function(entry) {
51 var item = self.ownerDocument.createElement('LI');
52 FileGrid.Item.decorate(item, entry, self);
53 return item;
54 };
55
56 self.relayoutAggregation_ =
57 new AsyncUtil.Aggregation(self.relayoutImmediately_.bind(self));
58 };
59
60 /**
61 * Updates items to reflect metadata changes.
62 * @param {string} type Type of metadata changed.
63 * @param {Object.<string, Object>} props Map from entry URLs to metadata props.
64 */
65 FileGrid.prototype.updateListItemsMetadata = function(type, props) {
66 var boxes = this.querySelectorAll('.img-container');
67 for (var i = 0; i < boxes.length; i++) {
68 var box = boxes[i];
69 var entry = this.dataModel.item(this.getListItemAncestor(box));
70 if (!entry || !(entry.toURL() in props))
71 continue;
72
73 FileGrid.decorateThumbnailBox(box,
74 entry,
75 this.metadataCache_,
76 this.volumeManager_,
77 ThumbnailLoader.FillMode.FIT,
78 FileGrid.ThumbnailQuality.HIGH);
79 }
80 };
81
82 /**
83 * Redraws the UI. Skips multiple consecutive calls.
84 */
85 FileGrid.prototype.relayout = function() {
86 this.relayoutAggregation_.run();
87 };
88
89 /**
90 * Redraws the UI immediately.
91 * @private
92 */
93 FileGrid.prototype.relayoutImmediately_ = function() {
94 this.startBatchUpdates();
95 this.columns = 0;
96 this.redraw();
97 this.endBatchUpdates();
98 cr.dispatchSimpleEvent(this, 'relayout');
99 };
100
101 /**
102 * Decorates thumbnail.
103 * @param {HTMLElement} li List item.
104 * @param {Entry} entry Entry to render a thumbnail for.
105 * @param {MetadataCache} metadataCache To retrieve metadata.
106 * @param {VolumeManagerWrapper} volumeManager Volume manager instance.
107 */
108 FileGrid.decorateThumbnail = function(li, entry, metadataCache, volumeManager) {
109 li.className = 'thumbnail-item';
110 if (entry)
111 filelist.decorateListItem(li, entry, metadataCache);
112
113 var frame = li.ownerDocument.createElement('div');
114 frame.className = 'thumbnail-frame';
115 li.appendChild(frame);
116
117 var box = li.ownerDocument.createElement('div');
118 if (entry) {
119 FileGrid.decorateThumbnailBox(box,
120 entry,
121 metadataCache,
122 volumeManager,
123 ThumbnailLoader.FillMode.AUTO,
124 FileGrid.ThumbnailQuality.HIGH);
125 }
126 frame.appendChild(box);
127
128 var bottom = li.ownerDocument.createElement('div');
129 bottom.className = 'thumbnail-bottom';
130 bottom.appendChild(filelist.renderFileNameLabel(li.ownerDocument, entry));
131 frame.appendChild(bottom);
132 };
133
134 /**
135 * Decorates the box containing a centered thumbnail image.
136 *
137 * @param {HTMLDivElement} box Box to decorate.
138 * @param {Entry} entry Entry which thumbnail is generating for.
139 * @param {MetadataCache} metadataCache To retrieve metadata.
140 * @param {VolumeManagerWrapper} volumeManager Volume manager instance.
141 * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
142 * @param {FileGrid.ThumbnailQuality} quality Thumbnail quality.
143 * @param {function(HTMLElement)=} opt_imageLoadCallback Callback called when
144 * the image has been loaded before inserting it into the DOM.
145 */
146 FileGrid.decorateThumbnailBox = function(
147 box, entry, metadataCache, volumeManager, fillMode, quality,
148 opt_imageLoadCallback) {
149 box.className = 'img-container';
150 if (entry.isDirectory) {
151 box.setAttribute('generic-thumbnail', 'folder');
152 if (opt_imageLoadCallback)
153 setTimeout(opt_imageLoadCallback, 0, null /* callback parameter */);
154 return;
155 }
156
157 var metadataTypes = 'thumbnail|filesystem';
158
159 var locationInfo = volumeManager.getLocationInfo(entry);
160 if (locationInfo && locationInfo.isDriveBased) {
161 metadataTypes += '|drive';
162 } else {
163 // TODO(dgozman): If we ask for 'media' for a Drive file we fall into an
164 // infinite loop.
165 metadataTypes += '|media';
166 }
167
168 // Drive provides high quality thumbnails via USE_EMBEDDED, however local
169 // images usually provide very tiny thumbnails, therefore USE_EMBEDDE can't
170 // be used to obtain high quality output.
171 var useEmbedded;
172 switch (quality) {
173 case FileGrid.ThumbnailQuality.LOW:
174 useEmbedded = ThumbnailLoader.UseEmbedded.USE_EMBEDDED;
175 break;
176 case FileGrid.ThumbnailQuality.HIGH:
177 // TODO(mtomasz): Use Entry instead of paths.
178 useEmbedded = (locationInfo && locationInfo.isDriveBased) ?
179 ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
180 ThumbnailLoader.UseEmbedded.NO_EMBEDDED;
181 break;
182 }
183
184 metadataCache.get(entry, metadataTypes,
185 function(metadata) {
186 new ThumbnailLoader(entry,
187 ThumbnailLoader.LoaderType.IMAGE,
188 metadata,
189 undefined, // opt_mediaType
190 useEmbedded).
191 load(box,
192 fillMode,
193 ThumbnailLoader.OptimizationMode.DISCARD_DETACHED,
194 opt_imageLoadCallback);
195 });
196 };
197
198 /**
199 * Item for the Grid View.
200 * @constructor
201 */
202 FileGrid.Item = function() {
203 throw new Error();
204 };
205
206 /**
207 * Inherits from cr.ui.ListItem.
208 */
209 FileGrid.Item.prototype.__proto__ = cr.ui.ListItem.prototype;
210
211 Object.defineProperty(FileGrid.Item.prototype, 'label', {
212 /**
213 * @this {FileGrid.Item}
214 * @return {string} Label of the item.
215 */
216 get: function() {
217 return this.querySelector('filename-label').textContent;
218 }
219 });
220
221 /**
222 * @param {Element} li List item element.
223 * @param {Entry} entry File entry.
224 * @param {FileGrid} grid Owner.
225 */
226 FileGrid.Item.decorate = function(li, entry, grid) {
227 li.__proto__ = FileGrid.Item.prototype;
228 // TODO(mtomasz): Pass the metadata cache and the volume manager directly
229 // instead of accessing private members of grid.
230 FileGrid.decorateThumbnail(
231 li, entry, grid.metadataCache_, grid.volumeManager_, true);
232
233 // Override the default role 'listitem' to 'option' to match the parent's
234 // role (listbox).
235 li.setAttribute('role', 'option');
236 };
237
238 /**
239 * Sets the margin height for the transparent preview panel at the bottom.
240 * @param {number} margin Margin to be set in px.
241 */
242 FileGrid.prototype.setBottomMarginForPanel = function(margin) {
243 // +20 bottom margin is needed to match the bottom margin size with the
244 // margin between its items.
245 this.style.paddingBottom = (margin + 20) + 'px';
246 this.scrollBar_.setBottomMarginForPanel(margin);
247 };
248
249 /**
250 * Obtains if the drag selection should be start or not by referring the mouse
251 * event.
252 * @param {MouseEvent} event Drag start event.
253 * @return {boolean} True if the mouse is hit to the background of the list.
254 */
255 FileGrid.prototype.shouldStartDragSelection = function(event) {
256 var pos = DragSelector.getScrolledPosition(this, event);
257 return this.getHitElements(pos.x, pos.y).length === 0;
258 };
259
260 /**
261 * Obtains the column/row index that the coordinate points.
262 * @param {number} coordinate Vertical/horizontal coordinate value that points
263 * column/row.
264 * @param {number} step Length from a column/row to the next one.
265 * @param {number} threshold Threshold that determines whether 1 offset is added
266 * to the return value or not. This is used in order to handle the margin of
267 * column/row.
268 * @return {number} Index of hit column/row.
269 * @private
270 */
271 FileGrid.prototype.getHitIndex_ = function(coordinate, step, threshold) {
272 var index = ~~(coordinate / step);
273 return (coordinate % step >= threshold) ? index + 1 : index;
274 };
275
276 /**
277 * Obtains the index list of elements that are hit by the point or the
278 * rectangle.
279 *
280 * We should match its argument interface with FileList.getHitElements.
281 *
282 * @param {number} x X coordinate value.
283 * @param {number} y Y coordinate value.
284 * @param {=number} opt_width Width of the coordinate.
285 * @param {=number} opt_height Height of the coordinate.
286 * @return {Array.<number>} Index list of hit elements.
287 */
288 FileGrid.prototype.getHitElements = function(x, y, opt_width, opt_height) {
289 var currentSelection = [];
290 var right = x + (opt_width || 0);
291 var bottom = y + (opt_height || 0);
292 var itemMetrics = this.measureItem();
293 var horizontalStartIndex = this.getHitIndex_(
294 x, itemMetrics.width, itemMetrics.width - itemMetrics.marginRight);
295 var horizontalEndIndex = Math.min(this.columns, this.getHitIndex_(
296 right, itemMetrics.width, itemMetrics.marginLeft));
297 var verticalStartIndex = this.getHitIndex_(
298 y, itemMetrics.height, itemMetrics.height - itemMetrics.bottom);
299 var verticalEndIndex = this.getHitIndex_(
300 bottom, itemMetrics.height, itemMetrics.marginTop);
301 for (var verticalIndex = verticalStartIndex;
302 verticalIndex < verticalEndIndex;
303 verticalIndex++) {
304 var indexBase = this.getFirstItemInRow(verticalIndex);
305 for (var horizontalIndex = horizontalStartIndex;
306 horizontalIndex < horizontalEndIndex;
307 horizontalIndex++) {
308 var index = indexBase + horizontalIndex;
309 if (0 <= index && index < this.dataModel.length)
310 currentSelection.push(index);
311 }
312 }
313 return currentSelection;
314 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698