blob: 5cbe2ffe20fba0b61ebc90b2a5cf753bc00cc24f [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
/**
* FileGrid constructor.
*
* Represents grid for the Grid Vew in the File Manager.
* @constructor
* @extends {cr.ui.Grid}
*/
function FileGrid() {
throw new Error('Use FileGrid.decorate');
}
/**
* Thumbnail quality.
* @enum {number}
*/
FileGrid.ThumbnailQuality = {
LOW: 0,
HIGH: 1
};
/**
* Inherits from cr.ui.Grid.
*/
FileGrid.prototype.__proto__ = cr.ui.Grid.prototype;
/**
* Decorates an HTML element to be a FileGrid.
* @param {HTMLElement} self The grid to decorate.
* @param {MetadataCache} metadataCache Metadata cache to find entries
* metadata.
*/
FileGrid.decorate = function(self, metadataCache) {
cr.ui.Grid.decorate(self);
self.__proto__ = FileGrid.prototype;
self.metadataCache_ = metadataCache;
self.scrollBar_ = new MainPanelScrollBar();
self.scrollBar_.initialize(self.parentNode, self);
self.itemConstructor = function(entry) {
var item = self.ownerDocument.createElement('LI');
FileGrid.Item.decorate(item, entry, self);
return item;
};
self.relayoutAggregation_ =
new AsyncUtil.Aggregation(self.relayoutImmediately_.bind(self));
};
/**
* Updates items to reflect metadata changes.
* @param {string} type Type of metadata changed.
* @param {Object.<string, Object>} props Map from entry URLs to metadata props.
*/
FileGrid.prototype.updateListItemsMetadata = function(type, props) {
var boxes = this.querySelectorAll('.img-container');
for (var i = 0; i < boxes.length; i++) {
var box = boxes[i];
var entry = this.dataModel.item(this.getListItemAncestor(box));
if (!entry || !(entry.toURL() in props))
continue;
FileGrid.decorateThumbnailBox(box,
entry,
this.metadataCache_,
ThumbnailLoader.FillMode.FIT,
FileGrid.ThumbnailQuality.HIGH);
}
};
/**
* Redraws the UI. Skips multiple consecutive calls.
*/
FileGrid.prototype.relayout = function() {
this.relayoutAggregation_.run();
};
/**
* Redraws the UI immediately.
* @private
*/
FileGrid.prototype.relayoutImmediately_ = function() {
this.startBatchUpdates();
this.columns = 0;
this.redraw();
this.endBatchUpdates();
cr.dispatchSimpleEvent(this, 'relayout');
};
/**
* Decorates thumbnail.
* @param {HTMLElement} li List item.
* @param {Entry} entry Entry to render a thumbnail for.
* @param {MetadataCache} metadataCache To retrieve metadata.
*/
FileGrid.decorateThumbnail = function(li, entry, metadataCache) {
li.className = 'thumbnail-item';
filelist.decorateListItem(li, entry, metadataCache);
var frame = li.ownerDocument.createElement('div');
frame.className = 'thumbnail-frame';
li.appendChild(frame);
var box = li.ownerDocument.createElement('div');
FileGrid.decorateThumbnailBox(box,
entry,
metadataCache,
ThumbnailLoader.FillMode.AUTO,
FileGrid.ThumbnailQuality.HIGH);
frame.appendChild(box);
var bottom = li.ownerDocument.createElement('div');
bottom.className = 'thumbnail-bottom';
frame.appendChild(bottom);
bottom.appendChild(filelist.renderFileNameLabel(li.ownerDocument, entry));
};
/**
* Decorates the box containing a centered thumbnail image.
*
* @param {HTMLDivElement} box Box to decorate.
* @param {Entry} entry Entry which thumbnail is generating for.
* @param {MetadataCache} metadataCache To retrieve metadata.
* @param {ThumbnailLoader.FillMode} fillMode Fill mode.
* @param {FileGrid.ThumbnailQuality} quality Thumbnail quality.
* @param {function(HTMLElement)=} opt_imageLoadCallback Callback called when
* the image has been loaded before inserting it into the DOM.
*/
FileGrid.decorateThumbnailBox = function(
box, entry, metadataCache, fillMode, quality, opt_imageLoadCallback) {
box.className = 'img-container';
if (entry.isDirectory) {
box.setAttribute('generic-thumbnail', 'folder');
if (opt_imageLoadCallback)
setTimeout(opt_imageLoadCallback, 0, null /* callback parameter */);
return;
}
var imageUrl = entry.toURL();
var metadataTypes = 'thumbnail|filesystem';
if (FileType.isOnDrive(imageUrl)) {
metadataTypes += '|drive';
} else {
// TODO(dgozman): If we ask for 'media' for a Drive file we fall into an
// infinite loop.
metadataTypes += '|media';
}
// Drive provides high quality thumbnails via USE_EMBEDDED, however local
// images usually provide very tiny thumbnails, therefore USE_EMBEDDE can't
// be used to obtain high quality output.
var useEmbedded;
switch (quality) {
case FileGrid.ThumbnailQuality.LOW:
useEmbedded = ThumbnailLoader.UseEmbedded.USE_EMBEDDED;
break;
case FileGrid.ThumbnailQuality.HIGH:
useEmbedded = FileType.isOnDrive(imageUrl) ?
ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
ThumbnailLoader.UseEmbedded.NO_EMBEDDED;
break;
}
metadataCache.get(imageUrl, metadataTypes,
function(metadata) {
new ThumbnailLoader(imageUrl,
ThumbnailLoader.LoaderType.IMAGE,
metadata,
undefined, // opt_mediaType
useEmbedded).
load(box,
fillMode,
ThumbnailLoader.OptimizationMode.DISCARD_DETACHED,
opt_imageLoadCallback);
});
};
/**
* Item for the Grid View.
* @constructor
*/
FileGrid.Item = function() {
throw new Error();
};
/**
* Inherits from cr.ui.ListItem.
*/
FileGrid.Item.prototype.__proto__ = cr.ui.ListItem.prototype;
Object.defineProperty(FileGrid.Item.prototype, 'label', {
/**
* @this {FileGrid.Item}
* @return {string} Label of the item.
*/
get: function() {
return this.querySelector('filename-label').textContent;
}
});
/**
* @param {Element} li List item element.
* @param {Entry} entry File entry.
* @param {FileGrid} grid Owner.
*/
FileGrid.Item.decorate = function(li, entry, grid) {
li.__proto__ = FileGrid.Item.prototype;
FileGrid.decorateThumbnail(li, entry, grid.metadataCache_, true);
// Override the default role 'listitem' to 'option' to match the parent's
// role (listbox).
li.setAttribute('role', 'option');
};
/**
* Sets the margin height for the transparent preview panel at the bottom.
* @param {number} margin Margin to be set in px.
*/
FileGrid.prototype.setBottomMarginForPanel = function(margin) {
this.style.paddingBottom = margin + 'px';
this.scrollBar_.setBottomMarginForPanel(margin);
};