package org.flixel.plugin; import org.flixel.FlxBasic; import org.flixel.FlxG; import org.flixel.FlxGesture; import org.flixel.system.gdx.GdxStage; import com.badlogic.gdx.input.GestureDetector; import com.badlogic.gdx.input.GestureDetector.GestureListener; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; /** * A simple manager for tracking and updating gesture objects. * * @author Ka Wing Chin * @author cyphertext */ public class GestureManager extends FlxBasic implements GestureListener { /** * An array that holds <code>FlxGestures</code> objects. */ protected Array<FlxGesture> _gestures; /** * Internal tracker for long press gesture. */ private boolean afterLongPress = false; /** * Holds the gesture data. */ protected GestureData data; /** * Creates a new <code>GestureManager<code> object. */ public GestureManager() { _gestures = new Array<FlxGesture>(); visible = false; data = new GestureData(); ((GdxStage)FlxG.getStage()).getInput().addProcessor(new GestureDetector(this)); } @Override public void destroy() { super.destroy(); clear(); _gestures = null; data.destroy(); data = null; } /** * Add a <code>FlxGesture</code> object. * * @param Gesture The object that will be added. */ public void add(FlxGesture Gesture) { _gestures.add(Gesture); } /** * Remove a <code>FlxGesture</code> object. * * @param Gesture The object that will be removed. */ public void remove(FlxGesture Gesture) { int index = _gestures.indexOf(Gesture, true); if(index >= 0) _gestures.removeIndex(index); } /** * Remove all gestures from the manager. */ public void clear() { int i = _gestures.size - 1; FlxGesture gesture; while(i >= 0) { gesture = _gestures.get(i--); if(gesture != null) gesture.destroy(); } _gestures.clear(); } /** * Update gestures by gesture type, e.g. <code>FlxGesture.PAN, FlxGesture.DIRECTION_DOWN, etc.</code>. * * @param Gesture The gesture type that needs to be updated. */ private void updateGestures(int Gesture, GestureData Data) { int i = _gestures.size - 1; FlxGesture gesture; while(i >= 0) { gesture = _gestures.get(i--); if(gesture != null) gesture.callback(Gesture, Data); } } @Override public boolean touchDown(float X, float Y, int Pointer, int Button) { data.clear(); data.x = X; data.y = Y; data.pointer = Pointer; data.button = Button; updateGestures(FlxGesture.TOUCH_DOWN, data); return false; } @Override public boolean tap(float X, float Y, int Count, int Button) { if(afterLongPress) afterLongPress = false; else { data.clear(); data.x = X; data.y = Y; data.button = Button; if(Count == 1) updateGestures(FlxGesture.TAP, data); else if(Count == 2) updateGestures(FlxGesture.DOUBLE_TAP, data); } return false; } @Override public boolean longPress(float X, float Y) { data.clear(); data.x = X; data.y = Y; updateGestures(FlxGesture.LONG_PRESS, data); afterLongPress = true; return false; } @Override public boolean fling(float VelocityX, float VelocityY, int Button) { data.clear(); data.velocityX = VelocityX; data.velocityY = VelocityY; data.button = Button; if(Math.abs(VelocityX) > Math.abs(VelocityY)) { if(VelocityX > 0) updateGestures(FlxGesture.DIRECTION_RIGHT, data); else updateGestures(FlxGesture.DIRECTION_LEFT, data); } else { if(VelocityY > 0) updateGestures(FlxGesture.DIRECTION_DOWN, data); else updateGestures(FlxGesture.DIRECTION_UP, data); } return false; } @Override public boolean pan(float X, float Y, float DeltaX, float DeltaY) { data.clear(); data.x = X; data.y = Y; data.deltaX = DeltaX; data.deltaY = DeltaY; updateGestures(FlxGesture.PAN, data); return false; } @Override public boolean panStop(float X, float Y, int Pointer, int Button) { data.clear(); data.x = X; data.y = Y; data.pointer = Pointer; data.button = Button; return false; } @Override public boolean zoom(float OriginalDistance, float CurrentDistance) { data.clear(); data.originalDistance = OriginalDistance; data.currentDistance = CurrentDistance; updateGestures(FlxGesture.ZOOM, data); return false; } @Override public boolean pinch(Vector2 InitialPointer1, Vector2 InitialPointer2, Vector2 Pointer1, Vector2 Pointer2) { data.clear(); data.initialPointer1 = InitialPointer1; data.initialPointer2 = InitialPointer2; data.pointer1 = Pointer1; data.pointer2 = Pointer2; updateGestures(FlxGesture.PINCH, data); return false; } /** * Holds the gesture data */ public class GestureData { /** * The x position where the gesture is performed. */ public float x; /** * The y position where the gesture is performed. */ public float y; /** * The x velocity in seconds. Used by FLING. */ public float velocityX; /** * The y velocity in seconds. Used by FLING. */ public float velocityY; /** * The difference in pixels to the last drag event on x. Used by PAN. */ public float deltaX; /** * The difference in pixels to the last drag event on Y. Used by PAN. */ public float deltaY; /** * The distance between fingers when the gesture started. Used by ZOOM. */ public float originalDistance; /** * The current distance between fingers. Used by ZOOM. */ public float currentDistance; /** * The first initial positions of the two involved fingers. Used by PINCH. */ public Vector2 initialPointer1; /** * The second initial positions of the two involved fingers. Used by PINCH. */ public Vector2 initialPointer2; /** * The first current position of the two involved fingers. Used by PINCH. */ public Vector2 pointer1; /** * The second current position of the two involved fingers. Used by PINCH. */ public Vector2 pointer2; /** * Tracks the pointer which is used. */ public int pointer; /** * Tracks the mouse button which is used. */ public int button; /** * Creates a new <code>GestureData</code> object. */ public GestureData() { initialPointer1 = new Vector2(); initialPointer2 = new Vector2(); pointer1 = new Vector2(); pointer2 = new Vector2(); } /** * Reset the values. */ public void clear() { x = y = velocityX = velocityY = deltaX = deltaY = originalDistance = currentDistance = 0; pointer = 0; button = 0; initialPointer1.set(0, 0); initialPointer2.set(0, 0); pointer1.set(0, 0); pointer2.set(0, 0); } /** * Free the memory. */ public void destroy() { initialPointer1 = null; initialPointer2 = null; pointer1 = null; pointer2 = null; } } }