Moved input logic out to separate classes

This commit is contained in:
Pavel fljot 2012-02-03 15:57:11 +02:00
parent ad767a4937
commit 6d8b733d51
17 changed files with 468 additions and 420 deletions

View file

@ -1,18 +1,13 @@
package org.gestouch.core
{
import flash.events.EventPhase;
import org.gestouch.events.MouseTouchEvent;
import org.gestouch.gestures.Gesture;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.utils.Dictionary;
/**
* @author Pavel fljot
*/
@ -22,7 +17,8 @@ package org.gestouch.core
private static var _allowInstantiation:Boolean;
protected const _touchesManager:ITouchesManager = TouchesManager.getInstance();
protected var _stage:Stage;
protected const _frameTickerShape:Shape = new Shape();
protected var _inputAdapters:Vector.<IInputAdapter> = new Vector.<IInputAdapter>();
protected var _gestures:Vector.<Gesture> = new Vector.<Gesture>();
protected var _gesturesForTouchMap:Array = [];
protected var _gesturesForTargetMap:Dictionary = new Dictionary(true);
@ -40,6 +36,12 @@ package org.gestouch.core
}
public function get inputAdapters():Vector.<IInputAdapter>
{
return _inputAdapters.concat();
}
public static function setImplementation(value:IGesturesManager):void
{
if (!value)
@ -88,15 +90,6 @@ package org.gestouch.core
targetGestures.push(gesture);
_gestures.push(gesture);
if (!_stage && gesture.target.stage)
{
installStage(gesture.target.stage);
}
else
{
gesture.target.addEventListener(Event.ADDED_TO_STAGE, gestureTarget_addedToStageHandler);
}
}
@ -115,7 +108,6 @@ package org.gestouch.core
if (targetGestures.length == 0)
{
delete _gesturesForTargetMap[target];
gesture.target.removeEventListener(Event.ADDED_TO_STAGE, gestureTarget_addedToStageHandler);
}
var index:int = _gestures.indexOf(gesture);
@ -134,7 +126,7 @@ package org.gestouch.core
{
_dirtyGestures.push(gesture);
_dirtyGesturesLength++;
_stage.addEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
_frameTickerShape.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
}
@ -168,6 +160,38 @@ package org.gestouch.core
}
public function addInputAdapter(inputAdapter:IInputAdapter):void
{
if (!inputAdapter)
{
throw new Error("Input adapter must be non null.");
}
if (_inputAdapters.indexOf(inputAdapter) > -1)
return;//TODO: throw Error or ignore?
_inputAdapters.push(inputAdapter);
inputAdapter.touchesManager = _touchesManager;
inputAdapter.gesturesManager = this;
}
public function removeInputAdapter(inputAdapter:IInputAdapter):void
{
if (!inputAdapter)
{
throw new Error("Input adapter must be non null.");
}
var index:int = _inputAdapters.indexOf(inputAdapter);
if (index == -1)
{
throw new Error("This input manager is not registered.");
}
_inputAdapters.splice(index, 1);
}
//--------------------------------------------------------------------------
@ -176,55 +200,6 @@ package org.gestouch.core
//
//--------------------------------------------------------------------------
protected function installStage(stage:Stage):void
{
_touchesManager.init(stage);
_stage = stage;
if (Multitouch.supportsTouchEvents)
{
stage.addEventListener(TouchEvent.TOUCH_BEGIN, touchBeginHandler, true);
}
else
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, true);
}
}
protected function installStageListeners():void
{
//TODO: maximum priority to prevent event hijacking?
if (Multitouch.supportsTouchEvents)
{
_stage.addEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, true);
_stage.addEventListener(TouchEvent.TOUCH_END, touchEndHandler, true);
_stage.addEventListener(TouchEvent.TOUCH_END, touchEndHandler);//to catch event out of stage
}
else
{
_stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);//to catch event out of stage
}
}
protected function uninstallStageListeners():void
{
if (Multitouch.supportsTouchEvents)
{
_stage.removeEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, true);
_stage.removeEventListener(TouchEvent.TOUCH_END, touchEndHandler, true);
}
else
{
_stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
_stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
}
}
protected function resetDirtyGestures():void
{
for each (var gesture:Gesture in _dirtyGestures)
@ -234,45 +209,17 @@ package org.gestouch.core
_dirtyGestures.length = 0;
_dirtyGesturesLength = 0;
_dirtyGesturesMap = new Dictionary(true);
_stage.removeEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
_frameTickerShape.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
protected function gestureTarget_addedToStageHandler(event:Event):void
{
var target:DisplayObject = event.target as DisplayObject;
target.removeEventListener(Event.ADDED_TO_STAGE, gestureTarget_addedToStageHandler);
if (!_stage)
{
installStage(target.stage);
}
var depth:uint = 1;//NB! not using 0-based for sorting function
var targetParent:DisplayObjectContainer = target.parent;
while (targetParent)
{
depth++;
targetParent = targetParent.parent;
}
}
protected function touchBeginHandler(event:TouchEvent):void
gestouch_internal function onTouchBegin(touch:Touch):void
{
if (_dirtyGesturesLength > 0)
{
resetDirtyGestures();
}
var touch:Touch = _touchesManager.getTouch(event.touchPointID);
var gesture:Gesture;
var i:uint;
@ -323,33 +270,23 @@ package org.gestouch.core
// Check for state because previous (i+1) gesture may already abort current (i) one
if (gesture.state != GestureState.FAILED)
{
gesture.gestouch_internal::touchBeginHandler(touch, event);
gesture.gestouch_internal::touchBeginHandler(touch);
}
else
{
gesturesForTouch.splice(i, 1);
}
}
installStageListeners();
}
protected function mouseDownHandler(event:MouseEvent):void
{
touchBeginHandler(MouseTouchEvent.createMouseTouchEvent(event));
}
protected function touchMoveHandler(event:TouchEvent):void
gestouch_internal function onTouchMove(touch:Touch):void
{
if (_dirtyGesturesLength > 0)
{
resetDirtyGestures();
}
var touch:Touch = _touchesManager.getTouch(event.touchPointID);
var gesturesForTouch:Vector.<Gesture> = _gesturesForTouchMap[touch.id] as Vector.<Gesture>;
var gesture:Gesture;
var i:int = gesturesForTouch.length;
@ -359,7 +296,7 @@ package org.gestouch.core
if (gesture.state != GestureState.FAILED && gesture.isTrackingTouch(touch.id))
{
gesture.gestouch_internal::touchMoveHandler(touch, event);
gesture.gestouch_internal::touchMoveHandler(touch);
}
else
{
@ -370,26 +307,13 @@ package org.gestouch.core
}
protected function mouseMoveHandler(event:MouseEvent):void
gestouch_internal function onTouchEnd(touch:Touch):void
{
//TODO: copy code from touchMoveHandler: save 1 function call?
touchMoveHandler(MouseTouchEvent.createMouseTouchEvent(event));
}
protected function touchEndHandler(event:TouchEvent):void
{
if (event.eventPhase == EventPhase.BUBBLING_PHASE)
return;
if (_dirtyGesturesLength > 0)
{
resetDirtyGestures();
}
var touch:Touch = _touchesManager.getTouch(event.touchPointID);
var gesturesForTouch:Vector.<Gesture> = _gesturesForTouchMap[touch.id] as Vector.<Gesture>;
var gesture:Gesture;
var i:int = gesturesForTouch.length;
@ -397,29 +321,29 @@ package org.gestouch.core
{
gesture = gesturesForTouch[i] as Gesture;
// TODO: handle cancelled touch:
// if (event.hasOwnProperty("isTouchPointCanceled") && event["isTouchPointCanceled"] && ...
if (gesture.state != GestureState.FAILED && gesture.isTrackingTouch(touch.id))
{
gesture.gestouch_internal::touchEndHandler(touch, event);
gesture.gestouch_internal::touchEndHandler(touch);
}
}
if (_touchesManager.activeTouchesCount == 0)
{
uninstallStageListeners();
}
}
protected function mouseUpHandler(event:MouseEvent):void
gestouch_internal function onTouchCancel(touch:Touch):void
{
touchEndHandler(MouseTouchEvent.createMouseTouchEvent(event));
//TODO
}
private function stage_enterFrameHandler(event:Event):void
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
private function enterFrameHandler(event:Event):void
{
resetDirtyGestures();
}

View file

@ -6,6 +6,9 @@ package org.gestouch.core
*/
public interface IGesturesManager
{
function addInputAdapter(inputAdapter:IInputAdapter):void;
function removeInputAdapter(inputAdapter:IInputAdapter):void;
function addGesture(gesture:Gesture):void;
function removeGesture(gesture:Gesture):void;

View file

@ -0,0 +1,11 @@
package org.gestouch.core
{
/**
* @author Pavel fljot
*/
public interface IInputAdapter
{
function set touchesManager(value:ITouchesManager):void;
function set gesturesManager(value:IGesturesManager):void;
}
}

View file

@ -1,6 +1,5 @@
package org.gestouch.core
{
import flash.display.Stage;
/**
* @author Pavel fljot
*/
@ -8,7 +7,10 @@ package org.gestouch.core
{
function get activeTouchesCount():uint;
function init(stage:Stage):void;
function createTouch():Touch;
function addTouch(touch:Touch):Touch;
function removeTouch(touch:Touch):Touch;
function getTouch(touchPointID:int):Touch;
function hasTouch(touchPointID:int):Boolean;
}
}

View file

@ -1,13 +1,7 @@
package org.gestouch.core
{
import flash.events.EventPhase;
import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.utils.getTimer;
/**
* @author Pavel fljot
*/
@ -16,7 +10,6 @@ package org.gestouch.core
private static var _instance:ITouchesManager;
private static var _allowInstantiation:Boolean;
protected var _stage:Stage;
protected var _touchesMap:Object = {};
{
@ -67,25 +60,44 @@ package org.gestouch.core
}
public function init(stage:Stage):void
public function createTouch():Touch
{
_stage = stage;
if (Multitouch.supportsTouchEvents)
//TODO: pool
return new Touch();
}
public function addTouch(touch:Touch):Touch
{
if (_touchesMap.hasOwnProperty(touch.id))
{
stage.addEventListener(TouchEvent.TOUCH_BEGIN, stage_touchBeginHandler, true, int.MAX_VALUE);
stage.addEventListener(TouchEvent.TOUCH_MOVE, stage_touchMoveHandler, true, int.MAX_VALUE);
stage.addEventListener(TouchEvent.TOUCH_END, stage_touchEndHandler, true, int.MAX_VALUE);
// if mouse/finger leaves the stage we will get only AT_TARGET phase
stage.addEventListener(TouchEvent.TOUCH_END, stage_touchEndHandler, false, int.MAX_VALUE);
throw new Error("Touch with id " + touch.id + " is already registered.");
}
else
_touchesMap[touch.id] = touch;
_activeTouchesCount++;
return touch;
}
public function removeTouch(touch:Touch):Touch
{
if (!_touchesMap.hasOwnProperty(touch.id))
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mouseDownHandler, true, int.MAX_VALUE);
stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler, true, int.MAX_VALUE);
stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler, true, int.MAX_VALUE);
// if mouse/finger leaves the stage we will get only AT_TARGET phase
stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler, false, int.MAX_VALUE);
throw new Error("Touch with id " + touch.id + " is not registered.");
}
delete _touchesMap[touch.id];
_activeTouchesCount--;
return touch;
}
public function hasTouch(touchPointID:int):Boolean
{
return _touchesMap.hasOwnProperty(touchPointID);
}
@ -94,119 +106,5 @@ package org.gestouch.core
var touch:Touch = _touchesMap[touchPointID] as Touch;
return touch ? touch.clone() : null;
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
protected function stage_touchBeginHandler(event:TouchEvent):void
{
var touch:Touch = new Touch(event.touchPointID);
_touchesMap[event.touchPointID] = touch;
touch.target = event.target as InteractiveObject;
touch.x = event.stageX;
touch.y = event.stageY;
touch.sizeX = event.sizeX;
touch.sizeY = event.sizeY;
touch.pressure = event.pressure;
touch.time = getTimer();//TODO: conditional compilation + event.timestamp
_activeTouchesCount++;
}
protected function stage_mouseDownHandler(event:MouseEvent):void
{
var touch:Touch = new Touch(0);
_touchesMap[0] = touch;
touch.target = event.target as InteractiveObject;
touch.x = event.stageX;
touch.y = event.stageY;
touch.sizeX = NaN;
touch.sizeY = NaN;
touch.pressure = NaN;
touch.time = getTimer();//TODO: conditional compilation + event.timestamp
_activeTouchesCount++;
}
protected function stage_touchMoveHandler(event:TouchEvent):void
{
var touch:Touch = _touchesMap[event.touchPointID] as Touch;
if (!touch)
{
// some fake event?
return;
}
touch.x = event.stageX;
touch.y = event.stageY;
touch.sizeX = event.sizeX;
touch.sizeY = event.sizeY;
touch.pressure = event.pressure;
touch.time = getTimer();//TODO: conditional compilation + event.timestamp
}
protected function stage_mouseMoveHandler(event:MouseEvent):void
{
var touch:Touch = _touchesMap[0] as Touch;
if (!touch)
{
// some fake event?
return;
}
touch.x = event.stageX;
touch.y = event.stageY;
touch.time = getTimer();//TODO: conditional compilation + event.timestamp
}
protected function stage_touchEndHandler(event:TouchEvent):void
{
var touch:Touch = _touchesMap[event.touchPointID] as Touch;
if (!touch)
{
// some fake event?
return;
}
touch.x = event.stageX;
touch.y = event.stageY;
touch.sizeX = event.sizeX;
touch.sizeY = event.sizeY;
touch.pressure = event.pressure;
touch.time = getTimer();//TODO: conditional compilation + event.timestamp
_activeTouchesCount--;
}
protected function stage_mouseUpHandler(event:MouseEvent):void
{
if (event.eventPhase == EventPhase.BUBBLING_PHASE)
return;
var touch:Touch = _touchesMap[0] as Touch;
if (!touch)
{
// some fake event?
return;
}
touch.x = event.stageX;
touch.y = event.stageY;
touch.time = getTimer();//TODO: conditional compilation + event.timestamp
_activeTouchesCount--;
}
}
}

