UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

243 lines (237 loc) 10.7 kB
/** _enyo.GridList_ extends <a href="#enyo.List">enyo.List</a>, allowing the display of multiple items per row, based on the available container width. Three rendering modes are supported: _fixedSize_, _fluidWidth_, and _variableSize_ (with or without normalization of rows). In _fixedSize_ mode, all items are of the same size, which may be configured upfront by setting the _itemWidth_ and _itemHeight_ properties at creation time. In _fluidWidth_ mode, all items are of the same size, but that size may grow or shrink to fit the available container width, while honoring the _itemMinWidth_ property. When the _itemWidth_ and _itemHeight_ are not known at creation time, you may set _normalizeRows_ to true and handle the _sizeupItem_ event to set the dimensions of each item at runtime. enyo.kind( { name: "App", components: [ { name: "gridList", kind: "enyo.GridList", onSizeupItem: "sizeupItem", onSetupItem: "setupItem", itemMinWidth: 160, itemSpacing: 2, components: [ {name: "img", kind: "enyo.Image"} ] }, ], ... //array of all item data _data: [], // example: [{width: 100, height: 100, source: "http://www.flickr.com/myimage.jpg"},....] sizeupItem: function(inSender, inEvent) { var item = this._data[inEvent.index]; inSender.setItemWidth(item.width); inSender.setItemHeight(item.height); }, setupItem: function(inSender, inEvent) { var item = this._data[inEvent.index]; this.$.img.setSrc(item.source); this.$.img.addStyles("width:100%; height: auto;"); return true; } ... }); */ enyo.kind( { name: "enyo.GridList", kind: "enyo.List", classes: "enyo-gridlist", published: { /** Set to true if you want all items to be of same size with fluid width (percentage-based width depending on how many items can fit in the available container width while honoring _itemMinWidth_). The _sizeupItem_ event is not fired in this case. */ itemFluidWidth: false, /** Set to true if you want all items to be of the same size, with fixed dimensions (configured by setting _itemWidth_ and _itemHeight_ upfront). The _sizeupItem_ event is not fired in this case. */ itemFixedSize: false, /** Minimum item width (in pixels). This is used to calculate the optimal _rowsPerPage_ (items per page) setting based on the available width of the container. */ itemMinWidth: 160, /** Minimum item height (in pixels). This is used to calculate the optimal _rowsPerPage_ (items per page) setting based on the available width of the container. */ itemMinHeight: 160, /** Width of each item (in pixels). The _sizeupItem_ event may be handled to set the width of each item at runtime. This value may be set upfront for all fixed-size items; for variable-sized items, any _itemWidth_ values set upfront will be ignored. */ itemWidth: 160, /** Height of each item (in pixels). The _sizeupItem_ event may be handled to set the height of each item at runtime. This value may be set upfront for all fixed-size items; for variable-sized items, any _itemHeight_ values set upfront will be ignored. */ itemHeight: 160, //* Spacing (in pixels) between GridList items. itemSpacing: 0, /** Set to true if you want the items in each GridList row to be normalized to the same height. If either _itemFluidWidth_ or _itemFixedSize_ is set to true, this setting will be ignored (i.e., rows will not be normalized for improved performance), since we already know that the items have the same height. */ normalizeRows: false }, horizontal: "hidden", events: { /** Fires once per item only in cases when items are NOT fluid-width or fixed-size at pre-render time. This gives the developer an opportunity to set the dimensions of the item. _inEvent.index_ contains the current item index. */ onSizeupItem: "" }, /** Designed to be called after the GridList data is ready, this method sets the _count_ on the list and renders it. This is a convenience method that calls _setCount()_ and then _reset()_ on the List, so the developer does not have to invoke the two methods separately. */ show: function(count) { this._calculateItemsPerRow(); this.setCount(count); this.reset(); }, create: enyo.inherit(function(sup) { return function() { this._setComponents(); sup.apply(this, arguments); this.itemFluidWidthChanged(); this.itemFixedSizeChanged(); this.itemMinWidthChanged(); this.itemMinHeightChanged(); this.itemWidthChanged(); this.itemHeightChanged(); this.itemSpacingChanged(); this.normalizeRowsChanged(); this.$.generator.setClientClasses("enyo-gridlist-row"); }; }), // Relays the published-property changes over to the GridFlyweightRepeater. itemFluidWidthChanged: function() { this.$.generator.itemFluidWidth = this.itemFluidWidth; this.setNormalizeRows(!this.itemFluidWidth && !this.itemFixedSize); }, itemFixedSizeChanged: function() { this.$.generator.itemFixedSize = this.itemFixedSize; this.setNormalizeRows(!this.itemFluidWidth && !this.itemFixedSize); }, itemWidthChanged: function() { this.$.generator.itemWidth = this.itemWidth; }, itemHeightChanged: function() { this.$.generator.itemHeight = this.itemHeight; }, itemMinWidthChanged: function() { var n = this.hasNode(); if (n) { if (!this.itemMinWidth) { this.itemMinWidth = 160; } this.itemMinWidth = Math.min(this.itemMinWidth, n.clientWidth); } this.$.generator.itemMinWidth = this.itemMinWidth; }, itemMinHeightChanged: function() { var n = this.hasNode(); if (n) { if (!this.itemMinHeight) { this.itemMinHeight = 160; } this.itemMinHeight = Math.min(this.itemMinHeight, n.clientHeight); } this.$.generator.itemMinHeight = this.itemMinHeight; }, itemSpacingChanged: function() { if (this.itemSpacing < 0) { this.itemSpacing = 0; } this.itemSpacing = this.itemSpacing; this.$.generator.itemSpacing = this.itemSpacing; }, normalizeRowsChanged: function() { this.$.generator.normalizeRows = this.normalizeRows; }, //* @protected bottomUpChanged: function() { //Don't let users change this (bottomUp is a published property of List but is not supported by GridList) this.bottomUp = false; this.pageBound = 'top'; }, //* @protected reflow: enyo.inherit(function(sup) { return function() { this._calculateItemsPerRow(); sup.apply(this, arguments); }; }), //* @protected _calculateItemsPerRow: function() { var n = this.hasNode(); if (n) { this.itemsPerRow = Math.floor((n.clientWidth - this.itemSpacing)/(this.itemMinWidth + this.itemSpacing)); var visibleRows = Math.round((n.clientHeight - this.itemSpacing)/(this.itemMinHeight + this.itemSpacing)); if (this.itemFixedSize || this.itemFluidWidth) { var itemsPerRow = Math.floor((n.clientWidth - this.itemSpacing)/(this.itemWidth + this.itemSpacing)); var low = Math.floor(itemsPerRow); var high = Math.ceil(itemsPerRow); var gutter = n.clientWidth - this.itemSpacing - (high * (this.itemWidth + this.itemSpacing)); this.itemsPerRow = (gutter > 0) ? high : low; visibleRows = Math.round((n.clientHeight - this.itemSpacing)/(this.itemHeight + this.itemSpacing)); } // Make sure there's at least 1 item per row this.itemsPerRow = Math.max(1, this.itemsPerRow); this.rowsPerPage = 3 * this.itemsPerRow * visibleRows; this.$.generator.itemsPerRow = this.itemsPerRow; } }, //* @protected _setComponents: function() { // TODO: The entire implementation of GridList needs an overhaul, but for now this ugly cloning is // needed to prevent the generator kind modification below from modifying enyo.Lists's generator this.listTools = enyo.clone(this.listTools); this.listTools[0] = enyo.clone(this.listTools[0]); this.listTools[0].components = enyo.clone(this.listTools[0].components); var c = this.listTools[0].components; // Create a dummy component to dynamically compute the dimensions of items at run-time (once for each item during sizeupItem) based on the actual content inside the item (only for variable sized items where sizeupItem is called). this.createComponent(new enyo.Component({name: "_dummy_", allowHtml: true, classes: "enyo-gridlist-dummy", showing: false}, {owner: this})); // Override List's listTools array to use GridFlyweightRepeater instead of FlyweightRepeater for (var i=0; i<c.length; i++) { if (c[i].name == 'generator') { c[i] = enyo.clone(c[i]); c[i].kind = "enyo.GridFlyWeightRepeater"; return; } } } } );