All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.org.gestouch.gestures.TapGesture.as Maven / Gradle / Ivy

package org.gestouch.gestures
{
	import flash.geom.Point;

	import org.gestouch.core.gestouch_internal;
	import org.gestouch.core.GestureState;
	import org.gestouch.core.Touch;

	import flash.events.TimerEvent;
	import flash.utils.Timer;

	use namespace gestouch_internal;

	/**
	 *
	 * @author Pavel fljot
	 */
	public class TapGesture extends AbstractDiscreteGesture
	{
		protected var _timer : Timer;
		protected var _numTouchesRequiredReached : Boolean;
		protected var _tapCounter : uint = 0;// iOS has 45px for 132 dpi screen
		protected var _touchBeginLocations : Vector. = new Vector.();
		public var numTouchesRequired : uint = 1;
		public var numTapsRequired : uint = 1;
		public var slop : Number = Gesture.DEFAULT_SLOP << 2;
		public var maxTapDelay : uint = 400;
		public var maxTapDuration : uint = 1500;
		public var maxTapDistance : Number = Gesture.DEFAULT_SLOP << 2;

		public function TapGesture( target : Object = null )
		{
			super( target );
		}

		// --------------------------------------------------------------------------
		//
		// Public methods
		//
		// --------------------------------------------------------------------------
		override public function reflect() : Class
		{
			return TapGesture;
		}

		override public function reset() : void
		{
			_numTouchesRequiredReached = false;
			_tapCounter = 0;
			_timer.reset();
			_touchBeginLocations.length = 0;

			super.reset();
		}

		override protected function preinit() : void
		{
			super.preinit();

			_timer = new Timer( maxTapDelay, 1 );
			_timer.addEventListener( TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler );
		}

		// --------------------------------------------------------------------------
		//
		// Protected methods
		//
		// --------------------------------------------------------------------------

		override protected function onTouchBegin( touch : Touch ) : void
		{
			if( touchesCount > numTouchesRequired )
			{
				failOrIgnoreTouch( touch );
				return;
			}

			if( touchesCount == 1 )
			{
				_timer.reset();
				_timer.delay = maxTapDuration;
				_timer.start();
			}

			if( numTapsRequired > 1 )
			{
				if( _tapCounter == 0 )
				{
					// Save touch begin locations to check
					_touchBeginLocations.push( touch.location );
				}
				else
				{
					// Quite a dirty check, but should work in most cases
					var found : Boolean = false;
					for each( var loc : Point in _touchBeginLocations )
					{
						// current touch should be near any previous one
						if( Point.distance( touch.location, loc ) <= maxTapDistance )
						{
							found = true;
							break;
						}
					}

					if( !found )
					{
						setState( GestureState.FAILED );
						return;
					}
				}
			}

			if( touchesCount == numTouchesRequired )
			{
				_numTouchesRequiredReached = true;
				updateLocation();
			}
		}

		override protected function onTouchMove( touch : Touch ) : void
		{
			if( slop >= 0 && touch.locationOffset.length > slop )
			{
				setState( GestureState.FAILED );
			}
		}

		override protected function onTouchEnd( touch : Touch ) : void
		{
			if( !_numTouchesRequiredReached )
			{
				setState( GestureState.FAILED );
			}
			else if( touchesCount == 0 )
			{
				// reset flag for the next "full press" cycle
				_numTouchesRequiredReached = false;

				_tapCounter++;
				_timer.reset();

				if( _tapCounter == numTapsRequired )
				{
					setState( GestureState.RECOGNIZED );
				}
				else
				{
					_timer.delay = maxTapDelay;
					_timer.start();
				}
			}
		}

		protected function timer_timerCompleteHandler( event : TimerEvent ) : void
		{
			if( state == GestureState.POSSIBLE )
			{
				setState( GestureState.FAILED );
			}
		}

		// --------------------------------------------------------------------------
		//
		// Event handlers
		//
		// --------------------------------------------------------------------------

		override gestouch_internal function canPreventGesture( preventedGesture : Gesture ) : Boolean
		{
			if( preventedGesture is TapGesture && (preventedGesture as TapGesture).numTapsRequired > this.numTapsRequired )
			{
				return false;
			}
			return true;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy