awips2/components/core-iconset/core-iconset.html
2016-04-03 22:04:09 -05:00

241 lines
8.2 KiB
HTML

<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<!--
/**
* @group Polymer Core Elements
*
* The `core-iconset` element allows users to define their own icon sets.
* The `src` property specifies the url of the icon image. Multiple icons may
* be included in this image and they may be organized into rows.
* The `icons` property is a space separated list of names corresponding to the
* icons. The names must be ordered as the icons are ordered in the icon image.
* Icons are expected to be square and are the size specified by the `iconSize`
* property. The `width` property corresponds to the width of the icon image
* and must be specified if icons are arranged into multiple rows in the image.
*
* All `core-iconset` elements are available for use by other `core-iconset`
* elements via a database keyed by id. Typically, an element author that wants
* to support a set of custom icons uses a `core-iconset` to retrieve
* and use another, user-defined iconset.
*
* Example:
*
* <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
* icons="location place starta stopb bus car train walk">
* </core-iconset>
*
* This will automatically register the icon set "my-icons" to the iconset
* database. To use these icons from within another element, make a
* `core-iconset` element and call the `byId` method to retrieve a
* given iconset. To apply a particular icon to an element, use the
* `applyIcon` method. For example:
*
* iconset.applyIcon(iconNode, 'car');
*
* Themed icon sets are also supported. The `core-iconset` can contain child
* `property` elements that specify a theme with an offsetX and offsetY of the
* theme within the icon resource. For example.
*
* <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
* icons="location place starta stopb bus car train walk">
* <property theme="special" offsetX="256" offsetY="24"></property>
* </core-iconset>
*
* Then a themed icon can be applied like this:
*
* iconset.applyIcon(iconNode, 'car', 'special');
*
* @element core-iconset
* @extends core-meta
* @homepage github.io
*/
-->
<link rel="import" href="../core-meta/core-meta.html">
<polymer-element name="core-iconset" extends="core-meta" attributes="src width icons iconSize">
<script>
Polymer('core-iconset', {
/**
* The URL of the iconset image.
*
* @attribute src
* @type string
* @default ''
*/
src: '',
/**
* The width of the iconset image. This must only be specified if the
* icons are arranged into separate rows inside the image.
*
* @attribute width
* @type number
* @default 0
*/
width: 0,
/**
* A space separated list of names corresponding to icons in the iconset
* image file. This list must be ordered the same as the icon images
* in the image file.
*
* @attribute icons
* @type string
* @default ''
*/
icons: '',
/**
* The size of an individual icon. Note that icons must be square.
*
* @attribute iconSize
* @type number
* @default 24
*/
iconSize: 24,
/**
* The horizontal offset of the icon images in the inconset src image.
* This is typically used if the image resource contains additional images
* beside those intended for the iconset.
*
* @attribute offsetX
* @type number
* @default 0
*/
offsetX: 0,
/**
* The vertical offset of the icon images in the inconset src image.
* This is typically used if the image resource contains additional images
* beside those intended for the iconset.
*
* @attribute offsetY
* @type number
* @default 0
*/
offsetY: 0,
type: 'iconset',
created: function() {
this.iconMap = {};
this.iconNames = [];
this.themes = {};
},
ready: function() {
// TODO(sorvell): ensure iconset's src is always relative to the main
// document
if (this.src && (this.ownerDocument !== document)) {
this.src = this.resolvePath(this.src, this.ownerDocument.baseURI);
}
this.super();
this.updateThemes();
},
iconsChanged: function() {
var ox = this.offsetX;
var oy = this.offsetY;
this.icons && this.icons.split(/\s+/g).forEach(function(name, i) {
this.iconNames.push(name);
this.iconMap[name] = {
offsetX: ox,
offsetY: oy
}
if (ox + this.iconSize < this.width) {
ox += this.iconSize;
} else {
ox = this.offsetX;
oy += this.iconSize;
}
}, this);
},
updateThemes: function() {
var ts = this.querySelectorAll('property[theme]');
ts && ts.array().forEach(function(t) {
this.themes[t.getAttribute('theme')] = {
offsetX: parseInt(t.getAttribute('offsetX')) || 0,
offsetY: parseInt(t.getAttribute('offsetY')) || 0
};
}, this);
},
// TODO(ffu): support retrived by index e.g. getOffset(10);
/**
* Returns an object containing `offsetX` and `offsetY` properties which
* specify the pixel locaion in the iconset's src file for the given
* `icon` and `theme`. It's uncommon to call this method. It is useful,
* for example, to manually position a css backgroundImage to the proper
* offset. It's more common to use the `applyIcon` method.
*
* @method getOffset
* @param {String|Number} icon The name of the icon or the index of the
* icon within in the icon image.
* @param {String} theme The name of the theme.
* @returns {Object} An object specifying the offset of the given icon
* within the icon resource file; `offsetX` is the horizontal offset and
* `offsetY` is the vertical offset. Both values are in pixel units.
*/
getOffset: function(icon, theme) {
var i = this.iconMap[icon];
if (!i) {
var n = this.iconNames[Number(icon)];
i = this.iconMap[n];
}
var t = this.themes[theme];
if (i && t) {
return {
offsetX: i.offsetX + t.offsetX,
offsetY: i.offsetY + t.offsetY
}
}
return i;
},
/**
* Applies an icon to the given element as a css background image. This
* method does not size the element, and it's often necessary to set
* the element's height and width so that the background image is visible.
*
* @method applyIcon
* @param {Element} element The element to which the background is
* applied.
* @param {String|Number} icon The name or index of the icon to apply.
* @param {Number} scale (optional, defaults to 1) A scaling factor
* with which the icon can be magnified.
* @return {Element} The icon element.
*/
applyIcon: function(element, icon, scale) {
var offset = this.getOffset(icon);
scale = scale || 1;
if (element && offset) {
var icon = element._icon || document.createElement('div');
var style = icon.style;
style.backgroundImage = 'url(' + this.src + ')';
style.backgroundPosition = (-offset.offsetX * scale + 'px') +
' ' + (-offset.offsetY * scale + 'px');
style.backgroundSize = scale === 1 ? 'auto' :
this.width * scale + 'px';
if (icon.parentNode !== element) {
element.appendChild(icon);
}
return icon;
}
}
});
</script>
</polymer-element>