| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- /*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- package com.jme3.input.android;
- import android.view.MotionEvent;
- import android.view.View;
- import com.jme3.input.event.InputEvent;
- import com.jme3.input.event.MouseButtonEvent;
- import com.jme3.input.event.MouseMotionEvent;
- import com.jme3.input.event.TouchEvent;
- import static com.jme3.input.event.TouchEvent.Type.DOWN;
- import static com.jme3.input.event.TouchEvent.Type.MOVE;
- import static com.jme3.input.event.TouchEvent.Type.UP;
- import com.jme3.math.Vector2f;
- import java.util.HashMap;
- import java.util.logging.Logger;
- /**
- * AndroidTouchHandler is the base class that receives touch inputs from the
- * Android system and creates the TouchEvents for jME. This class is designed
- * to handle the base touch events for Android rev 9 (Android 2.3). This is
- * extended by other classes to add features that were introducted after
- * Android rev 9.
- *
- * @author iwgeric
- */
- public class AndroidTouchHandler implements View.OnTouchListener {
- private static final Logger logger = Logger.getLogger(AndroidTouchHandler.class.getName());
-
- final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>();
- protected int numPointers = 0;
-
- protected AndroidInputHandler androidInput;
- protected AndroidGestureHandler gestureHandler;
- public AndroidTouchHandler(AndroidInputHandler androidInput, AndroidGestureHandler gestureHandler) {
- this.androidInput = androidInput;
- this.gestureHandler = gestureHandler;
- }
- public void initialize() {
- }
-
- public void destroy() {
- setView(null);
- }
-
- public void setView(View view) {
- if (view != null) {
- view.setOnTouchListener(this);
- } else {
- androidInput.getView().setOnTouchListener(null);
- }
- }
-
- protected int getPointerIndex(MotionEvent event) {
- return (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
- >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- }
-
- protected int getPointerId(MotionEvent event) {
- return event.getPointerId(getPointerIndex(event));
- }
-
- protected int getAction(MotionEvent event) {
- return event.getAction() & MotionEvent.ACTION_MASK;
- }
-
- /**
- * onTouch gets called from android thread on touch events
- */
- public boolean onTouch(View view, MotionEvent event) {
- if (!androidInput.isInitialized() || view != androidInput.getView()) {
- return false;
- }
-
- boolean bWasHandled = false;
- TouchEvent touch = null;
- // System.out.println("native : " + event.getAction());
- int action = getAction(event);
- int pointerIndex = getPointerIndex(event);
- int pointerId = getPointerId(event);
- Vector2f lastPos = lastPositions.get(pointerId);
- float jmeX;
- float jmeY;
-
- numPointers = event.getPointerCount();
- // final int historySize = event.getHistorySize();
- //final int pointerCount = event.getPointerCount();
- switch (getAction(event)) {
- case MotionEvent.ACTION_POINTER_DOWN:
- case MotionEvent.ACTION_DOWN:
- jmeX = androidInput.getJmeX(event.getX(pointerIndex));
- jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex)));
- touch = androidInput.getFreeTouchEvent();
- touch.set(TouchEvent.Type.DOWN, jmeX, jmeY, 0, 0);
- touch.setPointerId(pointerId);
- touch.setTime(event.getEventTime());
- touch.setPressure(event.getPressure(pointerIndex));
- lastPos = new Vector2f(jmeX, jmeY);
- lastPositions.put(pointerId, lastPos);
- processEvent(touch);
- bWasHandled = true;
- break;
- case MotionEvent.ACTION_POINTER_UP:
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- jmeX = androidInput.getJmeX(event.getX(pointerIndex));
- jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(pointerIndex)));
- touch = androidInput.getFreeTouchEvent();
- touch.set(TouchEvent.Type.UP, jmeX, jmeY, 0, 0);
- touch.setPointerId(pointerId);
- touch.setTime(event.getEventTime());
- touch.setPressure(event.getPressure(pointerIndex));
- lastPositions.remove(pointerId);
- processEvent(touch);
- bWasHandled = true;
- break;
- case MotionEvent.ACTION_MOVE:
- // Convert all pointers into events
- for (int p = 0; p < event.getPointerCount(); p++) {
- jmeX = androidInput.getJmeX(event.getX(p));
- jmeY = androidInput.invertY(androidInput.getJmeY(event.getY(p)));
- lastPos = lastPositions.get(event.getPointerId(p));
- if (lastPos == null) {
- lastPos = new Vector2f(jmeX, jmeY);
- lastPositions.put(event.getPointerId(p), lastPos);
- }
- float dX = jmeX - lastPos.x;
- float dY = jmeY - lastPos.y;
- if (dX != 0 || dY != 0) {
- touch = androidInput.getFreeTouchEvent();
- touch.set(TouchEvent.Type.MOVE, jmeX, jmeY, dX, dY);
- touch.setPointerId(event.getPointerId(p));
- touch.setTime(event.getEventTime());
- touch.setPressure(event.getPressure(p));
- lastPos.set(jmeX, jmeY);
- processEvent(touch);
- bWasHandled = true;
- }
- }
- break;
- case MotionEvent.ACTION_OUTSIDE:
- break;
- }
- // Try to detect gestures
- if (gestureHandler != null) {
- gestureHandler.detectGesture(event);
- }
- return bWasHandled;
- }
- protected void processEvent(TouchEvent event) {
- // Add the touch event
- androidInput.addEvent(event);
- // MouseEvents do not support multi-touch, so only evaluate 1 finger pointer events
- if (androidInput.isSimulateMouse() && numPointers == 1) {
- InputEvent mouseEvent = generateMouseEvent(event);
- if (mouseEvent != null) {
- // Add the mouse event
- androidInput.addEvent(mouseEvent);
- }
- }
-
- }
- // TODO: Ring Buffer for mouse events?
- protected InputEvent generateMouseEvent(TouchEvent event) {
- InputEvent inputEvent = null;
- int newX;
- int newY;
- int newDX;
- int newDY;
- if (androidInput.isMouseEventsInvertX()) {
- newX = (int) (androidInput.invertX(event.getX()));
- newDX = (int)event.getDeltaX() * -1;
- } else {
- newX = (int) event.getX();
- newDX = (int)event.getDeltaX();
- }
- if (androidInput.isMouseEventsInvertY()) {
- newY = (int) (androidInput.invertY(event.getY()));
- newDY = (int)event.getDeltaY() * -1;
- } else {
- newY = (int) event.getY();
- newDY = (int)event.getDeltaY();
- }
- switch (event.getType()) {
- case DOWN:
- // Handle mouse down event
- inputEvent = new MouseButtonEvent(0, true, newX, newY);
- inputEvent.setTime(event.getTime());
- break;
- case UP:
- // Handle mouse up event
- inputEvent = new MouseButtonEvent(0, false, newX, newY);
- inputEvent.setTime(event.getTime());
- break;
- case HOVER_MOVE:
- case MOVE:
- inputEvent = new MouseMotionEvent(newX, newY, newDX, newDY, (int)event.getScaleSpan(), (int)event.getDeltaScaleSpan());
- inputEvent.setTime(event.getTime());
- break;
- }
- return inputEvent;
- }
-
- }
|