/**
*
* @author Peter Brinkmann (peter.brinkmann@gmail.com)
*
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
*
*/
package org.puredata.android.scenes;
import org.puredata.android.utils.Properties;
import org.puredata.core.PdBase;
import android.view.MotionEvent;
// Cute little hack to support multiple versions of the Android API, based on an idea
// from http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html
public final class VersionedTouch {
private static final String TOUCH_SYMBOL = "#touch", DOWN = "down", UP = "up", XY = "xy";
private static final boolean hasEclair = Properties.version >= 5;
private static final float XS = 319.0f, YS = 319.0f;
private VersionedTouch() {
// do nothing
}
public static boolean evaluateTouch(MotionEvent event, int xImg, int yImg) {
return (hasEclair) ? TouchEclair.evaluateTouch(event, xImg, yImg) : TouchCupcake.evaluateTouch(event, xImg, yImg);
}
private static class TouchEclair {
public static boolean evaluateTouch(MotionEvent event, int xImg, int yImg) {
int action = event.getAction();
String actionTag = null;
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
actionTag = DOWN;
case MotionEvent.ACTION_POINTER_UP:
if (actionTag == null) actionTag = UP;
int pointerIndex = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; // funny misnomer in Eclair...
int pointerId = event.getPointerId(pointerIndex);
float x = normalize(event.getX(pointerIndex), XS, xImg);
float y = normalize(event.getY(pointerIndex), YS, yImg);
sendMessage(actionTag, pointerId, x, y);
break;
case MotionEvent.ACTION_DOWN:
actionTag = DOWN;
case MotionEvent.ACTION_MOVE:
if (actionTag == null) actionTag = XY;
default:
if (actionTag == null) actionTag = UP;
for (int i = 0; i < event.getPointerCount(); i++) {
x = normalize(event.getX(i), XS, xImg);
y = normalize(event.getY(i), YS, yImg);
sendMessage(actionTag, event.getPointerId(i), x, y);
}
break;
}
return true;
}
}
private static class TouchCupcake {
public static boolean evaluateTouch(MotionEvent event, int xImg, int yImg) {
String actionTag;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
actionTag = DOWN;
break;
case MotionEvent.ACTION_MOVE:
actionTag = XY;
break;
default:
actionTag = UP;
break;
}
float x = normalize(event.getX(), XS, xImg);
float y = normalize(event.getY(), YS, yImg);
sendMessage(actionTag, 0, x, y);
return true;
}
}
private static float normalize(float v, float vm, int dim) {
float t = v * vm / dim;
if (t < 0) t = 0;
else if (t > vm) t = vm;
return t;
}
private static void sendMessage(String actionTag, int pointerId, float x, float y) {
PdBase.sendMessage(TOUCH_SYMBOL, actionTag, pointerId + 1, x, y);
}
}