/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
******************************************************************************/
package com.badlogic.gdx.backends.android;
import android.content.Context;
import android.view.MotionEvent;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidInput.TouchEvent;
/**
* Multitouch handler for devices running Android >= 2.0. If device is capable of (fake) multitouch this will report
* additional pointers.
*
* @author badlogicgames@gmail.com
*/
public class AndroidMultiTouchHandler implements AndroidTouchHandler {
public void onTouch(MotionEvent event, AndroidInput input) {
final int action = event.getAction() & MotionEvent.ACTION_MASK;
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
int pointerId = event.getPointerId(pointerIndex);
int x = 0, y = 0;
int realPointerIndex = 0;
long timeStamp = System.nanoTime();
synchronized (input) {
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
realPointerIndex = input.getFreePointerIndex(); // get a free pointer index as reported by Input.getX() etc.
input.realId[realPointerIndex] = pointerId;
x = (int) event.getX(pointerIndex);
y = (int) event.getY(pointerIndex);
postTouchEvent(input, TouchEvent.TOUCH_DOWN, x, y, realPointerIndex, timeStamp);
input.touchX[realPointerIndex] = x;
input.touchY[realPointerIndex] = y;
input.deltaX[realPointerIndex] = 0;
input.deltaY[realPointerIndex] = 0;
input.touched[realPointerIndex] = true;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
realPointerIndex = input.lookUpPointerIndex(pointerId);
if (realPointerIndex == -1)
break;
input.realId[realPointerIndex] = -1;
x = (int) event.getX(pointerIndex);
y = (int) event.getY(pointerIndex);
postTouchEvent(input, TouchEvent.TOUCH_UP, x, y, realPointerIndex, timeStamp);
input.touchX[realPointerIndex] = x;
input.touchY[realPointerIndex] = y;
input.deltaX[realPointerIndex] = 0;
input.deltaY[realPointerIndex] = 0;
input.touched[realPointerIndex] = false;
break;
case MotionEvent.ACTION_MOVE:
int pointerCount = event.getPointerCount();
for (int i = 0; i < pointerCount; i++) {
pointerIndex = i;
pointerId = event.getPointerId(pointerIndex);
x = (int) event.getX(pointerIndex);
y = (int) event.getY(pointerIndex);
realPointerIndex = input.lookUpPointerIndex(pointerId);
if (realPointerIndex == -1)
continue;
postTouchEvent(input, TouchEvent.TOUCH_DRAGGED, x, y, realPointerIndex, timeStamp);
input.deltaX[realPointerIndex] = x - input.touchX[realPointerIndex];
input.deltaY[realPointerIndex] = y - input.touchY[realPointerIndex];
input.touchX[realPointerIndex] = x;
input.touchY[realPointerIndex] = y;
}
break;
}
}
Gdx.app.getGraphics().requestRendering();
}
private void logAction(int action, int pointer) {
String actionStr = "";
if (action == MotionEvent.ACTION_DOWN)
actionStr = "DOWN";
else if (action == MotionEvent.ACTION_POINTER_DOWN)
actionStr = "POINTER DOWN";
else if (action == MotionEvent.ACTION_UP)
actionStr = "UP";
else if (action == MotionEvent.ACTION_POINTER_UP)
actionStr = "POINTER UP";
else if (action == MotionEvent.ACTION_OUTSIDE)
actionStr = "OUTSIDE";
else if (action == MotionEvent.ACTION_CANCEL)
actionStr = "CANCEL";
else if (action == MotionEvent.ACTION_MOVE)
actionStr = "MOVE";
else
actionStr = "UNKNOWN (" + action + ")";
Gdx.app.log("AndroidMultiTouchHandler", "action " + actionStr + ", Android pointer id: " + pointer);
}
private void postTouchEvent(AndroidInput input, int type, int x, int y, int pointer, long timeStamp) {
TouchEvent event = input.usedTouchEvents.obtain();
event.timeStamp = timeStamp;
event.pointer = pointer;
event.x = x;
event.y = y;
event.type = type;
input.touchEvents.add(event);
}
public boolean supportsMultitouch(Context activity) {
return activity.getPackageManager().hasSystemFeature("android.hardware.touchscreen.multitouch");
}
}