Check in first version of Scriptographer-style Palette / Component GUI code, including a basic example.

It kinda works already!
This commit is contained in:
Jürg Lehni 2012-11-14 01:35:34 -08:00
parent 9a180b5377
commit 550d43ae0b
4 changed files with 309 additions and 0 deletions

View file

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Paelette</title>
<link rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="../../dist/paper.js"></script>
<script type="text/paperscript" canvas="canvas">
var values = {
number: 1,
string: 200,
checkbox: true,
list: 'Two',
text: 'Hello World!'
};
var components = {
number: {
type: 'number',
label: 'A Number',
step: 2.5
},
string: {
type: 'string',
label: 'A String'
},
checkbox: {
type: 'boolean',
label: 'A Checkbox',
onChange: function(value) {
values.list = 'Two';
}
},
list: {
type: 'list',
label: 'A List',
options: [ 'One', 'Two', 'Three' ]
},
text: {
type: 'text',
label: 'A Text'
},
button: {
type: 'button',
label: 'A Button',
value: 'Click Me!',
onClick: function() {
values.text = 'You clicked!';
}
},
slider: {
type: 'slider',
label: 'A Slider',
value: 10,
range: [0, 50],
step: 10
}
};
var palette = new Palette('Values', components, values);
palette.onChange = function(component, name, value) {
console.log(component, name + ' = ' + value);
}
values.number = 10;
values.string = 'Woop woop';
values.list = 'Three';
console.log(JSON.stringify(values));
</script>
</head>
<body>
<canvas id="canvas" width="640" height="480"></canvas>
</body>
</html>

View file

@ -123,6 +123,9 @@ var paper = new function() {
/*#*/ include('ui/Key.js');
/*#*/ include('ui/MouseEvent.js');
/*#*/ include('ui/Palette.js');
/*#*/ include('ui/Component.js');
/*#*/ include('tool/ToolEvent.js');
/*#*/ include('tool/Tool.js');
/*#*/ } // options.browser

165
src/ui/Component.js Normal file
View file

@ -0,0 +1,165 @@
/*
* Paper.js
*
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
* based on Scriptographer.org and designed to be largely API compatible.
* http://paperjs.org/
* http://scriptographer.org/
*
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
* http://lehni.org/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
var Component = this.Component = Base.extend(Callback, /** @lends Component# */{
_events: [ 'onChange', 'onClick' ],
_types: {
'boolean': {
type: 'checkbox',
value: 'checked'
},
string: {
type: 'text'
},
number: {
type: 'number'
},
button: {
type: 'button'
},
text: {
tag: 'div',
value: 'text'
},
slider: {
type: 'range'
},
list: {
tag: 'select',
options: function() {
DomElement.removeChildren(this.element);
DomElement.create(Base.each(this._options, function(option) {
this.push('option', { value: option, text: option });
}, []), this.element);
},
value: function(value) {
DomElement.set(
DomElement.find('option[value="' + value + '"]', this.element),
'selected', true);
}
}
},
initialize: function(obj) {
this._type = obj.type
|| ('options' in obj
? 'list'
: 'onClick' in obj
? 'button'
: typeof value);
this._info = this._types[this._type] || { type: this._type };
var that = this,
fireChange = false;
this.element = DomElement.create(this._info.tag || 'input', {
type: this._info.type,
events: {
change: function() {
var key = that._info.value;
if (typeof key === 'function')
key = null;
var value = DomElement.get(that.element, key || 'value');
if (fireChange) {
that.palette.fire('change', that, that.name, value);
that.fire('change', value);
}
},
click: function() {
that.fire('click');
}
}
});
Base.each(obj, function(value, key) {
this[key] = value;
}, this);
this._defaultValue = this._value;
// Only fire change events after we have initalized
fireChange = true;
},
getType: function() {
return this._type;
},
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) {
var key = this._info.value;
if (typeof key === 'function')
key.call(this, value);
else
DomElement.set(this.element, key || 'value', value);
this._value = value;
},
getRange: function() {
return [toFloat(DomElement.get(this.element, 'min')),
toFloat(DomElement.get(this.element, 'max'))];
},
setRange: function(arg0, arg1) {
if (!Array.isArray(arg0))
arg0 = [arg0, arg1];
DomElement.set(this.element, { min: arg0[0], max: arg0[1] });
},
getMin: function() {
return getRange()[0];
},
setMin: function(min) {
this.setRange(min, getMax());
},
getMax: function() {
return getRange()[1];
},
setMax: function(max) {
this.setRange(getMin(), max);
},
getStep: function() {
return toFloat(DomElement.get(this.element, 'step'));
},
setStep: function(step) {
DomElement.set(this.element, 'step', step);
},
reset: function() {
this.setValue(this._defaultValue);
}
});

70
src/ui/Palette.js Normal file
View file

@ -0,0 +1,70 @@
/*
* Paper.js
*
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
* based on Scriptographer.org and designed to be largely API compatible.
* http://paperjs.org/
* http://scriptographer.org/
*
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
* http://lehni.org/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
var Palette = this.Palette = Base.extend(Callback, /** @lends Palette# */{
_events: [ 'onChange' ],
initialize: function(title, components, values) {
var parent = DomElement.find('.paperjs-palettes')
|| DomElement.find('body').appendChild(
DomElement.create('div', { 'class': 'paperjs-palettes' }));
var table = parent.appendChild(
DomElement.create('table', { 'class': 'paperjs-palette' }));
this._title = title;
if (!values)
values = {};
this._components = Base.each(components, function(component, name) {
if (!(component instanceof Component)) {
if (component.value == null)
component.value = values[name];
component.name = name;
component = components[name] = new Component(component);
}
component.palette = this;
// Make sure each component has an entry in values, so observers get
// installed further down.
if (values[name] === undefined)
values[name] = null;
var row = table.appendChild(
DomElement.create('tr', [
'td', { text: (component.label || name) + ':' },
'td', component.element
])
);
}, this);
this._values = Base.each(values, function(value, name) {
// Replace each entry with an getter / setters so we can observe
// change.
Base.define(values, name, {
enumerable: true,
configurable: true,
writable: true,
get: function() {
return value;
},
set: function(val) {
value = val;
components[name].setValue(val);
}
});
});
},
reset: function() {
for (var i in this._components)
this._components[i].reset();
}
});