This commit is contained in:
Pavel fljot 2012-08-25 23:50:34 +03:00
commit 595d6ab989
26 changed files with 378 additions and 720 deletions

View file

@ -31,33 +31,43 @@ Features:
h3. Current state of the project
v0.3 introduces "new architecture". I'm planning to develop everything in develop branch and merge to master only release versions. Release versions suppose to be pretty stable. As much as I test them on the examples project.
Current plan is to fix possible bugs in v0.3.#, and I really want to introduce Stage3D support in v0.4. So watch both branches.
And I hope people to become giving some real feedback at least.
h3. Getting Started h3. Getting Started
Like so: All gestures dispatch (if you listen) GestureEvent with the next types:
GestureEvent.GESTURE_STATE_CHANGE
GestureEvent.GESTURE_IDLE
GestureEvent.GESTURE_POSSIBLE
GestureEvent.GESTURE_FAILED
Discrete gestures also dispatch:
GestureEvent.GESTURE_RECOGNIZED
Continuous gestures also dispatch:
GestureEvent.GESTURE_BEGAN
GestureEvent.GESTURE_CHANGED
GestureEvent.GESTURE_ENDED
If you use a good IDE (such as Intellij IDEA, FDT, FlashDevelop, Flash Builder) you should see these events in autocompletion.
Quick start:
<pre><code>var doubleTap:TapGesture = new TapGesture(myButton); <pre><code>var doubleTap:TapGesture = new TapGesture(myButton);
doubleTap.numTapsRequired = 2; doubleTap.numTapsRequired = 2;
doubleTap.addEventListener(TapGestureEvent.GESTURE_TAP, onDoubleTap); doubleTap.addEventListener(GestureEvent.GESTURE_RECOGNIZED, onDoubleTap);
... ...
private function onDoubleTap(event:TapGestureEvent):void private function onDoubleTap(event:GestureEvent):void
{ {
// handle double tap! // handle double tap!
} }
</code></pre> </code></pre>
or or
<pre><code>var freeTransform:TransformGesture = new TransformGesture(myImage); <pre><code>var freeTransform:TransformGesture = new TransformGesture(myImage);
freeTransform.addEventListener(TransformGestureEvent.GESTURE_TRANSFORM, onFreeTransform); freeTransform.addEventListener(GestureEvent.GESTURE_BEGAN, onFreeTransform);
freeTransform.addEventListener(GestureEvent.GESTURE_CHANGED, onFreeTransform);
... ...
private function onFreeTransform(event:TransformGestureEvent):void private function onFreeTransform(event:GestureEvent):void
{ {
// move, rotate, scale — all at once for better performance! // move, rotate, scale — all at once for better performance!
trace(freeTransform.offsetX, freeTransform.offsetY, freeTransform.rotation, freeTransform.scale);
} }
</code></pre> </code></pre>

View file

@ -1,41 +1,36 @@
package org.gestouch.core package org.gestouch.core
{ {
import flash.utils.Dictionary;
import flash.errors.IllegalOperationError; import flash.errors.IllegalOperationError;
/** /**
* @author Pavel fljot * @author Pavel fljot
*/ */
public class GestureState final public class GestureState
{ {
public static const IDLE:GestureState = new GestureState(1 << 0, "IDLE"); public static const IDLE:GestureState = new GestureState("IDLE");
public static const POSSIBLE:GestureState = new GestureState(1 << 1, "POSSIBLE"); public static const POSSIBLE:GestureState = new GestureState("POSSIBLE");
public static const RECOGNIZED:GestureState = new GestureState(1 << 2, "RECOGNIZED"); public static const RECOGNIZED:GestureState = new GestureState("RECOGNIZED", true);
public static const BEGAN:GestureState = new GestureState(1 << 3, "BEGAN"); public static const BEGAN:GestureState = new GestureState("BEGAN");
public static const CHANGED:GestureState = new GestureState(1 << 4, "CHANGED"); public static const CHANGED:GestureState = new GestureState("CHANGED");
public static const ENDED:GestureState = new GestureState(1 << 5, "ENDED"); public static const ENDED:GestureState = new GestureState("ENDED", true);
public static const CANCELLED:GestureState = new GestureState(1 << 6, "CANCELLED"); public static const CANCELLED:GestureState = new GestureState("CANCELLED", true);
public static const FAILED:GestureState = new GestureState(1 << 7, "FAILED"); public static const FAILED:GestureState = new GestureState("FAILED", true);
private static const endStatesBitMask:uint =
GestureState.CANCELLED.toUint() |
GestureState.RECOGNIZED.toUint() |
GestureState.ENDED.toUint() |
GestureState.FAILED.toUint();
private static var allStatesInitialized:Boolean; private static var allStatesInitialized:Boolean;
private var value:uint;
private var name:String; private var name:String;
private var validTransitionsBitMask:uint; private var eventType:String;
private var validTransitionStateMap:Dictionary = new Dictionary();
{ {
_initClass(); _initClass();
} }
public function GestureState(value:uint, name:String) public function GestureState(name:String, isEndState:Boolean = false)
{ {
if (allStatesInitialized) if (allStatesInitialized)
{ {
@ -43,8 +38,9 @@ package org.gestouch.core
"Use predefined constats like GestureState.RECOGNIZED"); "Use predefined constats like GestureState.RECOGNIZED");
} }
this.value = value; this.name = "GestureState." + name;
this.name = name; this.eventType = "gesture" + name.charAt(0).toUpperCase() + name.substr(1).toLowerCase();
this._isEndState = isEndState;
} }
@ -65,36 +61,35 @@ package org.gestouch.core
public function toString():String public function toString():String
{ {
return "GestureState." + name; return name;
}
public function toUint():uint
{
return value;
} }
private function setValidNextStates(...states):void private function setValidNextStates(...states):void
{ {
var mask:uint;
for each (var state:GestureState in states) for each (var state:GestureState in states)
{ {
mask = mask | state.value; validTransitionStateMap[state] = true;
} }
validTransitionsBitMask = mask; }
gestouch_internal function toEventType():String
{
return eventType;
} }
gestouch_internal function canTransitionTo(state:GestureState):Boolean gestouch_internal function canTransitionTo(state:GestureState):Boolean
{ {
return (validTransitionsBitMask & state.value) > 0; return (state in validTransitionStateMap);
} }
private var _isEndState:Boolean = false;
gestouch_internal function get isEndState():Boolean gestouch_internal function get isEndState():Boolean
{ {
return (endStatesBitMask & value) > 0; return _isEndState;
} }
} }
} }

View file

@ -1,6 +1,5 @@
package org.gestouch.core package org.gestouch.core
{ {
import flash.geom.Point;
/** /**
* @author Pavel fljot * @author Pavel fljot
*/ */
@ -8,8 +7,6 @@ package org.gestouch.core
{ {
function get target():Object; function get target():Object;
function globalToLocal(point:Point):Point;
function contains(object:Object):Boolean; function contains(object:Object):Boolean;
} }
} }

View file

@ -10,38 +10,40 @@ package org.gestouch.events
*/ */
public class GestureEvent extends Event public class GestureEvent extends Event
{ {
public var gestureState:GestureState; public static const GESTURE_IDLE:String = "gestureIdle";
public var stageX:Number; public static const GESTURE_POSSIBLE:String = "gesturePossible";
public var stageY:Number; public static const GESTURE_RECOGNIZED:String = "gestureRecognized";
public var localX:Number; public static const GESTURE_BEGAN:String = "gestureBegan";
public var localY:Number; public static const GESTURE_CHANGED:String = "gestureChanged";
public static const GESTURE_ENDED:String = "gestureEnded";
public static const GESTURE_CANCELLED:String = "gestureCancelled";
public static const GESTURE_FAILED:String = "gestureFailed";
public static const GESTURE_STATE_CHANGE:String = "gestureStateChange";
public function GestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, public var newState:GestureState;
gestureState:GestureState = null, public var oldState:GestureState;
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0)
public function GestureEvent(type:String, newState:GestureState, oldState:GestureState)
{ {
super(type, bubbles, cancelable); super(type, false, false);
this.gestureState = gestureState; this.newState = newState;
this.stageX = stageX; this.oldState = oldState;
this.stageY = stageY;
this.localX = localX;
this.localY = localY;
} }
override public function clone():Event override public function clone():Event
{ {
return new GestureEvent(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY); return new GestureEvent(type, newState, oldState);
} }
override public function toString():String override public function toString():String
{ {
return formatToString("org.gestouch.events.GestureEvent", "bubbles", "cancelable", return formatToString("GestureEvent", "type", "oldState", "newState");
"gestureState", "stageX", "stageY", "localX", "localY");
} }
} }
} }

View file

@ -1,39 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class GestureStateEvent extends Event
{
public static const STATE_CHANGE:String = "stateChange";
public var newState:GestureState;
public var oldState:GestureState;
public function GestureStateEvent(type:String, newState:GestureState, oldState:GestureState)
{
super(type, false, false);
this.newState = newState;
this.oldState = oldState;
}
override public function clone():Event
{
return new GestureStateEvent(type, newState, oldState);
}
override public function toString():String
{
return formatToString("GestureStateEvent", "type", "oldState", "newState");
}
}
}

View file

@ -1,36 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class LongPressGestureEvent extends GestureEvent
{
public static const GESTURE_LONG_PRESS:String = "gestureLongPress";
public function LongPressGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY);
}
override public function clone():Event
{
return new LongPressGestureEvent(type, bubbles, cancelable, gestureState, localX, localY);
}
override public function toString():String
{
return super.toString().replace("GestureEvent", "LongPressGestureEvent");
}
}
}

View file

@ -1,37 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class PanGestureEvent extends TransformGestureEvent
{
public static const GESTURE_PAN:String = "gesturePan";
public function PanGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
offsetX:Number = 0, offsetY:Number = 0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, 1, 1, 0, offsetX, offsetY);
}
override public function clone():Event
{
return new PanGestureEvent(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, offsetX, offsetY);
}
override public function toString():String
{
return super.toString().replace("TransformGestureEvent", "PanGestureEvent");
}
}
}

View file

@ -1,37 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class RotateGestureEvent extends TransformGestureEvent
{
public static const GESTURE_ROTATE:String = "gestureRotate";
public function RotateGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
rotation:Number = 0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, 1, 1, rotation);
}
override public function clone():Event
{
return new RotateGestureEvent(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, rotation);
}
override public function toString():String
{
return super.toString().replace("TransformGestureEvent", "RotateGestureEvent");
}
}
}

View file

@ -1,37 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class SwipeGestureEvent extends TransformGestureEvent
{
public static const GESTURE_SWIPE:String = "gestureSwipe";
public function SwipeGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
offsetX:Number = 0, offsetY:Number = 0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, 1, 1, 0, offsetX, offsetY);
}
override public function clone():Event
{
return new SwipeGestureEvent(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, offsetX, offsetY);
}
override public function toString():String
{
return super.toString().replace("TransformGestureEvent", "SwipeGestureEvent");
}
}
}

View file

@ -1,36 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class TapGestureEvent extends GestureEvent
{
public static const GESTURE_TAP:String = "gestureTap";
public function TapGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY);
}
override public function clone():Event
{
return new TapGestureEvent(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY);
}
override public function toString():String
{
return super.toString().replace("GestureEvent", "TapGestureEvent");
}
}
}

View file

@ -1,53 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class TransformGestureEvent extends GestureEvent
{
public static const GESTURE_TRANSFORM:String = "gestureTransform";
public var scaleX:Number;
public var scaleY:Number;
public var rotation:Number;
public var offsetX:Number;
public var offsetY:Number;
public function TransformGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
scaleX:Number = 1.0, scaleY:Number = 1.0,
rotation:Number = 0,
offsetX:Number = 0, offsetY:Number = 0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY);
this.scaleX = scaleX;
this.scaleY = scaleY;
this.rotation = rotation;
this.offsetX = offsetX;
this.offsetY = offsetY;
}
override public function clone():Event
{
return new TransformGestureEvent(type, bubbles, cancelable, gestureState,
stageX, stageY, localX, localY, scaleX, scaleY, rotation, offsetX, offsetY);
}
override public function toString():String
{
return formatToString("org.gestouch.events.TransformGestureEvent", "bubbles", "cancelable",
"gestureState", "stageX", "stageY", "localX", "localY", "scaleX", "scaleY", "offsetX", "offsetY", "rotation");
}
}
}

View file

@ -1,37 +0,0 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
/**
* @author Pavel fljot
*/
public class ZoomGestureEvent extends TransformGestureEvent
{
public static const GESTURE_ZOOM:String = "gestureZoom";
public function ZoomGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
scaleX:Number = 1.0, scaleY:Number = 1.0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, scaleX, scaleY);
}
override public function clone():Event
{
return new ZoomGestureEvent(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY, scaleX, scaleY);
}
override public function toString():String
{
return super.toString().replace("TransformGestureEvent", "ZoomGestureEvent");
}
}
}