View file

@ -1,99 +0,0 @@
package org.gestouch.events
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TouchEvent;
/**
* @author Pavel fljot
*/
public class MouseTouchEvent extends TouchEvent
{
private static const typeMap:Object = {};
protected var _mouseEvent:MouseEvent;
{
MouseTouchEvent.typeMap[MouseEvent.MOUSE_DOWN] = TouchEvent.TOUCH_BEGIN;
MouseTouchEvent.typeMap[MouseEvent.MOUSE_MOVE] = TouchEvent.TOUCH_MOVE;
MouseTouchEvent.typeMap[MouseEvent.MOUSE_UP] = TouchEvent.TOUCH_END;
}
public function MouseTouchEvent(type:String, event:MouseEvent)
{
super(type, event.bubbles, event.cancelable, 0, true, event.localX, event.localY, NaN, NaN, NaN, event.relatedObject, event.ctrlKey, event.altKey, event.shiftKey);
_mouseEvent = event;
}
public static function createMouseTouchEvent(event:MouseEvent):MouseTouchEvent
{
var type:String = MouseTouchEvent.typeMap[event.type];
if (!type)
{
throw new Error("No match found for MouseEvent of type \"" + event.type + "\"");
}
return new MouseTouchEvent(type, event);
}
override public function get target():Object
{
return _mouseEvent.target;
}
override public function get currentTarget():Object
{
return _mouseEvent.currentTarget;
}
override public function get eventPhase():uint
{
return _mouseEvent.eventPhase;
}
override public function get stageX():Number
{
return _mouseEvent.stageX;
}
override public function get stageY():Number
{
return _mouseEvent.stageY;
}
override public function stopPropagation():void
{
super.stopPropagation();
_mouseEvent.stopPropagation();
}
override public function stopImmediatePropagation():void
{
super.stopImmediatePropagation();
_mouseEvent.stopImmediatePropagation();
}
override public function clone():Event
{
return super.clone();
}
override public function toString():String
{
return super.toString() + " *faked";
}
}
}

