Android: preparation of android tree for jme input integration
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7547 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
a10e44f738
commit
dd100bed74
@ -1,9 +1,7 @@
|
|||||||
package com.jme3.input.android;
|
package com.jme3.input.android;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.HashMap;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@ -11,35 +9,37 @@ import android.view.GestureDetector;
|
|||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
import com.jme3.input.android.TouchEvent;
|
|
||||||
import com.jme3.input.KeyInput;
|
import com.jme3.input.KeyInput;
|
||||||
import com.jme3.input.MouseInput;
|
|
||||||
import com.jme3.input.RawInputListener;
|
import com.jme3.input.RawInputListener;
|
||||||
import com.jme3.input.event.KeyInputEvent;
|
import com.jme3.input.TouchInput;
|
||||||
import com.jme3.input.event.MouseButtonEvent;
|
import com.jme3.input.event.MouseButtonEvent;
|
||||||
import com.jme3.input.event.MouseMotionEvent;
|
import com.jme3.input.event.MouseMotionEvent;
|
||||||
|
import com.jme3.input.event.TouchEvent;
|
||||||
|
import com.jme3.input.event.TouchEvent.Type;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
|
import com.jme3.util.RingBuffer;
|
||||||
|
|
||||||
|
|
||||||
public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
|
public class AndroidInput extends GLSurfaceView implements TouchInput,
|
||||||
GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener
|
GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener
|
||||||
{
|
{
|
||||||
private final static Logger logger = Logger.getLogger(AndroidInput.class.getName());
|
private final static Logger logger = Logger.getLogger(AndroidInput.class.getName());
|
||||||
|
private boolean isInitialized = false;
|
||||||
|
private RawInputListener listener = null;
|
||||||
|
|
||||||
|
final private static int MAX_EVENTS = 1024;
|
||||||
|
|
||||||
|
final private RingBuffer<TouchEvent> eventQueue = new RingBuffer<TouchEvent>(MAX_EVENTS);
|
||||||
|
final private RingBuffer<TouchEvent> eventPool = new RingBuffer<TouchEvent>(MAX_EVENTS);
|
||||||
|
final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>();
|
||||||
|
|
||||||
|
public boolean fireMouseEvents = true;
|
||||||
|
public boolean fireKeyboardEvents = false;
|
||||||
|
|
||||||
private RawInputListener listenerRaw = null;
|
|
||||||
private AndroidTouchInputListener listenerTouch = null;
|
|
||||||
private ScaleGestureDetector scaledetector;
|
private ScaleGestureDetector scaledetector;
|
||||||
private GestureDetector detector;
|
private GestureDetector detector;
|
||||||
private int lastX;
|
private int lastX;
|
||||||
private int lastY;
|
private int lastY;
|
||||||
private boolean dragging = false;
|
|
||||||
|
|
||||||
private List<Object> currentEvents = new ArrayList<Object>();
|
|
||||||
|
|
||||||
private final static int MAX_EVENTS = 1024;
|
|
||||||
|
|
||||||
|
|
||||||
private boolean FIRE_MOUSE_EVENTS = true;
|
|
||||||
|
|
||||||
|
|
||||||
private static final int[] ANDROID_TO_JME = {
|
private static final int[] ANDROID_TO_JME = {
|
||||||
@ -159,6 +159,40 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
|
|||||||
scaledetector=new ScaleGestureDetector(ctx, this);
|
scaledetector=new ScaleGestureDetector(ctx, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TouchEvent getNextFreeTouchEvent()
|
||||||
|
{
|
||||||
|
return getNextFreeTouchEvent(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TouchEvent getNextFreeTouchEvent(boolean wait)
|
||||||
|
{
|
||||||
|
TouchEvent evt;
|
||||||
|
if (eventPool.isEmpty() && wait)
|
||||||
|
{
|
||||||
|
logger.warning("eventPool buffer underrun");
|
||||||
|
boolean isEmpty;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
synchronized(eventPool)
|
||||||
|
{
|
||||||
|
isEmpty = eventPool.isEmpty();
|
||||||
|
}
|
||||||
|
try { Thread.sleep(50); } catch (InterruptedException e) { }
|
||||||
|
}
|
||||||
|
while (isEmpty);
|
||||||
|
evt = eventPool.pop();
|
||||||
|
}
|
||||||
|
else if (eventPool.isEmpty())
|
||||||
|
{
|
||||||
|
evt = new TouchEvent();
|
||||||
|
logger.warning("eventPool buffer underrun");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evt = eventPool.pop();
|
||||||
|
}
|
||||||
|
return evt;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* onTouchEvent gets called from android thread on touchpad events
|
* onTouchEvent gets called from android thread on touchpad events
|
||||||
*/
|
*/
|
||||||
@ -166,94 +200,62 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
|
|||||||
public boolean onTouchEvent(MotionEvent event)
|
public boolean onTouchEvent(MotionEvent event)
|
||||||
{
|
{
|
||||||
boolean bWasHandled = false;
|
boolean bWasHandled = false;
|
||||||
MouseButtonEvent btn;
|
|
||||||
TouchEvent touch;
|
TouchEvent touch;
|
||||||
|
|
||||||
// Send the raw event
|
|
||||||
processEvent(event);
|
|
||||||
|
|
||||||
// Try to detect gestures
|
// Try to detect gestures
|
||||||
this.detector.onTouchEvent(event);
|
this.detector.onTouchEvent(event);
|
||||||
this.scaledetector.onTouchEvent(event);
|
this.scaledetector.onTouchEvent(event);
|
||||||
|
|
||||||
int newX = getWidth() - (int) event.getX();
|
|
||||||
int newY = (int) event.getY();
|
|
||||||
|
|
||||||
switch (event.getAction())
|
switch (event.getAction())
|
||||||
{
|
{
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
|
||||||
if (FIRE_MOUSE_EVENTS)
|
// Convert all pointers into events
|
||||||
|
for (int p = 0; p < event.getPointerCount(); p++)
|
||||||
{
|
{
|
||||||
// Handle mouse events
|
touch = getNextFreeTouchEvent();
|
||||||
btn = new MouseButtonEvent(0, true, newX, newY);
|
touch.set(Type.DOWN, event.getX(p), event.getY(p), 0, 0);
|
||||||
btn.setTime(event.getEventTime());
|
touch.setPointerId(event.getPointerId(p));
|
||||||
processEvent(btn);
|
touch.setTime(event.getEventTime());
|
||||||
}
|
|
||||||
// Store current pos
|
|
||||||
lastX = -1;
|
|
||||||
lastY = -1;
|
|
||||||
|
|
||||||
// Handle gesture events
|
|
||||||
touch = new TouchEvent(TouchEvent.Type.GRABBED, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
|
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
|
}
|
||||||
|
|
||||||
bWasHandled = true;
|
bWasHandled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
|
|
||||||
if (FIRE_MOUSE_EVENTS)
|
// Convert all pointers into events
|
||||||
|
for (int p = 0; p < event.getPointerCount(); p++)
|
||||||
{
|
{
|
||||||
// Handle mouse events
|
touch = getNextFreeTouchEvent();
|
||||||
btn = new MouseButtonEvent(0, false, newX, newY);
|
touch.set(Type.UP, event.getX(p), event.getY(p), 0, 0);
|
||||||
btn.setTime(event.getEventTime());
|
touch.setPointerId(event.getPointerId(p));
|
||||||
processEvent(btn);
|
touch.setTime(event.getEventTime());
|
||||||
|
processEvent(touch);
|
||||||
}
|
}
|
||||||
// Store current pos
|
|
||||||
lastX = -1;
|
|
||||||
lastY = -1;
|
|
||||||
|
|
||||||
// Handle gesture events
|
|
||||||
if(dragging)
|
|
||||||
{
|
|
||||||
touch = new TouchEvent(TouchEvent.Type.DRAGGED, TouchEvent.Operation.STOPPED,event.getX(),event.getY(),event.getX()-lastX,event.getY()-lastY,null);
|
|
||||||
processEvent(touch);
|
|
||||||
}
|
|
||||||
touch = new TouchEvent(TouchEvent.Type.RELEASED, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
|
|
||||||
processEvent(touch);
|
|
||||||
dragging=false;
|
|
||||||
bWasHandled = true;
|
bWasHandled = true;
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_MOVE:
|
case MotionEvent.ACTION_MOVE:
|
||||||
if(!scaledetector.isInProgress())
|
|
||||||
{
|
|
||||||
if(!dragging)
|
|
||||||
touch = new TouchEvent(TouchEvent.Type.DRAGGED, TouchEvent.Operation.STARTED,event.getX(),event.getY(),event.getX()-lastX,event.getY()-lastY,null);
|
|
||||||
else
|
|
||||||
touch = new TouchEvent(TouchEvent.Type.DRAGGED, TouchEvent.Operation.RUNNING,event.getX(),event.getY(),event.getX()-lastX,event.getY()-lastY,null);
|
|
||||||
|
|
||||||
|
// Convert all pointers into events
|
||||||
|
for (int p = 0; p < event.getPointerCount(); p++)
|
||||||
|
{
|
||||||
|
Vector2f lastPos = lastPositions.get(event.getPointerId(p));
|
||||||
|
if (lastPos == null)
|
||||||
|
{
|
||||||
|
lastPos = new Vector2f(event.getX(p), event.getY(p));
|
||||||
|
lastPositions.put(event.getPointerId(p), lastPos);
|
||||||
|
}
|
||||||
|
touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.MOVE, event.getX(p), event.getY(p), event.getX(p) - lastPos.x, event.getY(p) - lastPos.y);
|
||||||
|
touch.setPointerId(event.getPointerId(p));
|
||||||
|
touch.setTime(event.getEventTime());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
dragging=true;
|
lastPos.set(event.getX(p), event.getY(p));
|
||||||
}
|
}
|
||||||
if (FIRE_MOUSE_EVENTS)
|
|
||||||
{
|
|
||||||
|
|
||||||
int dx;
|
|
||||||
int dy;
|
|
||||||
if (lastX != -1){
|
|
||||||
dx = newX - lastX;
|
|
||||||
dy = newY - lastY;
|
|
||||||
}else{
|
|
||||||
dx = 0;
|
|
||||||
dy = 0;
|
|
||||||
}
|
|
||||||
MouseMotionEvent mot = new MouseMotionEvent(newX, newY, dx, dy, 0, 0);
|
|
||||||
mot.setTime(event.getEventTime());
|
|
||||||
processEvent(mot);
|
|
||||||
}
|
|
||||||
lastX = newX;
|
|
||||||
lastY = newY;
|
|
||||||
bWasHandled = true;
|
bWasHandled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -274,20 +276,18 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown (int keyCode, KeyEvent event) {
|
public boolean onKeyDown (int keyCode, KeyEvent event)
|
||||||
|
|
||||||
// Send the raw event
|
|
||||||
processEvent(event);
|
|
||||||
|
|
||||||
int jmeCode = ANDROID_TO_JME[keyCode];
|
|
||||||
if (jmeCode != 0)
|
|
||||||
{
|
{
|
||||||
String str = event.getCharacters();
|
TouchEvent evt;
|
||||||
char c = str != null && str.length() > 0 ? str.charAt(0) : 0x0;
|
evt = getNextFreeTouchEvent();
|
||||||
KeyInputEvent evt = new KeyInputEvent(jmeCode, c, true, false);
|
evt.set(TouchEvent.Type.KEY_DOWN);
|
||||||
logger.info("onKeyDown " + evt);
|
evt.setKeyCode(keyCode);
|
||||||
|
evt.setCharacters(event.getCharacters());
|
||||||
|
evt.setTime(event.getEventTime());
|
||||||
|
|
||||||
|
// Send the event
|
||||||
processEvent(evt);
|
processEvent(evt);
|
||||||
}
|
|
||||||
// Handle all keys ourself, except the back button (4)
|
// Handle all keys ourself, except the back button (4)
|
||||||
if (keyCode == 4)
|
if (keyCode == 4)
|
||||||
return false;
|
return false;
|
||||||
@ -296,20 +296,17 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyUp (int keyCode, KeyEvent event) {
|
public boolean onKeyUp (int keyCode, KeyEvent event)
|
||||||
|
|
||||||
// Send the raw event
|
|
||||||
processEvent(event);
|
|
||||||
|
|
||||||
int jmeCode = ANDROID_TO_JME[keyCode];
|
|
||||||
if (jmeCode != 0)
|
|
||||||
{
|
{
|
||||||
String str = event.getCharacters();
|
TouchEvent evt;
|
||||||
char c = str != null && str.length() > 0 ? str.charAt(0) : 0x0;
|
evt = getNextFreeTouchEvent();
|
||||||
KeyInputEvent evt = new KeyInputEvent(jmeCode, c, false, false);
|
evt.set(TouchEvent.Type.KEY_UP);
|
||||||
logger.info("onKeyUp " + evt);
|
evt.setKeyCode(keyCode);
|
||||||
|
evt.setCharacters(event.getCharacters());
|
||||||
|
evt.setTime(event.getEventTime());
|
||||||
|
|
||||||
|
// Send the event
|
||||||
processEvent(evt);
|
processEvent(evt);
|
||||||
}
|
|
||||||
|
|
||||||
// Handle all keys ourself, except the back button (4)
|
// Handle all keys ourself, except the back button (4)
|
||||||
if (keyCode == 4)
|
if (keyCode == 4)
|
||||||
@ -318,81 +315,143 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCursorVisible(boolean visible){
|
|
||||||
|
// -----------------------------------------
|
||||||
|
// JME3 Input interface
|
||||||
|
@Override
|
||||||
|
public void initialize()
|
||||||
|
{
|
||||||
|
TouchEvent item;
|
||||||
|
for (int i = 0; i < MAX_EVENTS; i++)
|
||||||
|
{
|
||||||
|
item = new TouchEvent();
|
||||||
|
eventPool.push(item);
|
||||||
|
}
|
||||||
|
isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getButtonCount(){
|
@Override
|
||||||
return 255;
|
public void destroy()
|
||||||
|
{
|
||||||
|
isInitialized = false;
|
||||||
|
|
||||||
|
// Clean up queues
|
||||||
|
while (! eventPool.isEmpty())
|
||||||
|
{
|
||||||
|
eventPool.pop();
|
||||||
|
}
|
||||||
|
while (! eventQueue.isEmpty())
|
||||||
|
{
|
||||||
|
eventQueue.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
@Override
|
||||||
|
public boolean isInitialized()
|
||||||
|
{
|
||||||
|
return isInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
@Override
|
||||||
|
public void setInputListener(RawInputListener listener)
|
||||||
|
{
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getInputTimeNanos()
|
||||||
|
{
|
||||||
|
return System.nanoTime();
|
||||||
|
}
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
private void processEvent(TouchEvent event)
|
||||||
|
{
|
||||||
|
synchronized (eventQueue)
|
||||||
|
{
|
||||||
|
eventQueue.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update()
|
||||||
|
{
|
||||||
generateEvents();
|
generateEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
private void generateEvents()
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInitialized() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void processEvent(Object event)
|
|
||||||
{
|
{
|
||||||
synchronized (currentEvents) {
|
if (listener != null)
|
||||||
if (currentEvents.size() < MAX_EVENTS)
|
|
||||||
currentEvents.add(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object event;
|
|
||||||
private void generateEvents() {
|
|
||||||
if (listenerRaw != null)
|
|
||||||
{
|
{
|
||||||
synchronized (currentEvents) {
|
TouchEvent event;
|
||||||
//for (Object event: currentEvents) {
|
MouseButtonEvent btn;
|
||||||
for (int i = 0; i < currentEvents.size(); i++) {
|
int newX;
|
||||||
event = currentEvents.get(i);
|
int newY;
|
||||||
if (event instanceof MouseButtonEvent) {
|
|
||||||
listenerRaw.onMouseButtonEvent((MouseButtonEvent) event);
|
while (!eventQueue.isEmpty())
|
||||||
} else if (event instanceof MouseMotionEvent) {
|
{
|
||||||
listenerRaw.onMouseMotionEvent((MouseMotionEvent) event);
|
synchronized (eventQueue)
|
||||||
} else if (event instanceof KeyInputEvent) {
|
{
|
||||||
listenerRaw.onKeyEvent((KeyInputEvent) event);
|
event = eventQueue.pop();
|
||||||
} else if (event instanceof TouchEvent) {
|
}
|
||||||
if (listenerTouch != null)
|
if (event != null)
|
||||||
listenerTouch.onTouchEvent((TouchEvent) event);
|
{
|
||||||
} else if (event instanceof MotionEvent) {
|
listener.onTouchEvent(event);
|
||||||
if (listenerTouch != null)
|
|
||||||
listenerTouch.onMotionEvent((MotionEvent) event);
|
if (fireMouseEvents)
|
||||||
} else if (event instanceof KeyEvent) {
|
{
|
||||||
if (listenerTouch != null)
|
newX = getWidth() - (int) event.getX();
|
||||||
listenerTouch.onAndroidKeyEvent((KeyEvent) event);
|
newY = (int) event.getY();
|
||||||
|
switch (event.getType())
|
||||||
|
{
|
||||||
|
case DOWN:
|
||||||
|
// Handle mouse events
|
||||||
|
btn = new MouseButtonEvent(0, true, newX, newY);
|
||||||
|
btn.setTime(event.getTime());
|
||||||
|
listener.onMouseButtonEvent(btn);
|
||||||
|
// Store current pos
|
||||||
|
lastX = -1;
|
||||||
|
lastY = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UP:
|
||||||
|
// Handle mouse events
|
||||||
|
btn = new MouseButtonEvent(0, false, newX, newY);
|
||||||
|
btn.setTime(event.getTime());
|
||||||
|
listener.onMouseButtonEvent(btn);
|
||||||
|
// Store current pos
|
||||||
|
lastX = -1;
|
||||||
|
lastY = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOVE:
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
if (lastX != -1){
|
||||||
|
dx = newX - lastX;
|
||||||
|
dy = newY - lastY;
|
||||||
|
}else{
|
||||||
|
dx = 0;
|
||||||
|
dy = 0;
|
||||||
|
}
|
||||||
|
MouseMotionEvent mot = new MouseMotionEvent(newX, newY, dx, dy, 0, 0);
|
||||||
|
mot.setTime(event.getTime());
|
||||||
|
listener.onMouseMotionEvent(mot);
|
||||||
|
lastX = newX;
|
||||||
|
lastY = newY;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentEvents.clear();
|
|
||||||
}
|
}
|
||||||
|
synchronized (eventPool)
|
||||||
|
{
|
||||||
|
eventPool.push(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInputListener(RawInputListener listener) {
|
|
||||||
this.listenerRaw = listener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInputListener(AndroidTouchInputListener listener) {
|
|
||||||
this.listenerRaw = listener;
|
|
||||||
this.listenerTouch = listener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getInputTimeNanos() {
|
|
||||||
return System.nanoTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --------------- Gesture detected callback events ----------------------------------
|
// --------------- Gesture detected callback events ----------------------------------
|
||||||
|
|
||||||
public boolean onDown(MotionEvent event)
|
public boolean onDown(MotionEvent event)
|
||||||
@ -402,74 +461,121 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
|
|||||||
|
|
||||||
public void onLongPress(MotionEvent event)
|
public void onLongPress(MotionEvent event)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.LONGPRESSED, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.LONGPRESSED, event.getX(), event.getY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(event.getEventTime());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onFling(MotionEvent event, MotionEvent event2, float vx, float vy)
|
public boolean onFling(MotionEvent event, MotionEvent event2, float vx, float vy)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.FLING, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.FLING, event.getX(), event.getY(), vx, vy);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(event.getEventTime());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onSingleTapConfirmed(MotionEvent event)
|
public boolean onSingleTapConfirmed(MotionEvent event)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.TAP, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.TAP, event.getX(), event.getY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(event.getEventTime());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onDoubleTap(MotionEvent event)
|
public boolean onDoubleTap(MotionEvent event)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.DOUBLETAP, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.DOUBLETAP, event.getX(), event.getY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(event.getEventTime());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector)
|
public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.SCALE, TouchEvent.Operation.STARTED,scaleGestureDetector.getFocusX(),scaleGestureDetector.getFocusY(),0,0,new float[]{scaleGestureDetector.getCurrentSpan(),scaleGestureDetector.getScaleFactor()});
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.SCALE_START, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(scaleGestureDetector.getEventTime());
|
||||||
|
touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
|
||||||
|
touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onScale(ScaleGestureDetector scaleGestureDetector)
|
public boolean onScale(ScaleGestureDetector scaleGestureDetector)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.SCALE, TouchEvent.Operation.RUNNING,scaleGestureDetector.getFocusX(),scaleGestureDetector.getFocusY(),0,0,new float[]{scaleGestureDetector.getCurrentSpan(),scaleGestureDetector.getScaleFactor()});
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.SCALE_MOVE, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(scaleGestureDetector.getEventTime());
|
||||||
|
touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
|
||||||
|
touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
|
|
||||||
if (FIRE_MOUSE_EVENTS)
|
|
||||||
{
|
|
||||||
MouseMotionEvent mot = new MouseMotionEvent(0, 0, 0, 0, 0, (int)scaleGestureDetector.getScaleFactor());
|
|
||||||
mot.setTime(scaleGestureDetector.getEventTime());
|
|
||||||
processEvent(mot);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector)
|
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.SCALE, TouchEvent.Operation.STOPPED,scaleGestureDetector.getFocusX(),scaleGestureDetector.getFocusY(),0,0,new float[]{scaleGestureDetector.getCurrentSpan(),scaleGestureDetector.getScaleFactor()});
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.SCALE_END, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(scaleGestureDetector.getEventTime());
|
||||||
|
touch.setScaleSpan(scaleGestureDetector.getCurrentSpan());
|
||||||
|
touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
|
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
|
||||||
float distanceY) {
|
{
|
||||||
// TODO Auto-generated method stub
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.SCROLL, e1.getX(), e1.getY(), distanceX, distanceY);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(e1.getEventTime());
|
||||||
|
processEvent(touch);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onShowPress(MotionEvent e) {
|
public void onShowPress(MotionEvent event)
|
||||||
// TODO Auto-generated method stub
|
{
|
||||||
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.SHOWPRESS, event.getX(), event.getY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(event.getEventTime());
|
||||||
|
processEvent(touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onSingleTapUp(MotionEvent event)
|
public boolean onSingleTapUp(MotionEvent event)
|
||||||
{
|
{
|
||||||
TouchEvent touch = new TouchEvent(TouchEvent.Type.TAP, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
|
TouchEvent touch = getNextFreeTouchEvent();
|
||||||
|
touch.set(Type.TAP, event.getX(), event.getY(), 0f, 0f);
|
||||||
|
touch.setPointerId(0);
|
||||||
|
touch.setTime(event.getEventTime());
|
||||||
processEvent(touch);
|
processEvent(touch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSimulateMouse(boolean simulate)
|
||||||
|
{
|
||||||
|
fireMouseEvents = simulate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSimulateKeyboard(boolean simulate)
|
||||||
|
{
|
||||||
|
fireKeyboardEvents = simulate;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.jme3.input.android;
|
package com.jme3.input.android;
|
||||||
|
|
||||||
import com.jme3.input.RawInputListener;
|
import com.jme3.input.RawInputListener;
|
||||||
|
import com.jme3.input.event.TouchEvent;
|
||||||
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
package com.jme3.input.android;
|
|
||||||
|
|
||||||
import com.jme3.math.Vector2f;
|
|
||||||
|
|
||||||
public class TouchEvent
|
|
||||||
{
|
|
||||||
public static enum Type {GRABBED,DRAGGED,RELEASED,FLING,TAP,DOUBLETAP,LONGPRESSED,SCALE,OUTSIDE,IDLE}
|
|
||||||
public Type type=Type.IDLE;
|
|
||||||
|
|
||||||
public static enum Operation {NOP,STARTED,RUNNING,STOPPED,CANCELED}
|
|
||||||
private Operation operation=Operation.NOP;
|
|
||||||
|
|
||||||
public float x;
|
|
||||||
public float y;
|
|
||||||
public float deltax;
|
|
||||||
public float deltay;
|
|
||||||
public float[] extra;
|
|
||||||
|
|
||||||
public TouchEvent(Type type, Operation operation, float x, float y, float deltax, float deltay, float[] extra)
|
|
||||||
{
|
|
||||||
set(type, operation, x, y, deltax, deltay, extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set( Type type, Operation operation, float x, float y, float deltax, float deltay, float[] extra)
|
|
||||||
{
|
|
||||||
this.type=type;
|
|
||||||
this.operation=operation;
|
|
||||||
this.x=x;
|
|
||||||
this.y=y;
|
|
||||||
this.deltax=deltax;
|
|
||||||
this.deltay=deltay;
|
|
||||||
this.extra=extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Type getType()
|
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Operation getOperation()
|
|
||||||
{
|
|
||||||
return operation;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public float getX()
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getY()
|
|
||||||
{
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getDeltaX()
|
|
||||||
{
|
|
||||||
return deltax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getDeltaY()
|
|
||||||
{
|
|
||||||
return deltay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float[] getExtra()
|
|
||||||
{
|
|
||||||
return extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2f getDelta()
|
|
||||||
{
|
|
||||||
return new Vector2f(deltax,deltay);
|
|
||||||
}
|
|
||||||
}
|
|
@ -41,7 +41,10 @@ import com.jme3.app.AndroidHarness;
|
|||||||
import com.jme3.input.JoyInput;
|
import com.jme3.input.JoyInput;
|
||||||
import com.jme3.input.KeyInput;
|
import com.jme3.input.KeyInput;
|
||||||
import com.jme3.input.MouseInput;
|
import com.jme3.input.MouseInput;
|
||||||
|
import com.jme3.input.TouchInput;
|
||||||
import com.jme3.input.android.AndroidInput;
|
import com.jme3.input.android.AndroidInput;
|
||||||
|
import com.jme3.input.dummy.DummyKeyInput;
|
||||||
|
import com.jme3.input.dummy.DummyMouseInput;
|
||||||
import com.jme3.renderer.android.OGLESShaderRenderer;
|
import com.jme3.renderer.android.OGLESShaderRenderer;
|
||||||
import com.jme3.system.AppSettings;
|
import com.jme3.system.AppSettings;
|
||||||
import com.jme3.system.JmeContext;
|
import com.jme3.system.JmeContext;
|
||||||
@ -231,12 +234,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MouseInput getMouseInput() {
|
public MouseInput getMouseInput() {
|
||||||
return view;
|
return new DummyMouseInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyInput getKeyInput() {
|
public KeyInput getKeyInput() {
|
||||||
return view;
|
return new DummyKeyInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -244,6 +247,11 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TouchInput getTouchInput() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Timer getTimer()
|
public Timer getTimer()
|
||||||
{
|
{
|
||||||
@ -386,4 +394,5 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
63
engine/src/android/com/jme3/util/RingBuffer.java
Normal file
63
engine/src/android/com/jme3/util/RingBuffer.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package com.jme3.util;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ring buffer (fixed size queue) implementation using a circular array (array with wrap-around).
|
||||||
|
*/
|
||||||
|
// suppress unchecked warnings in Java 1.5.0_6 and later
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public class RingBuffer<Item> implements Iterable<Item>
|
||||||
|
{
|
||||||
|
private Item[] buffer; // queue elements
|
||||||
|
private int count = 0; // number of elements on queue
|
||||||
|
private int indexOut = 0; // index of first element of queue
|
||||||
|
private int indexIn = 0; // index of next available slot
|
||||||
|
|
||||||
|
// cast needed since no generic array creation in Java
|
||||||
|
public RingBuffer(int capacity)
|
||||||
|
{
|
||||||
|
buffer = (Item[]) new Object[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() { return count == 0; }
|
||||||
|
public int size() { return count; }
|
||||||
|
|
||||||
|
public void push(Item item)
|
||||||
|
{
|
||||||
|
if (count == buffer.length) { throw new RuntimeException("Ring buffer overflow"); }
|
||||||
|
buffer[indexIn] = item;
|
||||||
|
indexIn = (indexIn + 1) % buffer.length; // wrap-around
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item pop()
|
||||||
|
{
|
||||||
|
if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); }
|
||||||
|
Item item = buffer[indexOut];
|
||||||
|
buffer[indexOut] = null; // to help with garbage collection
|
||||||
|
count--;
|
||||||
|
indexOut = (indexOut + 1) % buffer.length; // wrap-around
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<Item> iterator() { return new RingBufferIterator(); }
|
||||||
|
|
||||||
|
// an iterator, doesn't implement remove() since it's optional
|
||||||
|
private class RingBufferIterator implements Iterator<Item> {
|
||||||
|
private int i = 0;
|
||||||
|
public boolean hasNext() { return i < count; }
|
||||||
|
public void remove() { throw new UnsupportedOperationException(); }
|
||||||
|
|
||||||
|
public Item next() {
|
||||||
|
if (!hasNext()) throw new NoSuchElementException();
|
||||||
|
return buffer[i++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user