package org.andengine.input.touch.detector; import org.andengine.engine.handler.IUpdateHandler; import org.andengine.engine.handler.timer.ITimerCallback; import org.andengine.engine.handler.timer.TimerHandler; import org.andengine.entity.scene.Scene; import org.andengine.input.touch.TouchEvent; import android.speech.tts.TextToSpeech.Engine; import android.view.MotionEvent; /** * Note: Needs to be registered as an {@link IUpdateHandler} to the {@link Engine} or {@link Scene} to work properly. * * (c) 2010 Nicolas Gramlich * (c) 2011 Zynga Inc. * * @author Nicolas Gramlich * @author Greg Haynes * @since 20:49:25 - 23.08.2010 */ public class ContinuousHoldDetector extends HoldDetector implements IUpdateHandler { // =========================================================== // Constants // =========================================================== private static final float TIME_BETWEEN_UPDATES_DEFAULT = 0.1f; // =========================================================== // Fields // =========================================================== private final TimerHandler mTimerHandler; // =========================================================== // Constructors // =========================================================== public ContinuousHoldDetector(final IHoldDetectorListener pHoldDetectorListener) { this(HoldDetector.TRIGGER_HOLD_MINIMUM_MILLISECONDS_DEFAULT, HoldDetector.TRIGGER_HOLD_MAXIMUM_DISTANCE_DEFAULT, ContinuousHoldDetector.TIME_BETWEEN_UPDATES_DEFAULT, pHoldDetectorListener); } public ContinuousHoldDetector(final long pTriggerHoldMinimumMilliseconds, final float pTriggerHoldMaximumDistance, final float pTimeBetweenUpdates, final IHoldDetectorListener pHoldDetectorListener) { super(pTriggerHoldMinimumMilliseconds, pTriggerHoldMaximumDistance, pHoldDetectorListener); this.mTimerHandler = new TimerHandler(pTimeBetweenUpdates, true, new ITimerCallback() { @Override public void onTimePassed(final TimerHandler pTimerHandler) { ContinuousHoldDetector.this.fireListener(); } }); } // =========================================================== // Getter & Setter // =========================================================== // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @Override public void onUpdate(final float pSecondsElapsed) { this.mTimerHandler.onUpdate(pSecondsElapsed); } /** * When {@link ContinuousHoldDetector#isHolding()} this method will call through to {@link IHoldDetectorListener#onHoldFinished(HoldDetector, long, int, float, float)}. */ @Override public void reset() { super.reset(); this.mTimerHandler.reset(); } @Override public boolean onManagedTouchEvent(final TouchEvent pSceneTouchEvent) { final MotionEvent motionEvent = pSceneTouchEvent.getMotionEvent(); switch(pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: if(this.mPointerID == TouchEvent.INVALID_POINTER_ID) { this.prepareHold(pSceneTouchEvent); return true; } else { return false; } case TouchEvent.ACTION_MOVE: { if(this.mPointerID == pSceneTouchEvent.getPointerID()) { this.mHoldX = pSceneTouchEvent.getX(); this.mHoldY = pSceneTouchEvent.getY(); this.mMaximumDistanceExceeded = this.mMaximumDistanceExceeded || Math.abs(this.mDownX - motionEvent.getX()) > this.mTriggerHoldMaximumDistance || Math.abs(this.mDownY - motionEvent.getY()) > this.mTriggerHoldMaximumDistance; return true; } else { return false; } } case TouchEvent.ACTION_UP: case TouchEvent.ACTION_CANCEL: { if(this.mPointerID == pSceneTouchEvent.getPointerID()) { this.mHoldX = pSceneTouchEvent.getX(); this.mHoldY = pSceneTouchEvent.getY(); if(this.mTriggering) { this.triggerOnHoldFinished(motionEvent.getEventTime() - this.mDownTimeMilliseconds); } this.mPointerID = TouchEvent.INVALID_POINTER_ID; return true; } else { return false; } } default: return false; } } @Override protected void prepareHold(final TouchEvent pSceneTouchEvent) { super.prepareHold(pSceneTouchEvent); this.mTimerHandler.reset(); } // =========================================================== // Methods // =========================================================== void fireListener() { if(this.mPointerID != TouchEvent.INVALID_POINTER_ID) { final long holdTimeMilliseconds = System.currentTimeMillis() - this.mDownTimeMilliseconds; if(holdTimeMilliseconds >= this.mTriggerHoldMinimumMilliseconds) { if(this.mTriggering) { this.triggerOnHold(holdTimeMilliseconds); } else if(!this.mMaximumDistanceExceeded) { this.triggerOnHoldStarted(); } } } } // =========================================================== // Inner and Anonymous Classes // =========================================================== }