View file

@ -36,12 +36,6 @@ package org.gestouch.extensions.native
} }
public function globalToLocal(point:Point):Point
{
return (target as DisplayObject).globalToLocal(point);
}
public function contains(object:Object):Boolean public function contains(object:Object):Boolean
{ {
const targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer; const targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer;

View file

@ -1,12 +1,10 @@
package org.gestouch.extensions.starling package org.gestouch.extensions.starling
{ {
import starling.core.Starling;
import starling.display.DisplayObject; import starling.display.DisplayObject;
import starling.display.DisplayObjectContainer; import starling.display.DisplayObjectContainer;
import org.gestouch.core.IDisplayListAdapter; import org.gestouch.core.IDisplayListAdapter;
import flash.geom.Point;
import flash.utils.Dictionary; import flash.utils.Dictionary;
@ -38,13 +36,6 @@ package org.gestouch.extensions.starling
} }
public function globalToLocal(point:Point):Point
{
point = StarlingUtils.adjustGlobalPoint(Starling.current, point);
return (target as DisplayObject).globalToLocal(point);
}
public function contains(object:Object):Boolean public function contains(object:Object):Boolean
{ {
const targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer; const targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer;

View file

@ -0,0 +1,44 @@
package org.gestouch.gestures
{
import org.gestouch.gestures.Gesture;
/**
* Dispatched when the state of the gesture changes to GestureState.BEGAN.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gestureBegan", type="org.gestouch.events.GestureEvent")]
/**
* Dispatched when the state of the gesture changes to GestureState.CHANGED.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gestureChanged", type="org.gestouch.events.GestureEvent")]
/**
* Dispatched when the state of the gesture changes to GestureState.ENDED.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gestureEnded", type="org.gestouch.events.GestureEvent")]
/**
* Dispatched when the state of the gesture changes to GestureState.CANCELLED.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gestureCancelled", type="org.gestouch.events.GestureEvent")]
/**
* @author Pavel fljot
*/
public class AbstractContinuousGesture extends Gesture
{
public function AbstractContinuousGesture(target:Object = null)
{
super(target);
}
}
}

View file

@ -0,0 +1,23 @@
package org.gestouch.gestures
{
import org.gestouch.gestures.Gesture;
/**
* Dispatched when the state of the gesture changes to GestureState.RECOGNIZED.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gestureRecognized", type="org.gestouch.events.GestureEvent")]
/**
* @author Pavel fljot
*/
public class AbstractDiscreteGesture extends Gesture
{
public function AbstractDiscreteGesture(target:Object = null)
{
super(target);
}
}
}

View file

@ -7,7 +7,7 @@ package org.gestouch.gestures
import org.gestouch.core.IGestureTargetAdapter; import org.gestouch.core.IGestureTargetAdapter;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.core.gestouch_internal; import org.gestouch.core.gestouch_internal;
import org.gestouch.events.GestureStateEvent; import org.gestouch.events.GestureEvent;
import flash.errors.IllegalOperationError; import flash.errors.IllegalOperationError;
import flash.events.EventDispatcher; import flash.events.EventDispatcher;
@ -19,10 +19,31 @@ package org.gestouch.gestures
/** /**
* Dispatched when the state of the gesture changes. * Dispatched when the state of the gesture changes.
* *
* @eventType org.gestouch.events.GestureStateEvent * @eventType org.gestouch.events.GestureEvent
* @see #state * @see #state
*/ */
[Event(name="stateChange", type="org.gestouch.events.GestureStateEvent")] [Event(name="gestureStateChange", type="org.gestouch.events.GestureEvent")]
/**
* Dispatched when the state of the gesture changes to GestureState.IDLE.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gestureIdle", type="org.gestouch.events.GestureEvent")]
/**
* Dispatched when the state of the gesture changes to GestureState.POSSIBLE.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gesturePossible", type="org.gestouch.events.GestureEvent")]
/**
* Dispatched when the state of the gesture changes to GestureState.FAILED.
*
* @eventType org.gestouch.events.GestureEvent
* @see #state
*/
[Event(name="gestureFailed", type="org.gestouch.events.GestureEvent")]
/** /**
* Base class for all gestures. Gesture is essentially a detector that tracks touch points * Base class for all gestures. Gesture is essentially a detector that tracks touch points
* in order detect specific gesture motion and form gesture event on target. * in order detect specific gesture motion and form gesture event on target.
@ -45,7 +66,6 @@ package org.gestouch.gestures
*/ */
protected var _touchesMap:Object = {}; protected var _touchesMap:Object = {};
protected var _centralPoint:Point = new Point(); protected var _centralPoint:Point = new Point();
protected var _localLocation:Point;
/** /**
* List of gesture we require to fail. * List of gesture we require to fail.
* @see requireGestureToFail() * @see requireGestureToFail()
@ -53,6 +73,8 @@ package org.gestouch.gestures
protected var _gesturesToFail:Dictionary = new Dictionary(true); protected var _gesturesToFail:Dictionary = new Dictionary(true);
protected var _pendingRecognizedState:GestureState; protected var _pendingRecognizedState:GestureState;
private var eventListeners:Dictionary = new Dictionary();
use namespace gestouch_internal; use namespace gestouch_internal;
@ -200,14 +222,40 @@ package org.gestouch.gestures
// //
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void override public function addEventListener(type:String, listener:Function,
useCapture:Boolean = false, priority:int = 0,
useWeakReference:Boolean = false):void
{ {
if (!eventTypeIsValid(type)) super.addEventListener(type, listener, useCapture, priority, useWeakReference);
const listenerProps:Array = eventListeners[listener] as Array;
if (listenerProps)
{ {
throw new ArgumentError("Event type does not match any of allowed values."); listenerProps.push(type, useCapture);
}
else
{
eventListeners[listener] = [type, useCapture];
}
} }
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
public function removeAllEventListeners():void
{
for (var listener:Object in eventListeners)
{
const listenerProps:Array = eventListeners[listener] as Array;
var n:uint = listenerProps.length;
for (var i:uint = 0; i < n;)
{
super.removeEventListener(listenerProps[i++] as String, listener as Function, listenerProps[i++] as Boolean);
}
delete eventListeners[listener];
}
// eventListeners = new Dictionary(true);
} }
@ -251,7 +299,7 @@ package org.gestouch.gestures
for (var key:* in _gesturesToFail) for (var key:* in _gesturesToFail)
{ {
var gestureToFail:Gesture = key as Gesture; var gestureToFail:Gesture = key as Gesture;
gestureToFail.removeEventListener(GestureStateEvent.STATE_CHANGE, gestureToFail_stateChangeHandler); gestureToFail.removeEventListener(GestureEvent.GESTURE_STATE_CHANGE, gestureToFail_stateChangeHandler);
} }
_pendingRecognizedState = null; _pendingRecognizedState = null;
@ -286,9 +334,11 @@ package org.gestouch.gestures
{ {
//TODO //TODO
reset(); reset();
removeAllEventListeners();
target = null; target = null;
delegate = null; delegate = null;
_gesturesToFail = null; _gesturesToFail = null;
eventListeners = null;
} }
@ -431,11 +481,19 @@ package org.gestouch.gestures
if (_state == newState && _state == GestureState.CHANGED) if (_state == newState && _state == GestureState.CHANGED)
{ {
// shortcut for better performance // shortcut for better performance
if (hasEventListener(GestureStateEvent.STATE_CHANGE))
if (hasEventListener(GestureEvent.GESTURE_STATE_CHANGE))
{ {
dispatchEvent(new GestureStateEvent(GestureStateEvent.STATE_CHANGE, _state, _state)); dispatchEvent(new GestureEvent(GestureEvent.GESTURE_STATE_CHANGE, _state, _state));
} }
if (hasEventListener(GestureEvent.GESTURE_CHANGED))
{
dispatchEvent(new GestureEvent(GestureEvent.GESTURE_CHANGED, _state, _state));
}
resetNotificationProperties();
return true; return true;
} }
@ -479,7 +537,7 @@ package org.gestouch.gestures
for (key in _gesturesToFail) for (key in _gesturesToFail)
{ {
gestureToFail = key as Gesture; gestureToFail = key as Gesture;
gestureToFail.addEventListener(GestureStateEvent.STATE_CHANGE, gestureToFail_stateChangeHandler, false, 0, true); gestureToFail.addEventListener(GestureEvent.GESTURE_STATE_CHANGE, gestureToFail_stateChangeHandler, false, 0, true);
} }
return false; return false;
@ -507,11 +565,18 @@ package org.gestouch.gestures
//TODO: what if RTE happens in event handlers? //TODO: what if RTE happens in event handlers?
if (hasEventListener(GestureStateEvent.STATE_CHANGE)) if (hasEventListener(GestureEvent.GESTURE_STATE_CHANGE))
{ {
dispatchEvent(new GestureStateEvent(GestureStateEvent.STATE_CHANGE, _state, oldState)); dispatchEvent(new GestureEvent(GestureEvent.GESTURE_STATE_CHANGE, _state, oldState));
} }
if (hasEventListener(_state.toEventType()))
{
dispatchEvent(new GestureEvent(_state.toEventType(), _state, oldState));
}
resetNotificationProperties();
if (_state == GestureState.BEGAN || _state == GestureState.RECOGNIZED) if (_state == GestureState.BEGAN || _state == GestureState.RECOGNIZED)
{ {
_gesturesManager.onGestureRecognized(this); _gesturesManager.onGestureRecognized(this);
@ -548,28 +613,15 @@ package org.gestouch.gestures
updateCentralPoint(); updateCentralPoint();
_location.x = _centralPoint.x; _location.x = _centralPoint.x;
_location.y = _centralPoint.y; _location.y = _centralPoint.y;
_localLocation = targetAdapter.globalToLocal(_location);
} }
/** protected function resetNotificationProperties():void
* Executed once requiredToFail gestures have been failed and
* pending (delayed) recognized state has been entered.
* You must dispatch gesture event here.
*/
protected function onDelayedRecognize():void
{ {
} }
protected function eventTypeIsValid(type:String):Boolean
{
// propertyChange just in case for bindings?
return type == GestureStateEvent.STATE_CHANGE || type == "propertyChange";
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -629,7 +681,7 @@ package org.gestouch.gestures
} }
protected function gestureToFail_stateChangeHandler(event:GestureStateEvent):void protected function gestureToFail_stateChangeHandler(event:GestureEvent):void
{ {
if (!_pendingRecognizedState || state != GestureState.POSSIBLE) if (!_pendingRecognizedState || state != GestureState.POSSIBLE)
return; return;
@ -647,10 +699,7 @@ package org.gestouch.gestures
} }
// at this point all gestures-to-fail are either in IDLE or in FAILED states // at this point all gestures-to-fail are either in IDLE or in FAILED states
if (setState(_pendingRecognizedState)) setState(_pendingRecognizedState);
{
onDelayedRecognize();
}
} }
else if (event.newState != GestureState.IDLE && event.newState != GestureState.POSSIBLE) else if (event.newState != GestureState.IDLE && event.newState != GestureState.POSSIBLE)
{ {

View file

@ -2,24 +2,18 @@ package org.gestouch.gestures
{ {
import org.gestouch.core.GestureState; import org.gestouch.core.GestureState;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.events.LongPressGestureEvent;
import flash.events.TimerEvent; import flash.events.TimerEvent;
import flash.utils.Timer; import flash.utils.Timer;
/**
*
* @eventType org.gestouch.events.LongPressGestureEvent
*/
[Event(name="gestureLongPress", type="org.gestouch.events.LongPressGestureEvent")]
/** /**
* TODO: * TODO:
* - add numTapsRequired * - add numTapsRequired
* *
* @author Pavel fljot * @author Pavel fljot
*/ */
public class LongPressGesture extends Gesture public class LongPressGesture extends AbstractContinuousGesture
{ {
public var numTouchesRequired:uint = 1; public var numTouchesRequired:uint = 1;
/** /**
@ -50,7 +44,7 @@ package org.gestouch.gestures
override public function reflect():Class override public function reflect():Class
{ {
return TapGesture; return LongPressGesture;
} }
@ -71,12 +65,6 @@ package org.gestouch.gestures
// //
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
override protected function eventTypeIsValid(type:String):Boolean
{
return type == LongPressGestureEvent.GESTURE_LONG_PRESS || super.eventTypeIsValid(type);
}
override protected function preinit():void override protected function preinit():void
{ {
super.preinit(); super.preinit();
@ -113,11 +101,7 @@ package org.gestouch.gestures
else if (state == GestureState.BEGAN || state == GestureState.CHANGED) else if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
updateLocation(); updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS)) setState(GestureState.CHANGED);
{
dispatchEvent(new LongPressGestureEvent(LongPressGestureEvent.GESTURE_LONG_PRESS, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
} }
} }
@ -129,11 +113,7 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
updateLocation(); updateLocation();
if (setState(GestureState.ENDED) && hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS)) setState(GestureState.ENDED);
{
dispatchEvent(new LongPressGestureEvent(LongPressGestureEvent.GESTURE_LONG_PRESS, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
} }
else else
{ {
@ -147,16 +127,6 @@ package org.gestouch.gestures
} }
override protected function onDelayedRecognize():void
{
if (hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS))
{
dispatchEvent(new LongPressGestureEvent(LongPressGestureEvent.GESTURE_LONG_PRESS, false, false, GestureState.BEGAN,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -170,11 +140,7 @@ package org.gestouch.gestures
if (state == GestureState.POSSIBLE) if (state == GestureState.POSSIBLE)
{ {
updateLocation(); updateLocation();
if (setState(GestureState.BEGAN) && hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS)) setState(GestureState.BEGAN);
{
dispatchEvent(new LongPressGestureEvent(LongPressGestureEvent.GESTURE_LONG_PRESS, false, false, GestureState.BEGAN,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
} }
} }
} }

View file

@ -2,16 +2,10 @@ package org.gestouch.gestures
{ {
import org.gestouch.core.GestureState; import org.gestouch.core.GestureState;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.events.PanGestureEvent;
import flash.geom.Point; import flash.geom.Point;
/**
*
* @eventType org.gestouch.events.PanGestureEvent
*/
[Event(name="gesturePan", type="org.gestouch.events.PanGestureEvent")]
/** /**
* TODO: * TODO:
* -location * -location
@ -19,7 +13,7 @@ package org.gestouch.gestures
* *
* @author Pavel fljot * @author Pavel fljot
*/ */
public class PanGesture extends Gesture public class PanGesture extends AbstractContinuousGesture
{ {
public var slop:Number = Gesture.DEFAULT_SLOP; public var slop:Number = Gesture.DEFAULT_SLOP;
/** /**
@ -27,9 +21,6 @@ package org.gestouch.gestures
*/ */
public var direction:uint = PanGestureDirection.NO_DIRECTION; public var direction:uint = PanGestureDirection.NO_DIRECTION;
protected var _gestureBeginOffsetX:Number;
protected var _gestureBeginOffsetY:Number;
public function PanGesture(target:Object = null) public function PanGesture(target:Object = null)
{ {
@ -81,6 +72,20 @@ package org.gestouch.gestures
} }
protected var _offsetX:Number = 0;
public function get offsetX():Number
{
return _offsetX;
}
protected var _offsetY:Number = 0;
public function get offsetY():Number
{
return _offsetY;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -95,15 +100,6 @@ package org.gestouch.gestures
} }
override public function reset():void
{
_gestureBeginOffsetX = NaN;
_gestureBeginOffsetY = NaN;
super.reset();
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -112,12 +108,6 @@ package org.gestouch.gestures
// //
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
override protected function eventTypeIsValid(type:String):Boolean
{
return type == PanGestureEvent.GESTURE_PAN || super.eventTypeIsValid(type);
}
override protected function onTouchBegin(touch:Touch):void override protected function onTouchBegin(touch:Touch):void
{ {
if (touchesCount > maxNumTouchesRequired) if (touchesCount > maxNumTouchesRequired)
@ -140,8 +130,6 @@ package org.gestouch.gestures
var prevLocationX:Number; var prevLocationX:Number;
var prevLocationY:Number; var prevLocationY:Number;
var offsetX:Number;
var offsetY:Number;
if (state == GestureState.POSSIBLE) if (state == GestureState.POSSIBLE)
{ {
@ -162,17 +150,11 @@ package org.gestouch.gestures
if (locationOffset.length > slop || slop != slop)//faster isNaN(slop) if (locationOffset.length > slop || slop != slop)//faster isNaN(slop)
{ {
offsetX = _location.x - prevLocationX; // NB! += instead of = for the case when this gesture recognition is delayed via requireGestureToFail
offsetY = _location.y - prevLocationY; _offsetX += _location.x - prevLocationX;
// acummulate begin offsets for the case when this gesture recognition is delayed by requireGestureToFail _offsetY += _location.y - prevLocationY;
_gestureBeginOffsetX = (_gestureBeginOffsetX != _gestureBeginOffsetX) ? offsetX : _gestureBeginOffsetX + offsetX;
_gestureBeginOffsetY = (_gestureBeginOffsetY != _gestureBeginOffsetY) ? offsetY : _gestureBeginOffsetY + offsetY;
if (setState(GestureState.BEGAN) && hasEventListener(PanGestureEvent.GESTURE_PAN)) setState(GestureState.BEGAN);
{
dispatchEvent(new PanGestureEvent(PanGestureEvent.GESTURE_PAN, false, false, GestureState.BEGAN,
_location.x, _location.y, _localLocation.x, _localLocation.y, offsetX, offsetY));
}
} }
} }
else if (state == GestureState.BEGAN || state == GestureState.CHANGED) else if (state == GestureState.BEGAN || state == GestureState.CHANGED)
@ -180,14 +162,10 @@ package org.gestouch.gestures
prevLocationX = _location.x; prevLocationX = _location.x;
prevLocationY = _location.y; prevLocationY = _location.y;
updateLocation(); updateLocation();
offsetX = _location.x - prevLocationX; _offsetX = _location.x - prevLocationX;
offsetY = _location.y - prevLocationY; _offsetY = _location.y - prevLocationY;
if (setState(GestureState.CHANGED) && hasEventListener(PanGestureEvent.GESTURE_PAN)) setState(GestureState.CHANGED);
{
dispatchEvent(new PanGestureEvent(PanGestureEvent.GESTURE_PAN, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y, offsetX, offsetY));
}
} }
} }
@ -202,11 +180,7 @@ package org.gestouch.gestures
} }
else else
{ {
if (setState(GestureState.ENDED) && hasEventListener(PanGestureEvent.GESTURE_PAN)) setState(GestureState.ENDED);
{
dispatchEvent(new PanGestureEvent(PanGestureEvent.GESTURE_PAN, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y, 0, 0));
}
} }
} }
else else
@ -216,13 +190,11 @@ package org.gestouch.gestures
} }
override protected function onDelayedRecognize():void override protected function resetNotificationProperties():void
{ {
if (hasEventListener(PanGestureEvent.GESTURE_PAN)) super.resetNotificationProperties();
{
dispatchEvent(new PanGestureEvent(PanGestureEvent.GESTURE_PAN, false, false, GestureState.BEGAN, _offsetX = _offsetY = 0;
_location.x, _location.y, _localLocation.x, _localLocation.y, _gestureBeginOffsetX, _gestureBeginOffsetY));
}
} }
} }
} }