View file

@ -273,7 +273,7 @@ package org.gestouch.gestures
/**
* TODO: clarify usage. For now it's supported to call this method in onTouchBegin with return.
*/
protected function ignoreTouch(touch:Touch, event:TouchEvent):void
protected function ignoreTouch(touch:Touch):void
{
if (_touchesMap.hasOwnProperty(touch.id))
{
@ -285,33 +285,27 @@ package org.gestouch.gestures
[Abstract]
/**
* Internal method, used by GesturesManager.
*
* <p><b>NB!</b> This is abstract method and must be overridden.</p>
*/
protected function onTouchBegin(touch:Touch, event:TouchEvent):void
protected function onTouchBegin(touch:Touch):void
{
}
[Abstract]
/**
* Internal method, used by GesturesManager.
*
* <p><b>NB!</b> This is abstract method and must be overridden.</p>
*/
protected function onTouchMove(touch:Touch, event:TouchEvent):void
protected function onTouchMove(touch:Touch):void
{
}
[Abstract]
/**
* Internal method, used by GesturesManager.
*
* <p><b>NB!</b> This is abstract method and must be overridden.</p>
*/
protected function onTouchEnd(touch:Touch, event:TouchEvent):void
protected function onTouchEnd(touch:Touch):void
{
}
@ -401,28 +395,28 @@ package org.gestouch.gestures
//
//--------------------------------------------------------------------------
gestouch_internal function touchBeginHandler(touch:Touch, event:TouchEvent):void
gestouch_internal function touchBeginHandler(touch:Touch):void
{
_touchesMap[touch.id] = touch;
_touchesCount++;
onTouchBegin(touch, event);
onTouchBegin(touch);
}
gestouch_internal function touchMoveHandler(touch:Touch, event:TouchEvent):void
gestouch_internal function touchMoveHandler(touch:Touch):void
{
_touchesMap[touch.id] = touch;
onTouchMove(touch, event);
onTouchMove(touch);
}
gestouch_internal function touchEndHandler(touch:Touch, event:TouchEvent):void
gestouch_internal function touchEndHandler(touch:Touch):void
{
delete _touchesMap[touch.id];
_touchesCount--;
onTouchEnd(touch, event);
onTouchEnd(touch);
}
}
}

