mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-28 17:02:24 -05:00
Add initial support for mouse events.
This commit is contained in:
parent
cb5a8aa2fc
commit
7e285abe7a
3 changed files with 455 additions and 0 deletions
48
src/Tool.js
Normal file
48
src/Tool.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
Tool = ToolHandler.extend({
|
||||
initialize: function(handlers, doc) {
|
||||
this.base(handlers);
|
||||
this.setEventInterval(-1);
|
||||
},
|
||||
|
||||
setDocument: function(doc) {
|
||||
this.document = doc;
|
||||
var that = this;
|
||||
$(doc.canvas).addEvents({
|
||||
mousedown: function(e) {
|
||||
that.onHandleEvent('MOUSE_DOWN', new Point(e.offset), null, null);
|
||||
that.document.redraw();
|
||||
},
|
||||
drag: function(e) {
|
||||
that.onHandleEvent('MOUSE_DRAG', new Point(e.offset), null, null);
|
||||
that.document.redraw();
|
||||
},
|
||||
mouseup: function(e) {
|
||||
that.onHandleEvent('MOUSE_UP', new Point(e.offset), null, null);
|
||||
that.document.redraw();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the fixed time delay between each call to the {@link #onMouseDrag}
|
||||
* event. Setting this to an interval means the {@link #onMouseDrag} event
|
||||
* is called repeatedly after the initial {@link #onMouseDown} until the
|
||||
* user releases the mouse.
|
||||
*
|
||||
* Sample code:
|
||||
* <code>
|
||||
* // Fire the onMouseDrag event once a second,
|
||||
* // while the mouse button is down
|
||||
* tool.eventInterval = 1000;
|
||||
* </code>
|
||||
*
|
||||
* @return the interval time in milliseconds
|
||||
*/
|
||||
getEventInterval: function() {
|
||||
return this.eventInterval;
|
||||
},
|
||||
|
||||
setEventInterval: function(interval) {
|
||||
this.eventInterval = interval;
|
||||
}
|
||||
});
|
233
src/ToolEvent.js
Normal file
233
src/ToolEvent.js
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Scriptographer
|
||||
*
|
||||
* This file is part of Scriptographer, a Plugin for Adobe Illustrator.
|
||||
*
|
||||
* Copyright (c) 2002-2010 Juerg Lehni, http://www.scratchdisk.com.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please visit http://scriptographer.org/ for updates and contact.
|
||||
*
|
||||
* -- GPL LICENSE NOTICE --
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* -- GPL LICENSE NOTICE --
|
||||
*
|
||||
* File created on 21.12.2004.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The ToolEvent object is received by the {@link Tool}'s mouse event handlers
|
||||
* {@link Tool#getOnMouseDown()}, {@link Tool#getOnMouseDrag()},
|
||||
* {@link Tool#getOnMouseMove()} and {@link Tool#getOnMouseUp()}. The ToolEvent
|
||||
* object is the only parameter passed to these functions and contains
|
||||
* information about the mouse event.
|
||||
*
|
||||
* Sample code:
|
||||
* <code>
|
||||
* function onMouseUp(event) {
|
||||
* // the position of the mouse when it is released
|
||||
* print(event.point);
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @author lehni
|
||||
*/
|
||||
ToolEvent = Base.extend({
|
||||
initialize: function(tool, type, modifiers) {
|
||||
// super(modifiers);
|
||||
this.tool = tool;
|
||||
this.type = type;
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return '{ type: ' + type
|
||||
+ ', point: ' + this.getPoint()
|
||||
+ ', count: ' + this.getCount()
|
||||
+ ', modifiers: ' + this.getModifiers()
|
||||
+ ' }';
|
||||
},
|
||||
|
||||
/**
|
||||
* Convenience method to allow local overrides of point values.
|
||||
* See application below.
|
||||
*/
|
||||
choosePoint: function(point, toolPoint) {
|
||||
if (point)
|
||||
return point;
|
||||
if (toolPoint)
|
||||
return new Point(toolPoint);
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* The position of the mouse in document coordinates when the event was
|
||||
* fired.
|
||||
*
|
||||
* Sample code:
|
||||
* <code>
|
||||
* function onMouseDrag(event) {
|
||||
* // the position of the mouse when it is dragged
|
||||
* print(event.point);
|
||||
* }
|
||||
*
|
||||
* function onMouseUp(event) {
|
||||
* // the position of the mouse when it is released
|
||||
* print(event.point);
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
getPoint: function() {
|
||||
return this.choosePoint(this.point, this.tool.point);
|
||||
},
|
||||
|
||||
setPoint: function(point) {
|
||||
this.point = point;
|
||||
},
|
||||
|
||||
/**
|
||||
* The position of the mouse in document coordinates when the previous
|
||||
* event was fired.
|
||||
*/
|
||||
getLastPoint: function() {
|
||||
return this.choosePoint(this.lastPoint, this.tool.lastPoint);
|
||||
},
|
||||
|
||||
setLastPoint: function(lastPoint) {
|
||||
this.lastPoint = lastPoint;
|
||||
},
|
||||
|
||||
/**
|
||||
* The position of the mouse in document coordinates when the mouse button
|
||||
* was last clicked.
|
||||
*/
|
||||
getDownPoint: function() {
|
||||
return this.choosePoint(this.downPoint, this.tool.downPoint);
|
||||
},
|
||||
|
||||
setDownPoint: function(downPoint) {
|
||||
this.downPoint = downPoint;
|
||||
},
|
||||
|
||||
/**
|
||||
* The point in the middle between {@link #getLastPoint()} and
|
||||
* {@link #getPoint()}. This is a useful position to use when creating
|
||||
* artwork based on the moving direction of the mouse, as returned by
|
||||
* {@link #getDelta()}.
|
||||
*/
|
||||
getMiddlePoint: function() {
|
||||
// For explanations, see getDelta()
|
||||
if (this.middlePoint == null && this.tool.lastPoint != null) {
|
||||
// (point + lastPoint) / 2
|
||||
return this.tool.point.add(this.tool.lastPoint).divide(2);
|
||||
}
|
||||
return this.middlePoint;
|
||||
},
|
||||
|
||||
setMiddlePoint: function(middlePoint) {
|
||||
this.middlePoint = middlePoint;
|
||||
},
|
||||
|
||||
/**
|
||||
* The difference between the current position and the last position of the
|
||||
* mouse when the event was fired. In case of the mouse-up event, the
|
||||
* difference to the mouse-down position is returned.
|
||||
*/
|
||||
getDelta: function() {
|
||||
// Do not put the calculated delta into delta, since this only reserved
|
||||
// for overriding event.delta.
|
||||
// Instead, keep calculating the delta each time, so the result can be
|
||||
// directly modified by the script without changing the internal values.
|
||||
// We could cache this and use clone, but this is almost as fast...
|
||||
if (this.delta == null && this.tool.lastPoint != null) {
|
||||
return this.tool.point.subtract(this.tool.lastPoint);
|
||||
}
|
||||
return this.delta;
|
||||
},
|
||||
|
||||
setDelta: function(delta) {
|
||||
this.delta = delta;
|
||||
},
|
||||
|
||||
/**
|
||||
* The number of times the mouse event was fired.
|
||||
*
|
||||
* Sample code:
|
||||
* <code>
|
||||
* function onMouseDrag(event) {
|
||||
* // the amount of times the onMouseDrag event was fired
|
||||
* // since the last onMouseDown event
|
||||
* print(event.count);
|
||||
* }
|
||||
*
|
||||
* function onMouseUp(event) {
|
||||
* // the amount of times the onMouseUp event was fired
|
||||
* // since the tool was activated
|
||||
* print(event.point);
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
getCount: function() {
|
||||
switch (this.type) {
|
||||
case 'MOUSE_DOWN':
|
||||
case 'MOUSE_UP':
|
||||
// Return downCount for both mouse down and up, since
|
||||
// the count is the same.
|
||||
return this.tool.downCount;
|
||||
default:
|
||||
return this.tool.count;
|
||||
}
|
||||
},
|
||||
|
||||
setCount: function(count) {
|
||||
switch (this.type) {
|
||||
case 'MOUSE_DOWN':
|
||||
case 'MOUSE_UP':
|
||||
this.tool.downCount = count;
|
||||
break;
|
||||
default:
|
||||
this.tool.count = count;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
getType: function() {
|
||||
return this.type;
|
||||
},
|
||||
|
||||
setType: function(type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
// TODO: implement hitTest first
|
||||
// getItem: function() {
|
||||
// if (this.item == null) {
|
||||
// var result = Doc.getActiveDocument().hitTest(this.getPoint());
|
||||
// if (result != null) {
|
||||
// this.item = result.getItem();
|
||||
// // Find group parent
|
||||
// var parent = item.getParent();
|
||||
// while (parent instanceof Group || parent instanceof CompoundPath) {
|
||||
// item = parent;
|
||||
// parent = parent.getParent();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return item;
|
||||
// }
|
||||
//
|
||||
// setItem: function(Item item) {
|
||||
// this.item = item;
|
||||
// }
|
||||
});
|
174
src/ToolHandler.js
Normal file
174
src/ToolHandler.js
Normal file
|
@ -0,0 +1,174 @@
|
|||
ToolHandler = Base.extend({
|
||||
/**
|
||||
* Initializes the tool's settings, so a new tool can be assigned to it
|
||||
*/
|
||||
initialize: function(handlers) {
|
||||
this.firstMove = true;
|
||||
this.count = 0;
|
||||
this.downCount = 0;
|
||||
for(var i in handlers) {
|
||||
this[i] = handlers[i];
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* The minimum distance the mouse has to drag before firing the onMouseDrag
|
||||
* event, since the last onMouseDrag event.
|
||||
*
|
||||
* Sample code:
|
||||
* <code>
|
||||
* // Fire the onMouseDrag event after the user has dragged
|
||||
* // more then 5 points from the last onMouseDrag event:
|
||||
* tool.minDistance = 5;
|
||||
* </code>
|
||||
*/
|
||||
getMinDistance: function() {
|
||||
return this.minDistance;
|
||||
},
|
||||
|
||||
setMinDistance: function(minDistance) {
|
||||
this.minDistance = minDistance;
|
||||
if (this.minDistance != null && this.maxDistance != null
|
||||
&& this.minDistance > this.maxDistance)
|
||||
this.maxDistance = this.minDistance;
|
||||
},
|
||||
|
||||
getMaxDistance: function() {
|
||||
return this.maxDistance;
|
||||
},
|
||||
|
||||
setMaxDistance: function(maxDistance) {
|
||||
this.maxDistance = maxDistance;
|
||||
if (this.minDistance != null && this.maxDistance != null
|
||||
&& this.maxDistance < this.minDistance)
|
||||
this.minDistance = maxDistance;
|
||||
},
|
||||
|
||||
getFixedDistance: function() {
|
||||
if (this.minDistance != null && this.minDistance.equals(this.maxDistance))
|
||||
return this.minDistance;
|
||||
return null;
|
||||
},
|
||||
|
||||
setFixedDistance: function(distance) {
|
||||
this.minDistance = distance;
|
||||
this.maxDistance = distance;
|
||||
},
|
||||
|
||||
updateEvent: function(type, pt, minDistance, maxDistance, start,
|
||||
needsChange, matchMaxDistance) {
|
||||
if (!start) {
|
||||
if (minDistance != null || maxDistance != null) {
|
||||
var minDist = minDistance != null ? minDistance : 0;
|
||||
var vector = pt.subtract(this.point);
|
||||
var distance = vector.getLength();
|
||||
if (distance < minDist)
|
||||
return false;
|
||||
// Produce a new point on the way to pt if pt is further away
|
||||
// than maxDistance
|
||||
var maxDist = maxDistance != null ? maxDistance : 0;
|
||||
if (maxDist != 0) {
|
||||
if (distance > maxDist)
|
||||
pt = this.point.add(vector.normalize(maxDist));
|
||||
else if (matchMaxDistance)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (needsChange && pt.equals(this.point))
|
||||
return false;
|
||||
}
|
||||
this.lastPoint = this.point;
|
||||
this.point = pt;
|
||||
switch (type) {
|
||||
case 'MOUSE_DOWN':
|
||||
this.lastPoint = this.downPoint;
|
||||
this.downPoint = this.point;
|
||||
this.downCount++;
|
||||
break;
|
||||
case 'MOUSE_UP':
|
||||
// Mouse up events return the down point for last point,
|
||||
// so delta is spanning over the whole drag.
|
||||
this.lastPoint = this.downPoint;
|
||||
break;
|
||||
}
|
||||
if (start) {
|
||||
this.count = 0;
|
||||
} else {
|
||||
this.count++;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
onHandleEvent: function(type, pt, modifiers) {
|
||||
try {
|
||||
switch (type) {
|
||||
case 'MOUSE_DOWN':
|
||||
this.updateEvent(type, pt, null, null, true, false, false);
|
||||
if(this.onMouseDown)
|
||||
this.onMouseDown(new ToolEvent(this, type, modifiers));
|
||||
break;
|
||||
case 'MOUSE_DRAG':
|
||||
// In order for idleInterval drag events to work, we need to
|
||||
// not check the first call for a change of position.
|
||||
// Subsequent calls required by min/maxDistance functionality
|
||||
// will require it, otherwise this might loop endlessly.
|
||||
this.needsChange = false;
|
||||
// If the mouse is moving faster than maxDistance, do not
|
||||
// produce events for what is left after the first event is
|
||||
// generated in case it is shorter than maxDistance, as this
|
||||
// would produce weird results. matchMaxDistance controls this.
|
||||
this.matchMaxDistance = false;
|
||||
while (this.updateEvent(type, pt, this.minDistance,
|
||||
this.maxDistance, false, this.needsChange, this.matchMaxDistance)) {
|
||||
try {
|
||||
if(this.onMouseDrag)
|
||||
this.onMouseDrag(new ToolEvent(this, type, modifiers));
|
||||
} catch (e) {
|
||||
// ScriptographerEngine.reportError(e);
|
||||
}
|
||||
this.needsChange = true;
|
||||
this.matchMaxDistance = true;
|
||||
}
|
||||
break;
|
||||
case 'MOUSE_UP':
|
||||
// If the last mouse drag happened in a different place, call
|
||||
// mouse drag first, then mouse up.
|
||||
if ((this.point.x != pt.x || this.point.y != pt.y) && this.updateEvent(
|
||||
'MOUSE_DRAG', pt, this.minDistance, this.maxDistance, false, false, false)) {
|
||||
try {
|
||||
if(this.onMouseDrag)
|
||||
this.onMouseDrag(new ToolEvent(this, type, modifiers));
|
||||
} catch (e) {
|
||||
// ScriptographerEngine.reportError(e);
|
||||
}
|
||||
}
|
||||
this.updateEvent(type, pt, null, this.maxDistance, false,
|
||||
false, false);
|
||||
try {
|
||||
this.onMouseUp(new ToolEvent(this, type, modifiers));
|
||||
} catch (e) {
|
||||
// ScriptographerEngine.reportError(e);
|
||||
}
|
||||
// Start with new values for TRACK_CURSOR
|
||||
this.updateEvent(type, pt, null, null, true, false, false);
|
||||
this.firstMove = true;
|
||||
break;
|
||||
case 'MOUSE_MOVE':
|
||||
while (this.updateEvent(type, pt, this.minDistance,
|
||||
this.maxDistance, this.firstMove, true, false)) {
|
||||
try {
|
||||
if(this.onMouseMove)
|
||||
this.onMouseMove(new ToolEvent(this, type, modifiers));
|
||||
} catch (e) {
|
||||
// ScriptographerEngine.reportError(e);
|
||||
}
|
||||
this.firstMove = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
//ScriptographerEngine.reportError(e);
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in a new issue