View file

@ -2,23 +2,17 @@ package org.gestouch.gestures
{ {
import org.gestouch.core.GestureState; import org.gestouch.core.GestureState;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.events.RotateGestureEvent;
import flash.geom.Point; import flash.geom.Point;
/**
*
* @eventType org.gestouch.events.RotateGestureEvent
*/
[Event(name="gestureRotate", type="org.gestouch.events.RotateGestureEvent")]
/** /**
* TODO: * TODO:
* -check native behavior on iDevice * -check native behavior on iDevice
* *
* @author Pavel fljot * @author Pavel fljot
*/ */
public class RotateGesture extends Gesture public class RotateGesture extends AbstractContinuousGesture
{ {
public var slop:Number = Gesture.DEFAULT_SLOP; public var slop:Number = Gesture.DEFAULT_SLOP;
@ -34,6 +28,13 @@ package org.gestouch.gestures
} }
protected var _rotation:Number = 0;
public function get rotation():Number
{
return _rotation;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -56,12 +57,6 @@ package org.gestouch.gestures
// //
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
override protected function eventTypeIsValid(type:String):Boolean
{
return type == RotateGestureEvent.GESTURE_ROTATE || super.eventTypeIsValid(type);
}
override protected function onTouchBegin(touch:Touch):void override protected function onTouchBegin(touch:Touch):void
{ {
if (touchesCount > 2) if (touchesCount > 2)
@ -109,24 +104,17 @@ package org.gestouch.gestures
_transformVector.x = currTransformVector.x; _transformVector.x = currTransformVector.x;
_transformVector.y = currTransformVector.y; _transformVector.y = currTransformVector.y;
_rotation = rotation;
updateLocation(); updateLocation();
if (state == GestureState.POSSIBLE) if (state == GestureState.POSSIBLE)
{ {
if (setState(GestureState.BEGAN) && hasEventListener(RotateGestureEvent.GESTURE_ROTATE)) setState(GestureState.BEGAN);
{
dispatchEvent(new RotateGestureEvent(RotateGestureEvent.GESTURE_ROTATE, false, false, GestureState.BEGAN,
_location.x, _location.y, _localLocation.x, _localLocation.y, rotation));
}
} }
else else
{ {
if (setState(GestureState.CHANGED) && hasEventListener(RotateGestureEvent.GESTURE_ROTATE)) setState(GestureState.CHANGED);
{
dispatchEvent(new RotateGestureEvent(RotateGestureEvent.GESTURE_ROTATE, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y, rotation));
}
} }
} }
@ -137,11 +125,7 @@ package org.gestouch.gestures
{ {
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
if (setState(GestureState.ENDED) && hasEventListener(RotateGestureEvent.GESTURE_ROTATE)) setState(GestureState.ENDED);
{
dispatchEvent(new RotateGestureEvent(RotateGestureEvent.GESTURE_ROTATE, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y, 0));
}
} }
else if (state == GestureState.POSSIBLE) else if (state == GestureState.POSSIBLE)
{ {
@ -159,13 +143,17 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
updateLocation(); updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(RotateGestureEvent.GESTURE_ROTATE)) setState(GestureState.CHANGED);
}
}
}
override protected function resetNotificationProperties():void
{ {
dispatchEvent(new RotateGestureEvent(RotateGestureEvent.GESTURE_ROTATE, false, false, GestureState.CHANGED, super.resetNotificationProperties();
_location.x, _location.y, _localLocation.x, _localLocation.y, 0));
} _rotation = 0;
}
}
} }
} }
} }

