/* * Paper.js - The Swiss Army Knife of Vector Graphics Scripting. * http://paperjs.org/ * * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey * http://lehni.org/ & http://jonathanpuckey.com/ * * Distributed under the MIT license. See LICENSE file for details. * * All rights reserved. */ /** * @name Component * @class */ var Component = Base.extend(Callback, /** @lends Component# */{ _class: 'Component', _events: [ 'onChange', 'onClick' ], _types: { 'boolean': { type: 'checkbox', value: 'checked' }, string: { type: 'text' }, number: { type: 'number', number: true }, button: { type: 'button' }, text: { tag: 'div', value: 'text' }, slider: { type: 'range', number: true }, list: { tag: 'select', options: function() { DomElement.removeChildren(this._inputItem); DomElement.create(Base.each(this._options, function(option) { this.push('option', { value: option, text: option }); }, []), this._inputItem); } } }, initialize: function Component(obj) { this._type = obj.type in this._types ? obj.type : 'options' in obj ? 'list' : 'onClick' in obj ? 'button' : typeof obj.value; this._info = this._types[this._type] || { type: this._type }; var that = this, dontFire = true; this._inputItem = DomElement.create(this._info.tag || 'input', { type: this._info.type, events: { change: function() { that.setValue( DomElement.get(this, that._info.value || 'value'), dontFire); }, click: function() { that.fire('click'); } } }); // Attach default 'change' even that delegates to palette this.attach('change', function(value) { if (!dontFire) this._palette.fire('change', this, this.name, value); }); this._element = DomElement.create('tr', [ this._labelItem = DomElement.create('td'), 'td', [this._inputItem] ]); Base.each(obj, function(value, key) { this[key] = value; }, this); this._defaultValue = this._value; // Start firing change events after we have initalized. dontFire = false; }, getType: function() { return this._type; }, getLabel: function() { return this._label; }, setLabel: function(label) { this._label = label; DomElement.set(this._labelItem, 'text', label + ':'); }, getOptions: function() { return this._options; }, setOptions: function(options) { this._options = options; if (this._info.options) this._info.options.call(this); }, getValue: function() { return this._value; }, setValue: function(value, _dontFire) { var key = this._info.value || 'value'; DomElement.set(this._inputItem, key, value); // Read back and convert from input again, to make sure we're in sync value = DomElement.get(this._inputItem, key); if (this._info.number) value = parseFloat(value, 10); if (this._value !== value) { this._value = value; if (!_dontFire) this.fire('change', value); } }, getRange: function() { return [parseFloat(DomElement.get(this._inputItem, 'min')), parseFloat(DomElement.get(this._inputItem, 'max'))]; }, setRange: function(min, max) { var range = Array.isArray(min) ? min : [min, max]; DomElement.set(this._inputItem, { min: range[0], max: range[1] }); }, getMin: function() { return this.getRange()[0]; }, setMin: function(min) { this.setRange(min, this.getMax()); }, getMax: function() { return this.getRange()[1]; }, setMax: function(max) { this.setRange(this.getMin(), max); }, getStep: function() { return parseFloat(DomElement.get(this._inputItem, 'step')); }, setStep: function(step) { DomElement.set(this._inputItem, 'step', step); }, reset: function() { this.setValue(this._defaultValue); } });