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
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);
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!
}
</code></pre>
or
<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!
trace(freeTransform.offsetX, freeTransform.offsetY, freeTransform.rotation, freeTransform.scale);
}
</code></pre>

View file

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

View file

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

View file

@ -10,38 +10,40 @@ package org.gestouch.events
*/
public class GestureEvent extends Event
{
public var gestureState:GestureState;
public var stageX:Number;
public var stageY:Number;
public var localX:Number;
public var localY:Number;
public static const GESTURE_IDLE:String = "gestureIdle";
public static const GESTURE_POSSIBLE:String = "gesturePossible";
public static const GESTURE_RECOGNIZED:String = "gestureRecognized";
public static const GESTURE_BEGAN:String = "gestureBegan";
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,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0)
public var newState:GestureState;
public var oldState:GestureState;
public function GestureEvent(type:String, newState:GestureState, oldState:GestureState)
{
super(type, bubbles, cancelable);
super(type, false, false);
this.gestureState = gestureState;
this.stageX = stageX;
this.stageY = stageY;
this.localX = localX;
this.localY = localY;
this.newState = newState;
this.oldState = oldState;
}
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
{
return formatToString("org.gestouch.events.GestureEvent", "bubbles", "cancelable",
"gestureState", "stageX", "stageY", "localX", "localY");
return formatToString("GestureEvent", "type", "oldState", "newState");
}
}
}
}

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
{
const targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer;

View file

@ -1,12 +1,10 @@
package org.gestouch.extensions.starling
{
import starling.core.Starling;
import starling.display.DisplayObject;
import starling.display.DisplayObjectContainer;
import org.gestouch.core.IDisplayListAdapter;
import flash.geom.Point;
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
{
const targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer;

View file

@ -29,7 +29,7 @@ package org.gestouch.extensions.starling
public function hitTest(point:Point, nativeTarget:InteractiveObject):Object
{
point = StarlingUtils.adjustGlobalPoint(starling, point);
point = StarlingUtils.adjustGlobalPoint(starling, point);
return starling.stage.hitTest(point, true);
}
}

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.Touch;
import org.gestouch.core.gestouch_internal;
import org.gestouch.events.GestureStateEvent;
import org.gestouch.events.GestureEvent;
import flash.errors.IllegalOperationError;
import flash.events.EventDispatcher;
@ -19,10 +19,31 @@ package org.gestouch.gestures
/**
* Dispatched when the state of the gesture changes.
*
* @eventType org.gestouch.events.GestureStateEvent
* @eventType org.gestouch.events.GestureEvent
* @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
* 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 _centralPoint:Point = new Point();
protected var _localLocation:Point;
/**
* List of gesture we require to fail.
* @see requireGestureToFail()
@ -53,6 +73,8 @@ package org.gestouch.gestures
protected var _gesturesToFail:Dictionary = new Dictionary(true);
protected var _pendingRecognizedState:GestureState;
private var eventListeners:Dictionary = new Dictionary();
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];
}
}
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];
}
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
// eventListeners = new Dictionary(true);
}
@ -251,7 +299,7 @@ package org.gestouch.gestures
for (var key:* in _gesturesToFail)
{
var gestureToFail:Gesture = key as Gesture;
gestureToFail.removeEventListener(GestureStateEvent.STATE_CHANGE, gestureToFail_stateChangeHandler);
gestureToFail.removeEventListener(GestureEvent.GESTURE_STATE_CHANGE, gestureToFail_stateChangeHandler);
}
_pendingRecognizedState = null;
@ -286,9 +334,11 @@ package org.gestouch.gestures
{
//TODO
reset();
removeAllEventListeners();
target = null;
delegate = null;
_gesturesToFail = null;
eventListeners = null;
}
@ -431,11 +481,19 @@ package org.gestouch.gestures
if (_state == newState && _state == GestureState.CHANGED)
{
// 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;
}
@ -479,7 +537,7 @@ package org.gestouch.gestures
for (key in _gesturesToFail)
{
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;
@ -507,11 +565,18 @@ package org.gestouch.gestures
//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)
{
_gesturesManager.onGestureRecognized(this);
@ -548,28 +613,15 @@ package org.gestouch.gestures
updateCentralPoint();
_location.x = _centralPoint.x;
_location.y = _centralPoint.y;
_localLocation = targetAdapter.globalToLocal(_location);
}
/**
* 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 resetNotificationProperties():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)
return;
@ -647,10 +699,7 @@ package org.gestouch.gestures
}
// at this point all gestures-to-fail are either in IDLE or in FAILED states
if (setState(_pendingRecognizedState))
{
onDelayedRecognize();
}
setState(_pendingRecognizedState);
}
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.Touch;
import org.gestouch.events.LongPressGestureEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
*
* @eventType org.gestouch.events.LongPressGestureEvent
*/
[Event(name="gestureLongPress", type="org.gestouch.events.LongPressGestureEvent")]
/**
* TODO:
* - add numTapsRequired
*
* @author Pavel fljot
*/
public class LongPressGesture extends Gesture
public class LongPressGesture extends AbstractContinuousGesture
{
public var numTouchesRequired:uint = 1;
/**
@ -50,7 +44,7 @@ package org.gestouch.gestures
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
{
super.preinit();
@ -113,11 +101,7 @@ package org.gestouch.gestures
else if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS))
{
dispatchEvent(new LongPressGestureEvent(LongPressGestureEvent.GESTURE_LONG_PRESS, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
setState(GestureState.CHANGED);
}
}
@ -129,11 +113,7 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
updateLocation();
if (setState(GestureState.ENDED) && hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS))
{
dispatchEvent(new LongPressGestureEvent(LongPressGestureEvent.GESTURE_LONG_PRESS, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
setState(GestureState.ENDED);
}
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)
{
updateLocation();
if (setState(GestureState.BEGAN) && hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS))
{
dispatchEvent(new LongPressGestureEvent(LongPressGestureEvent.GESTURE_LONG_PRESS, false, false, GestureState.BEGAN,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
setState(GestureState.BEGAN);
}
}
}

View file

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

View file

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

View file

@ -2,7 +2,6 @@ package org.gestouch.gestures
{
import org.gestouch.core.GestureState;
import org.gestouch.core.Touch;
import org.gestouch.events.SwipeGestureEvent;
import org.gestouch.utils.GestureUtils;
import flash.events.TimerEvent;
@ -11,11 +10,6 @@ package org.gestouch.gestures
import flash.utils.Timer;
/**
*
* @eventType org.gestouch.events.SwipeGestureEvent
*/
[Event(name="gestureSwipe", type="org.gestouch.events.SwipeGestureEvent")]
/**
* Recognition logic:<br/>
* 1. should be recognized during <code>maxDuration</code> period<br/>
@ -24,7 +18,7 @@ package org.gestouch.gestures
*
* @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 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
{
super.preinit();
@ -189,12 +189,7 @@ package org.gestouch.gestures
{
if (avrgVel >= minVelocity || offsetLength >= minOffset)
{
if (setState(GestureState.RECOGNIZED) && hasEventListener(SwipeGestureEvent.GESTURE_SWIPE))
{
_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));
}
setState(GestureState.RECOGNIZED);
}
}
else
@ -225,12 +220,7 @@ package org.gestouch.gestures
else if (absVelX >= minVelocity || absOffsetX >= minOffset)
{
_offset.y = 0;
if (setState(GestureState.RECOGNIZED) && hasEventListener(SwipeGestureEvent.GESTURE_SWIPE))
{
_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));
}
setState(GestureState.RECOGNIZED);
}
}
else if (absVelY > absVelX)
@ -253,12 +243,7 @@ package org.gestouch.gestures
else if (absVelY >= minVelocity || absOffsetY >= minOffset)
{
_offset.x = 0;
if (setState(GestureState.RECOGNIZED) && hasEventListener(SwipeGestureEvent.GESTURE_SWIPE))
{
_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));
}
setState(GestureState.RECOGNIZED);
}
}
// 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))
{
_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));
}
super.resetNotificationProperties();
_offset.x = _offset.y = 0;
}

View file

@ -2,22 +2,16 @@ package org.gestouch.gestures
{
import org.gestouch.core.GestureState;
import org.gestouch.core.Touch;
import org.gestouch.events.TapGestureEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
*
* @eventType org.gestouch.events.TapGestureEvent
*/
[Event(name="gestureTap", type="org.gestouch.events.TapGestureEvent")]
/**
*
* @author Pavel fljot
*/
public class TapGesture extends Gesture
public class TapGesture extends AbstractDiscreteGesture
{
public var numTouchesRequired: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
{
super.preinit();
@ -142,11 +130,7 @@ package org.gestouch.gestures
if (_tapCounter == numTapsRequired)
{
if (setState(GestureState.RECOGNIZED) && hasEventListener(TapGestureEvent.GESTURE_TAP))
{
dispatchEvent(new TapGestureEvent(TapGestureEvent.GESTURE_TAP, false, false, GestureState.RECOGNIZED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
setState(GestureState.RECOGNIZED);
}
else
{
@ -156,16 +140,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.Touch;
import org.gestouch.events.TransformGestureEvent;
import flash.geom.Point;
/**
*
* @eventType org.gestouch.events.TransformGestureEvent
*/
[Event(name="gestureTransform", type="org.gestouch.events.TransformGestureEvent")]
/**
* @author Pavel fljot
*/
public class TransformGesture extends Gesture
public class TransformGesture extends AbstractContinuousGesture
{
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;
}
// --------------------------------------------------------------------------
@ -43,12 +65,12 @@ package org.gestouch.gestures
return TransformGesture;
}
override public function reset():void
{
_touch1 = null;
_touch2 = null;
super.reset();
}
@ -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
{
if (touchesCount > 2)
@ -90,11 +106,8 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
// notify that location (and amount of touches) has changed
setState(GestureState.CHANGED);
}
}
@ -125,41 +138,16 @@ package org.gestouch.gestures
currTransformVector = _touch2.location.subtract(_touch1.location);
}
var prevLocalLocation:Point;
var offsetX:Number = _location.x - prevLocation.x;
var offsetY:Number = _location.y - prevLocation.y;
var scale:Number = 1;
var rotation:Number = 0;
_offsetX = _location.x - prevLocation.x;
_offsetY = _location.y - prevLocation.y;
if (_touch2)
{
rotation = Math.atan2(currTransformVector.y, currTransformVector.x) - Math.atan2(_transformVector.y, _transformVector.x);
scale = currTransformVector.length / _transformVector.length;
_rotation = Math.atan2(currTransformVector.y, currTransformVector.x) - Math.atan2(_transformVector.y, _transformVector.x);
_scale = currTransformVector.length / _transformVector.length;
_transformVector = _touch2.location.subtract(_touch1.location);
}
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));
}
}
setState(state == GestureState.POSSIBLE ? GestureState.BEGAN : GestureState.CHANGED);
}
@ -169,11 +157,7 @@ package org.gestouch.gestures
{
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
if (setState(GestureState.ENDED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
setState(GestureState.ENDED);
}
else if (state == GestureState.POSSIBLE)
{
@ -191,13 +175,19 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(TransformGestureEvent.GESTURE_TRANSFORM))
{
dispatchEvent(new TransformGestureEvent(TransformGestureEvent.GESTURE_TRANSFORM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y));
}
setState(GestureState.CHANGED);
}
}
}
override protected function resetNotificationProperties():void
{
super.resetNotificationProperties();
_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.Touch;
import org.gestouch.events.ZoomGestureEvent;
import flash.geom.Point;
/**
*
* @eventType org.gestouch.events.ZoomGestureEvent
*/
[Event(name="gestureZoom", type="org.gestouch.events.ZoomGestureEvent")]
/**
*
* @author Pavel fljot
*/
public class ZoomGesture extends Gesture
public class ZoomGesture extends AbstractContinuousGesture
{
public var slop:Number = Gesture.DEFAULT_SLOP;
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
{
if (touchesCount > 2)
@ -89,8 +91,6 @@ package org.gestouch.gestures
return;
var currTransformVector:Point = _touch2.location.subtract(_touch1.location);
var scaleX:Number;
var scaleY:Number;
if (state == GestureState.POSSIBLE)
{
@ -114,12 +114,13 @@ package org.gestouch.gestures
if (lockAspectRatio)
{
scaleX = scaleY = currTransformVector.length / _transformVector.length;
_scaleX *= currTransformVector.length / _transformVector.length;
_scaleY = _scaleX;
}
else
{
scaleX = currTransformVector.x / _transformVector.x;
scaleY = currTransformVector.y / _transformVector.y;
_scaleX *= currTransformVector.x / _transformVector.x;
_scaleY *= currTransformVector.y / _transformVector.y;
}
_transformVector.x = currTransformVector.x;
@ -129,19 +130,11 @@ package org.gestouch.gestures
if (state == GestureState.POSSIBLE)
{
if (setState(GestureState.BEGAN) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM))
{
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.BEGAN,
_location.x, _location.y, _localLocation.x, _localLocation.y, scaleX, scaleY));
}
setState(GestureState.BEGAN);
}
else
{
if (setState(GestureState.CHANGED) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM))
{
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y, scaleX, scaleY));
}
setState(GestureState.CHANGED);
}
}
@ -152,11 +145,7 @@ package org.gestouch.gestures
{
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
if (setState(GestureState.ENDED) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM))
{
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.ENDED,
_location.x, _location.y, _localLocation.x, _localLocation.y, 1, 1));
}
setState(GestureState.ENDED);
}
else if (state == GestureState.POSSIBLE)
{
@ -174,13 +163,17 @@ package org.gestouch.gestures
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
updateLocation();
if (setState(GestureState.CHANGED) && hasEventListener(ZoomGestureEvent.GESTURE_ZOOM))
{
dispatchEvent(new ZoomGestureEvent(ZoomGestureEvent.GESTURE_ZOOM, false, false, GestureState.CHANGED,
_location.x, _location.y, _localLocation.x, _localLocation.y, 1, 1));
}
setState(GestureState.CHANGED);
}
}
}
override protected function resetNotificationProperties():void
{
super.resetNotificationProperties();
_scaleX = _scaleY = 1;
}
}
}

View file

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