View file

@ -2,7 +2,6 @@ package org.gestouch.gestures
{ {
import org.gestouch.core.GestureState; import org.gestouch.core.GestureState;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.events.SwipeGestureEvent;
import org.gestouch.utils.GestureUtils; import org.gestouch.utils.GestureUtils;
import flash.events.TimerEvent; import flash.events.TimerEvent;
@ -11,11 +10,6 @@ package org.gestouch.gestures
import flash.utils.Timer; import flash.utils.Timer;
/**
*
* @eventType org.gestouch.events.SwipeGestureEvent
*/
[Event(name="gestureSwipe", type="org.gestouch.events.SwipeGestureEvent")]
/** /**
* Recognition logic:<br/> * Recognition logic:<br/>
* 1. should be recognized during <code>maxDuration</code> period<br/> * 1. should be recognized during <code>maxDuration</code> period<br/>
@ -24,7 +18,7 @@ package org.gestouch.gestures
* *
* @author Pavel fljot * @author Pavel fljot
*/ */
public class SwipeGesture extends Gesture public class SwipeGesture extends AbstractDiscreteGesture
{ {
private static const ANGLE:Number = 40 * GestureUtils.DEGREES_TO_RADIANS; private static const ANGLE:Number = 40 * GestureUtils.DEGREES_TO_RADIANS;
private static const MAX_DURATION:uint = 500; private static const MAX_DURATION:uint = 500;
@ -87,6 +81,18 @@ package org.gestouch.gestures
} }
public function get offsetX():Number
{
return _offset.x;
}
public function get offsetY():Number
{
return _offset.y;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -120,12 +126,6 @@ package org.gestouch.gestures
// //
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
override protected function eventTypeIsValid(type:String):Boolean
{
return type == SwipeGestureEvent.GESTURE_SWIPE || super.eventTypeIsValid(type);
}
override protected function preinit():void override protected function preinit():void
{ {
super.preinit(); super.preinit();
@ -189,12 +189,7 @@ package org.gestouch.gestures
{ {
if (avrgVel >= minVelocity || offsetLength >= minOffset) if (avrgVel >= minVelocity || offsetLength >= minOffset)
{ {
if (setState(GestureState.RECOGNIZED) && hasEventListener(SwipeGestureEvent.GESTURE_SWIPE)) setState(GestureState.RECOGNIZED);
{
_localLocation = targetAdapter.globalToLocal(_location);//refresh local location in case target moved
dispatchEvent(new SwipeGestureEvent(SwipeGestureEvent.GESTURE_SWIPE, false, false, GestureState.RECOGNIZED,
_location.x, _location.y, _localLocation.x, _localLocation.y, _offset.x, _offset.y));
}
} }
} }
else else
@ -225,12 +220,7 @@ package org.gestouch.gestures
else if (absVelX >= minVelocity || absOffsetX >= minOffset) else if (absVelX >= minVelocity || absOffsetX >= minOffset)
{ {
_offset.y = 0; _offset.y = 0;
if (setState(GestureState.RECOGNIZED) && hasEventListener(SwipeGestureEvent.GESTURE_SWIPE)) setState(GestureState.RECOGNIZED);
{
_localLocation = targetAdapter.globalToLocal(_location);//refresh local location in case target moved
dispatchEvent(new SwipeGestureEvent(SwipeGestureEvent.GESTURE_SWIPE, false, false, GestureState.RECOGNIZED,
_location.x, _location.y, _localLocation.x, _localLocation.y, _offset.x, _offset.y));
}
} }
} }
else if (absVelY > absVelX) else if (absVelY > absVelX)
@ -253,12 +243,7 @@ package org.gestouch.gestures
else if (absVelY >= minVelocity || absOffsetY >= minOffset) else if (absVelY >= minVelocity || absOffsetY >= minOffset)
{ {
_offset.x = 0; _offset.x = 0;
if (setState(GestureState.RECOGNIZED) && hasEventListener(SwipeGestureEvent.GESTURE_SWIPE)) setState(GestureState.RECOGNIZED);
{
_localLocation = targetAdapter.globalToLocal(_location);//refresh local location in case target moved
dispatchEvent(new SwipeGestureEvent(SwipeGestureEvent.GESTURE_SWIPE, false, false, GestureState.RECOGNIZED,
_location.x, _location.y, _localLocation.x, _localLocation.y, _offset.x, _offset.y));
}
} }
} }
// Give some tolerance for accidental offset on finger press (slop) // Give some tolerance for accidental offset on finger press (slop)
@ -279,14 +264,11 @@ package org.gestouch.gestures
} }
override protected function onDelayedRecognize():void override protected function resetNotificationProperties():void
{ {
if (hasEventListener(SwipeGestureEvent.GESTURE_SWIPE)) super.resetNotificationProperties();
{
_localLocation = targetAdapter.globalToLocal(_location);//refresh local location in case target moved _offset.x = _offset.y = 0;
dispatchEvent(new SwipeGestureEvent(SwipeGestureEvent.GESTURE_SWIPE, false, false, GestureState.RECOGNIZED,
_location.x, _location.y, _localLocation.x, _localLocation.y, _offset.x, _offset.y));
}
} }

