More work to make new events mechanisms work for Tool too.

This commit is contained in:
Jürg Lehni 2011-11-11 19:49:31 +01:00
parent 5fd7753c60
commit e238dea3ac
4 changed files with 61 additions and 56 deletions

View file

@ -16,14 +16,15 @@
var Callback = { var Callback = {
attach: function(type, func) { attach: function(type, func) {
var entry = this._events[type];
// If an object literal is passed, attach all callbacks defined in it // If an object literal is passed, attach all callbacks defined in it
if (!entry) { if (typeof type !== 'string') {
return Base.each(type, function(value, key) { return Base.each(type, function(value, key) {
this.attach(key, value); this.attach(key, value);
}, this); }, this);
} }
// Otherwise, attach the event now var entry = this._eventTypes[type];
if (!entry)
return this;
var handlers = this._handlers = this._handlers || {}; var handlers = this._handlers = this._handlers || {};
handlers = handlers[type] = handlers[type] || []; handlers = handlers[type] = handlers[type] || [];
if (handlers.indexOf(func) == -1) { // Not added yet, add it now if (handlers.indexOf(func) == -1) { // Not added yet, add it now
@ -37,20 +38,23 @@ var Callback = {
}, },
detach: function(type, func) { detach: function(type, func) {
var entry = this._events[type];
// If an object literal is passed, detach all callbacks defined in it // If an object literal is passed, detach all callbacks defined in it
if (!entry) { if (typeof type !== 'string') {
return Base.each(type, function(value, key) { return Base.each(type, function(value, key) {
this.detach(key, value); this.detach(key, value);
}, this); }, this);
} }
// Otherwise, detach the event now var entry = this._eventTypes[type],
var handlers = this._handlers && this._handlers[type], handlers = this._handlers && this._handlers[type],
index = handlers && handlers.indexOf(func) || -1; index;
if (index != -1) { if (entry && handlers) {
if (!func) { // Remove all
handlers = [];
} else if ((index = handlers.indexOf(func)) != -1) {
handlers.splice(index, 1); handlers.splice(index, 1);
// See if this is the last handler that we're detaching, and }
// call uninstall if defined. // See if this is the last handler that we're detaching, and call
// uninstall if defined.
if (!handlers.length) { if (!handlers.length) {
delete this._handlers[type]; delete this._handlers[type];
if (entry.uninstall) if (entry.uninstall)
@ -60,14 +64,6 @@ var Callback = {
return this; return this;
}, },
detachAll: function(type) {
return Base.each(this._handlers && this._handlers[type] || [],
function(func) {
this.detach(type, func);
},
this);
},
fire: function(type, param) { fire: function(type, param) {
// Returns true if fired, false otherwise // Returns true if fired, false otherwise
var handlers = this._handlers && this._handlers[type]; var handlers = this._handlers && this._handlers[type];
@ -79,26 +75,44 @@ var Callback = {
return true; return true;
}, },
responds: function(type) {
return this._handlers && this._handlers[type];
},
statics: { statics: {
inject: function(/* src, ... */) { inject: function(/* src, ... */) {
for (var i = 0, l = arguments.length; i < l; i++) { for (var i = 0, l = arguments.length; i < l; i++) {
var src = arguments[i], var src = arguments[i],
events = src._events; events = src._events;
if (events) { if (events) {
Base.each(events, function(entry, type) { // events can either be an object literal or an array of
var part = Base.capitalize(type); // strings describing the on*-names.
src['getOn' + part] = function() { // We need to map lowercased event types to the event
return this['_on' + part]; // entries represented by these on*-names in _events.
var types = {};
Base.each(events, function(entry, key) {
var isString = typeof entry === 'string',
name = isString ? entry : key,
part = Base.capitalize(name),
type = name.substring(2).toLowerCase();
// Map the event type name to the event entry.
types[type] = isString ? {} : entry;
// Create getters and setters for the property
// with the on*-name name:
name = '_' + name;
src['get' + part] = function() {
return this[name];
}; };
src['setOn' + part] = function(func) { src['set' + part] = function(func) {
if (func) { if (func) {
this.attach(type, func); this.attach(type, func);
} else { } else {
this.detach(type, this['_on' + part]); this.detach(type, this[name]);
} }
this['_on' + part] = func; this[name] = func;
}; };
}); });
src._eventTypes = types;
} }
this.base(src); this.base(src);
} }

View file

@ -169,10 +169,7 @@ var PaperScript = this.PaperScript = new function() {
(function() { (function() {
var onEditOptions, onSelect, onDeselect, onReselect, onMouseDown, var onEditOptions, onSelect, onDeselect, onReselect, onMouseDown,
onMouseUp, onMouseDrag, onMouseMove, onKeyDown, onKeyUp, onMouseUp, onMouseDrag, onMouseMove, onKeyDown, onKeyUp,
onFrame, onResize, onFrame, onResize;
handlers = [ 'onEditOptions', 'onSelect', 'onDeselect',
'onReselect', 'onMouseDown', 'onMouseUp', 'onMouseDrag',
'onMouseMove', 'onKeyDown', 'onKeyUp'];
res = eval(compile(code)); res = eval(compile(code));
if (tool) { if (tool) {
// We could do this instead to avoid eval(), but it's longer // We could do this instead to avoid eval(), but it's longer
@ -186,7 +183,7 @@ var PaperScript = this.PaperScript = new function() {
// tool.onMouseMove = onMouseMove; // tool.onMouseMove = onMouseMove;
// tool.onKeyDown = onKeyDown; // tool.onKeyDown = onKeyDown;
// tool.onKeyUp = onKeyUp; // tool.onKeyUp = onKeyUp;
Base.each(handlers, function(key) { Base.each(tool._events, function(key) {
tool[key] = eval(key); tool[key] = eval(key);
}); });
} }

View file

@ -46,9 +46,12 @@
* path.add(event.point); * path.add(event.point);
* } * }
*/ */
var Tool = this.Tool = PaperScopeItem.extend(/** @lends Tool# */{ var Tool = this.Tool = PaperScopeItem.extend(Callback, /** @lends Tool# */{
_list: 'tools', _list: 'tools',
_reference: 'tool', _reference: 'tool',
_events: [ 'onEditOptions', 'onSelect', 'onDeselect', 'onReselect',
'onMouseDown', 'onMouseUp', 'onMouseDrag', 'onMouseMove',
'onKeyDown', 'onKeyUp' ],
// DOCS: rewrite Tool constructor explanation // DOCS: rewrite Tool constructor explanation
initialize: function() { initialize: function() {
@ -329,10 +332,8 @@ var Tool = this.Tool = PaperScopeItem.extend(/** @lends Tool# */{
switch (type) { switch (type) {
case 'mousedown': case 'mousedown':
this.updateEvent(type, pt, null, null, true, false, false); this.updateEvent(type, pt, null, null, true, false, false);
if (this.onMouseDown) { if (this.responds(type))
this.onMouseDown(new ToolEvent(this, type, event)); called = this.fire(type, new ToolEvent(this, type, event));
called = true;
}
break; break;
case 'mousedrag': case 'mousedrag':
// In order for idleInterval drag events to work, we need to not // In order for idleInterval drag events to work, we need to not
@ -347,10 +348,8 @@ var Tool = this.Tool = PaperScopeItem.extend(/** @lends Tool# */{
matchMaxDistance = false; matchMaxDistance = false;
while (this.updateEvent(type, pt, this.minDistance, while (this.updateEvent(type, pt, this.minDistance,
this.maxDistance, false, needsChange, matchMaxDistance)) { this.maxDistance, false, needsChange, matchMaxDistance)) {
if (this.onMouseDrag) { if (this.responds(type))
this.onMouseDrag(new ToolEvent(this, type, event)); called = this.fire(type, new ToolEvent(this, type, event));
called = true;
}
needsChange = true; needsChange = true;
matchMaxDistance = true; matchMaxDistance = true;
} }
@ -361,17 +360,14 @@ var Tool = this.Tool = PaperScopeItem.extend(/** @lends Tool# */{
if ((this._point.x != pt.x || this._point.y != pt.y) if ((this._point.x != pt.x || this._point.y != pt.y)
&& this.updateEvent('mousedrag', pt, this.minDistance, && this.updateEvent('mousedrag', pt, this.minDistance,
this.maxDistance, false, false, false)) { this.maxDistance, false, false, false)) {
if (this.onMouseDrag) { if (this.responds('mousedrag'))
this.onMouseDrag(new ToolEvent(this, type, event)); called = this.fire('mousedrag',
called = true; new ToolEvent(this, type, event));
}
} }
this.updateEvent(type, pt, null, this.maxDistance, false, this.updateEvent(type, pt, null, this.maxDistance, false,
false, false); false, false);
if (this.onMouseUp) { if (this.responds(type))
this.onMouseUp(new ToolEvent(this, type, event)); called = this.fire(type, new ToolEvent(this, type, event));
called = true;
}
// Start with new values for 'mousemove' // Start with new values for 'mousemove'
this.updateEvent(type, pt, null, null, true, false, false); this.updateEvent(type, pt, null, null, true, false, false);
this._firstMove = true; this._firstMove = true;
@ -379,10 +375,8 @@ var Tool = this.Tool = PaperScopeItem.extend(/** @lends Tool# */{
case 'mousemove': case 'mousemove':
while (this.updateEvent(type, pt, this.minDistance, while (this.updateEvent(type, pt, this.minDistance,
this.maxDistance, this._firstMove, true, false)) { this.maxDistance, this._firstMove, true, false)) {
if (this.onMouseMove) { if (this.responds(type))
this.onMouseMove(new ToolEvent(this, type, event)); called = this.fire(type, new ToolEvent(this, type, event));
called = true;
}
this._firstMove = false; this._firstMove = false;
} }
break; break;

View file

@ -27,7 +27,7 @@ var View = this.View = PaperScopeItem.extend(Callback, /** @lends View# */{
_list: 'views', _list: 'views',
_reference: 'view', _reference: 'view',
_events: { _events: {
frame: { onFrame: {
install: function() { install: function() {
/*#*/ if (options.browser) { /*#*/ if (options.browser) {
var that = this, var that = this,
@ -75,7 +75,7 @@ var View = this.View = PaperScopeItem.extend(Callback, /** @lends View# */{
} }
}, },
resize: {} onResize: {}
}, },
/** /**
@ -210,7 +210,7 @@ var View = this.View = PaperScopeItem.extend(Callback, /** @lends View# */{
this._canvas = this._domEvents = null; this._canvas = this._domEvents = null;
// Removing all onFrame handlers makes the _onFrameCallback handler stop // Removing all onFrame handlers makes the _onFrameCallback handler stop
// automatically through its uninstall method. // automatically through its uninstall method.
this.detachAll('frame'); this.detach('frame');
return true; return true;
}, },