View file

@ -7,7 +7,6 @@ package org.gestouch.gestures
import flash.display.InteractiveObject;
import flash.events.GesturePhase;
import flash.events.TimerEvent;
import flash.events.TouchEvent;
import flash.utils.Timer;
@ -82,13 +81,13 @@ package org.gestouch.gestures
}
override protected function onTouchBegin(touch:Touch, event:TouchEvent):void
override protected function onTouchBegin(touch:Touch):void
{
if (touchesCount > numTouchesRequired)
{
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
ignoreTouch(touch, event);
ignoreTouch(touch);
}
else
{
@ -117,7 +116,7 @@ package org.gestouch.gestures
}
override protected function onTouchMove(touch:Touch, event:TouchEvent):void
override protected function onTouchMove(touch:Touch):void
{
if (state == GestureState.POSSIBLE && slop > 0)
{
@ -141,7 +140,7 @@ package org.gestouch.gestures
}
override protected function onTouchEnd(touch:Touch, event:TouchEvent):void
override protected function onTouchEnd(touch:Touch):void
{
//TODO: check proper condition (behavior) on iOS native
if (_numTouchesRequiredReached)

View file

@ -1,13 +1,11 @@
package org.gestouch.gestures
{
import org.gestouch.events.PanGestureEvent;
import org.gestouch.core.GestureState;
import org.gestouch.core.Touch;
import org.gestouch.events.ZoomGestureEvent;
import org.gestouch.events.PanGestureEvent;
import flash.display.InteractiveObject;
import flash.events.GesturePhase;
import flash.events.TouchEvent;
import flash.geom.Point;
[Event(name="gesturePan", type="org.gestouch.events.PanGestureEvent")]
@ -107,12 +105,12 @@ package org.gestouch.gestures
//
// --------------------------------------------------------------------------
override protected function onTouchBegin(touch:Touch, event:TouchEvent):void
override protected function onTouchBegin(touch:Touch):void
{
if (touchesCount > maxNumTouchesRequired)
{
//TODO
ignoreTouch(touch, event);
ignoreTouch(touch);
return;
}
@ -126,7 +124,7 @@ package org.gestouch.gestures
}
override protected function onTouchMove(touch:Touch, event:TouchEvent):void
override protected function onTouchMove(touch:Touch):void
{
if (touchesCount < minNumTouchesRequired)
return;
@ -180,7 +178,7 @@ package org.gestouch.gestures
}
override protected function onTouchEnd(touch:Touch, event:TouchEvent):void
override protected function onTouchEnd(touch:Touch):void
{
if (touchesCount < minNumTouchesRequired)
{

View file

@ -7,7 +7,6 @@ package org.gestouch.gestures
import flash.display.InteractiveObject;
import flash.events.GesturePhase;
import flash.events.TouchEvent;
import flash.geom.Point;
[Event(name="gestureRotate", type="org.gestouch.events.RotateGestureEvent")]
@ -66,12 +65,12 @@ package org.gestouch.gestures
//
// --------------------------------------------------------------------------
override protected function onTouchBegin(touch:Touch, event:TouchEvent):void
override protected function onTouchBegin(touch:Touch):void
{
if (touchesCount > 2)
{
//TODO
ignoreTouch(touch, event);
ignoreTouch(touch);
return;
}
@ -94,7 +93,7 @@ package org.gestouch.gestures
}
override protected function onTouchMove(touch:Touch, event:TouchEvent):void
override protected function onTouchMove(touch:Touch):void
{
if (touch.id == _firstTouch.id)
{
@ -155,7 +154,7 @@ package org.gestouch.gestures
}
override protected function onTouchEnd(touch:Touch, event:TouchEvent):void
override protected function onTouchEnd(touch:Touch):void
{
if (touchesCount == 0)
{

View file

@ -6,7 +6,6 @@ package org.gestouch.gestures
import flash.display.InteractiveObject;
import flash.events.GesturePhase;
import flash.events.TouchEvent;
import flash.geom.Point;
import flash.system.Capabilities;
@ -69,7 +68,7 @@ package org.gestouch.gestures
//
// --------------------------------------------------------------------------
override protected function onTouchBegin(touch:Touch, event:TouchEvent):void
override protected function onTouchBegin(touch:Touch):void
{
if (touchesCount > numTouchesRequired)
{
@ -88,7 +87,7 @@ package org.gestouch.gestures
}
override protected function onTouchMove(touch:Touch, event:TouchEvent):void
override protected function onTouchMove(touch:Touch):void
{
if (touchesCount < numTouchesRequired)
return;
@ -185,7 +184,7 @@ package org.gestouch.gestures
}
override protected function onTouchEnd(touch:Touch, event:TouchEvent):void
override protected function onTouchEnd(touch:Touch):void
{
setState(GestureState.FAILED);
}

View file

@ -7,7 +7,6 @@ package org.gestouch.gestures
import flash.display.InteractiveObject;
import flash.events.GesturePhase;
import flash.events.TimerEvent;
import flash.events.TouchEvent;
import flash.utils.Timer;
@ -91,7 +90,7 @@ package org.gestouch.gestures
}
override protected function onTouchBegin(touch:Touch, event:TouchEvent):void
override protected function onTouchBegin(touch:Touch):void
{
if (touchesCount > numTouchesRequired)
{
@ -118,7 +117,7 @@ package org.gestouch.gestures
}
override protected function onTouchMove(touch:Touch, event:TouchEvent):void
override protected function onTouchMove(touch:Touch):void
{
if (slop >= 0)
{
@ -133,7 +132,7 @@ package org.gestouch.gestures
}
override protected function onTouchEnd(touch:Touch, event:TouchEvent):void
override protected function onTouchEnd(touch:Touch):void
{
if (!_numTouchesRequiredReached)
{

View file

@ -6,7 +6,6 @@ package org.gestouch.gestures
import flash.display.InteractiveObject;
import flash.events.GesturePhase;
import flash.events.TouchEvent;
import flash.geom.Point;
[Event(name="gestureZoom", type="org.gestouch.events.ZoomGestureEvent")]
@ -66,12 +65,12 @@ package org.gestouch.gestures
//
// --------------------------------------------------------------------------
override protected function onTouchBegin(touch:Touch, event:TouchEvent):void
override protected function onTouchBegin(touch:Touch):void
{
if (touchesCount > 2)
{
//TODO
ignoreTouch(touch, event);
ignoreTouch(touch);
return;
}
@ -94,7 +93,7 @@ package org.gestouch.gestures
}
override protected function onTouchMove(touch:Touch, event:TouchEvent):void
override protected function onTouchMove(touch:Touch):void
{
if (touch.id == _firstTouch.id)
{
@ -165,7 +164,7 @@ package org.gestouch.gestures
}
override protected function onTouchEnd(touch:Touch, event:TouchEvent):void
override protected function onTouchEnd(touch:Touch):void
{
if (touchesCount == 0)
{

View file

@ -0,0 +1,37 @@
package org.gestouch.input
{
import org.gestouch.core.IGesturesManager;
import org.gestouch.core.IInputAdapter;
import org.gestouch.core.ITouchesManager;
/**
* @author Pavel fljot
*/
public class AbstractInputAdapter implements IInputAdapter
{
protected var _touchesManager:ITouchesManager;
protected var _gesturesManager:IGesturesManager;
public function AbstractInputAdapter()
{
if (Object(this).constructor == AbstractInputAdapter)
{
throw new Error("This is abstract class and should not be directly instantiated.");
}
}
public function set touchesManager(value:ITouchesManager):void
{
_touchesManager = value;
}
public function set gesturesManager(value:IGesturesManager):void
{
_gesturesManager = value;
}
}
}

View file

@ -0,0 +1,121 @@
package org.gestouch.input
{
import org.gestouch.core.Touch;
import org.gestouch.core.gestouch_internal;
import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.events.EventPhase;
import flash.events.MouseEvent;
import flash.utils.getTimer;
/**
* @author Pavel fljot
*/
public class MouseInputAdapter extends AbstractInputAdapter
{
private static const PRIMARY_TOUCH_POINT_ID:uint = 0;
protected var _stage:Stage;
public function MouseInputAdapter(stage:Stage)
{
super();
if (!stage)
{
throw new Error("Stage must be not null.");
}
_stage = stage;
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, true);
}
protected function installStageListeners():void
{
// Maximum priority to prevent event hijacking
_stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true, int.MAX_VALUE);
_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true, int.MAX_VALUE);
// To catch event out of stage
_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, int.MAX_VALUE);
}
protected function uninstallStageListeners():void
{
_stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
_stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
_stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
protected function mouseDownHandler(event:MouseEvent):void
{
// Way to prevent MouseEvent/TouchEvent collisions.
// Also helps to ignore possible fake events.
if (_touchesManager.hasTouch(PRIMARY_TOUCH_POINT_ID))
return;
installStageListeners();
var touch:Touch = _touchesManager.createTouch();
touch.id = 0;
touch.target = event.target as InteractiveObject;
touch.x = event.stageX;
touch.y = event.stageY;
touch.time = getTimer();
_touchesManager.addTouch(touch);
_gesturesManager.gestouch_internal::onTouchBegin(touch);
}
protected function mouseMoveHandler(event:MouseEvent):void
{
// Way to prevent MouseEvent/TouchEvent collisions.
// Also helps to ignore possible fake events.
if (!_touchesManager.hasTouch(PRIMARY_TOUCH_POINT_ID))
return;
var touch:Touch = _touchesManager.getTouch(PRIMARY_TOUCH_POINT_ID);
touch.x = event.stageX;
touch.y = event.stageY;
//TODO: time update vs begin time
_gesturesManager.gestouch_internal::onTouchMove(touch);
}
protected function mouseUpHandler(event:MouseEvent):void
{
// If event happens outside of stage it will be with AT_TARGET phase
if (event.eventPhase == EventPhase.BUBBLING_PHASE)
return;
// Way to prevent MouseEvent/TouchEvent collisions.
// Also helps to ignore possible fake events.
if (!_touchesManager.hasTouch(PRIMARY_TOUCH_POINT_ID))
return;
var touch:Touch = _touchesManager.getTouch(PRIMARY_TOUCH_POINT_ID);
touch.x = event.stageX;
touch.y = event.stageY;
//TODO: time update vs begin time
_gesturesManager.gestouch_internal::onTouchEnd(touch);
_touchesManager.removeTouch(touch);
if (_touchesManager.activeTouchesCount == 0)
{
uninstallStageListeners();
}
}
}
}

View file

@ -0,0 +1,17 @@
package org.gestouch.input
{
import org.gestouch.input.AbstractInputAdapter;
/**
* @author Pavel fljot
*/
public class TUIOInputAdapter extends AbstractInputAdapter
{
public function TUIOInputAdapter()
{
super();
//TODO
}
}
}

View file

@ -0,0 +1,147 @@
package org.gestouch.input
{
import org.gestouch.core.Touch;
import org.gestouch.core.gestouch_internal;
import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.events.EventPhase;
import flash.events.TouchEvent;
import flash.utils.getTimer;
/**
* @author Pavel fljot
*/
public class TouchInputAdapter extends AbstractInputAdapter
{
protected var _stage:Stage;
/**
* The hash map of touches instantiated via TouchEvent.
* Used to avoid collisions (double processing) with MouseInputAdapter.
*
* TODO: any better way?
*/
protected var _touchesMap:Object = {};
public function TouchInputAdapter(stage:Stage)
{
super();
if (!stage)
{
throw new Error("Stage must be not null.");
}
_stage = stage;
stage.addEventListener(TouchEvent.TOUCH_BEGIN, touchBeginHandler, true);
}
protected function installStageListeners():void
{
// Maximum priority to prevent event hijacking
_stage.addEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, true, int.MAX_VALUE);
_stage.addEventListener(TouchEvent.TOUCH_END, touchEndHandler, true, int.MAX_VALUE);
// To catch event out of stage
_stage.addEventListener(TouchEvent.TOUCH_END, touchEndHandler, false, int.MAX_VALUE);
}
protected function uninstallStageListeners():void
{
_stage.removeEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, true);
_stage.removeEventListener(TouchEvent.TOUCH_END, touchEndHandler, true);
_stage.removeEventListener(TouchEvent.TOUCH_END, touchEndHandler);
}
protected function touchBeginHandler(event:TouchEvent):void
{
// Way to prevent MouseEvent/TouchEvent collisions.
// Also helps to ignore possible fake events.
if (_touchesManager.hasTouch(event.touchPointID))
return;
installStageListeners();
var touch:Touch = _touchesManager.createTouch();
touch.id = event.touchPointID;
touch.target = event.target as InteractiveObject;
touch.x = event.stageX;
touch.y = event.stageY;
touch.sizeX = event.sizeX;
touch.sizeY = event.sizeY;
touch.pressure = event.pressure;
//TODO: conditional compilation?
if (event.hasOwnProperty("timestamp"))
{
touch.time = event["timestamp"];
}
else
{
touch.time = getTimer();
}
_touchesManager.addTouch(touch);
_touchesMap[touch.id] = true;
_gesturesManager.gestouch_internal::onTouchBegin(touch);
}
protected function touchMoveHandler(event:TouchEvent):void
{
// Way to prevent MouseEvent/TouchEvent collisions.
// Also helps to ignore possible fake events.
if (!_touchesManager.hasTouch(event.touchPointID) || !_touchesMap.hasOwnProperty(event.touchPointID))
return;
var touch:Touch = _touchesManager.getTouch(event.touchPointID);
touch.x = event.stageX;
touch.y = event.stageY;
touch.sizeX = event.sizeX;
touch.sizeY = event.sizeY;
touch.pressure = event.pressure;
//TODO: time update vs begin time
_gesturesManager.gestouch_internal::onTouchMove(touch);
}
protected function touchEndHandler(event:TouchEvent):void
{
// If event happens outside of stage it will be with AT_TARGET phase
if (event.eventPhase == EventPhase.BUBBLING_PHASE)
return;
// Way to prevent MouseEvent/TouchEvent collisions.
// Also helps to ignore possible fake events.
if (!_touchesManager.hasTouch(event.touchPointID))
return;
var touch:Touch = _touchesManager.getTouch(event.touchPointID);
touch.x = event.stageX;
touch.y = event.stageY;
touch.sizeX = event.sizeX;
touch.sizeY = event.sizeY;
touch.pressure = event.pressure;
//TODO: time update vs begin time
_gesturesManager.gestouch_internal::onTouchEnd(touch);
_touchesManager.removeTouch(touch);
delete _touchesMap[touch.id];
if (_touchesManager.activeTouchesCount == 0)
{
uninstallStageListeners();
}
// TODO: handle cancelled touch:
// if (event.hasOwnProperty("isTouchPointCanceled") && event["isTouchPointCanceled"] && ...
}
}
}