View file

@ -2,22 +2,16 @@ package org.gestouch.gestures
{ {
import org.gestouch.core.GestureState; import org.gestouch.core.GestureState;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.events.TapGestureEvent;
import flash.events.TimerEvent; import flash.events.TimerEvent;
import flash.utils.Timer; import flash.utils.Timer;
/**
*
* @eventType org.gestouch.events.TapGestureEvent
*/
[Event(name="gestureTap", type="org.gestouch.events.TapGestureEvent")]
/** /**
* *
* @author Pavel fljot * @author Pavel fljot
*/ */
public class TapGesture extends Gesture public class TapGesture extends AbstractDiscreteGesture
{ {
public var numTouchesRequired:uint = 1; public var numTouchesRequired:uint = 1;
public var numTapsRequired:uint = 1; public var numTapsRequired:uint = 1;
@ -79,12 +73,6 @@ package org.gestouch.gestures
// //
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
override protected function eventTypeIsValid(type:String):Boolean
{
return type == TapGestureEvent.GESTURE_TAP || super.eventTypeIsValid(type);
}
override protected function preinit():void override protected function preinit():void
{ {
super.preinit(); super.preinit();
@ -142,11 +130,7 @@ package org.gestouch.gestures
if (_tapCounter == numTapsRequired) if (_tapCounter == numTapsRequired)
{ {
if (setState(GestureState.RECOGNIZED) && hasEventListener(TapGestureEvent.GESTURE_TAP)) setState(GestureState.RECOGNIZED);
{
dispatchEvent(new TapGestureEvent(TapGestureEvent.GESTURE_TAP, false, false, GestureState.RECOGNIZED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
} }
else else
{ {
@ -157,16 +141,6 @@ package org.gestouch.gestures
} }
override protected function onDelayedRecognize():void
{
if (hasEventListener(TapGestureEvent.GESTURE_TAP))
{
dispatchEvent(new TapGestureEvent(TapGestureEvent.GESTURE_TAP, false, false, GestureState.RECOGNIZED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View file

@ -2,20 +2,14 @@ package org.gestouch.gestures
{ {
import org.gestouch.core.GestureState; import org.gestouch.core.GestureState;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.events.TransformGestureEvent;
import flash.geom.Point; import flash.geom.Point;
/**
*
* @eventType org.gestouch.events.TransformGestureEvent
*/
[Event(name="gestureTransform", type="org.gestouch.events.TransformGestureEvent")]
/** /**
* @author Pavel fljot * @author Pavel fljot
*/ */
public class TransformGesture extends Gesture public class TransformGesture extends AbstractContinuousGesture
{ {
public var slop:Number = Gesture.DEFAULT_SLOP; public var slop:Number = Gesture.DEFAULT_SLOP;
@ -30,6 +24,34 @@ package org.gestouch.gestures
} }
protected var _offsetX:Number = 0;
public function get offsetX():Number
{
return _offsetX;
}
protected var _offsetY:Number = 0;
public function get offsetY():Number
{
return _offsetY;
}
protected var _rotation:Number = 0;
public function get rotation():Number
{
return _rotation;
}
protected var _scale:Number = 1;
public function get scale():Number
{
return _scale;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -61,12 +83,6 @@ package org.gestouch.gestures
// //
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
override protected function eventTypeIsValid(type:String):Boolean
{
return type == TransformGestureEvent.GESTURE_TRANSFORM || super.eventTypeIsValid(type);
}
override protected function onTouchBegin(touch:Touch):void override protected function onTouchBegin(touch:Touch):void
{ {
if (touchesCount > 2) if (touchesCount > 2)
@ -90,11 +106,8 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM)) // notify that location (and amount of touches) has changed
{ setState(GestureState.CHANGED);
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
} }
} }
@ -125,41 +138,16 @@ package org.gestouch.gestures
currTransformVector = _touch2.location.subtract(_touch1.location); currTransformVector = _touch2.location.subtract(_touch1.location);
} }
var prevLocalLocation:Point; _offsetX = _location.x - prevLocation.x;
var offsetX:Number = _location.x - prevLocation.x; _offsetY = _location.y - prevLocation.y;
var offsetY:Number = _location.y - prevLocation.y;
var scale:Number = 1;
var rotation:Number = 0;
if (_touch2) if (_touch2)
{ {
rotation = Math.atan2(currTransformVector.y, currTransformVector.x) - Math.atan2(_transformVector.y, _transformVector.x); _rotation = Math.atan2(currTransformVector.y, currTransformVector.x) - Math.atan2(_transformVector.y, _transformVector.x);
scale = currTransformVector.length / _transformVector.length; _scale = currTransformVector.length / _transformVector.length;
_transformVector = _touch2.location.subtract(_touch1.location); _transformVector = _touch2.location.subtract(_touch1.location);
} }
setState(state == GestureState.POSSIBLE ? GestureState.BEGAN : GestureState.CHANGED);
if (state == GestureState.POSSIBLE)
{
if (setState(GestureState.BEGAN) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
// Note that we dispatch previous location point which gives a way to perform
// accurate UI redraw. See examples project for more info.
prevLocalLocation = targetAdapter.globalToLocal(prevLocation);
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.BEGAN,
prevLocation.x, prevLocation.y, prevLocalLocation.x, prevLocalLocation.y, scale, scale, rotation, offsetX, offsetY));
}
}
else
{
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
// Note that we dispatch previous location point which gives a way to perform
// accurate UI redraw. See examples project for more info.
prevLocalLocation = targetAdapter.globalToLocal(prevLocation);
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED,
prevLocation.x, prevLocation.y, prevLocalLocation.x, prevLocalLocation.y, scale, scale, rotation, offsetX, offsetY));
}
}
} }
@ -169,11 +157,7 @@ package org.gestouch.gestures
{ {
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
if (setState(GestureState.ENDED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM)) setState(GestureState.ENDED);
{
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
} }
else if (state == GestureState.POSSIBLE) else if (state == GestureState.POSSIBLE)
{ {
@ -191,13 +175,19 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
updateLocation(); updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM)) setState(GestureState.CHANGED);
}
}
}
override protected function resetNotificationProperties():void
{ {
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED, super.resetNotificationProperties();
_location.x, _location.y, _localLocation.x, _localLocation.y));
} _offsetX = _offsetY = 0;
} _rotation = 0;
} _scale = 1;
} }
} }
} }

View file

@ -2,21 +2,15 @@ package org.gestouch.gestures
{ {
import org.gestouch.core.GestureState; import org.gestouch.core.GestureState;
import org.gestouch.core.Touch; import org.gestouch.core.Touch;
import org.gestouch.events.ZoomGestureEvent;
import flash.geom.Point; import flash.geom.Point;
/**
*
* @eventType org.gestouch.events.ZoomGestureEvent
*/
[Event(name="gestureZoom", type="org.gestouch.events.ZoomGestureEvent")]
/** /**
* *
* @author Pavel fljot * @author Pavel fljot
*/ */
public class ZoomGesture extends Gesture public class ZoomGesture extends AbstractContinuousGesture
{ {
public var slop:Number = Gesture.DEFAULT_SLOP; public var slop:Number = Gesture.DEFAULT_SLOP;
public var lockAspectRatio:Boolean = true; public var lockAspectRatio:Boolean = true;
@ -33,6 +27,20 @@ package org.gestouch.gestures
} }
protected var _scaleX:Number = 1;
public function get scaleX():Number
{
return _scaleX;
}
protected var _scaleY:Number = 1;
public function get scaleY():Number
{
return _scaleY;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -55,12 +63,6 @@ package org.gestouch.gestures
// //
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
override protected function eventTypeIsValid(type:String):Boolean
{
return type == ZoomGestureEvent.GESTURE_ZOOM || super.eventTypeIsValid(type);
}
override protected function onTouchBegin(touch:Touch):void override protected function onTouchBegin(touch:Touch):void
{ {
if (touchesCount > 2) if (touchesCount > 2)
@ -89,8 +91,6 @@ package org.gestouch.gestures
return; return;
var currTransformVector:Point = _touch2.location.subtract(_touch1.location); var currTransformVector:Point = _touch2.location.subtract(_touch1.location);
var scaleX:Number;
var scaleY:Number;
if (state == GestureState.POSSIBLE) if (state == GestureState.POSSIBLE)
{ {
@ -114,12 +114,13 @@ package org.gestouch.gestures
if (lockAspectRatio) if (lockAspectRatio)
{ {
scaleX = scaleY = currTransformVector.length / _transformVector.length; _scaleX *= currTransformVector.length / _transformVector.length;
_scaleY = _scaleX;
} }
else else
{ {
scaleX = currTransformVector.x / _transformVector.x; _scaleX *= currTransformVector.x / _transformVector.x;
scaleY = currTransformVector.y / _transformVector.y; _scaleY *= currTransformVector.y / _transformVector.y;
} }
_transformVector.x = currTransformVector.x; _transformVector.x = currTransformVector.x;
@ -129,19 +130,11 @@ package org.gestouch.gestures
if (state == GestureState.POSSIBLE) if (state == GestureState.POSSIBLE)
{ {
if (setState(GestureState.BEGAN) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM)) setState(GestureState.BEGAN);
{
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.BEGAN,
_location.x, _location.y, _localLocation.x, _localLocation.y, scaleX, scaleY));
}
} }
else else
{ {
if (setState(GestureState.CHANGED) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM)) setState(GestureState.CHANGED);
{
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y, scaleX, scaleY));
}
} }
} }
@ -152,11 +145,7 @@ package org.gestouch.gestures
{ {
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
if (setState(GestureState.ENDED) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM)) setState(GestureState.ENDED);
{
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y, 1, 1));
}
} }
else if (state == GestureState.POSSIBLE) else if (state == GestureState.POSSIBLE)
{ {
@ -174,13 +163,17 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED) if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{ {
updateLocation(); updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM)) setState(GestureState.CHANGED);
}
}
}
override protected function resetNotificationProperties():void
{ {
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.CHANGED, super.resetNotificationProperties();
_location.x, _location.y, _localLocation.x, _localLocation.y, 1, 1));
} _scaleX = _scaleY = 1;
}
}
} }
} }
} }

View file

@ -1 +1 @@
project.version = 0.4 project.version = 0.4.1