/**
* Copyright 2008 - 2015 The Loon Game Engine Authors
*
* 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.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.5
*/
package loon.android;
import loon.LObject;
import loon.event.InputMake;
import loon.event.KeyMake;
import loon.event.SysKey;
import loon.event.TouchMake;
import android.view.KeyEvent;
import android.view.MotionEvent;
public class AndroidInputMake extends InputMake {
private final AndroidGame game;
public AndroidInputMake(AndroidGame game) {
this.game = game;
}
@Override
public boolean hasHardwareKeyboard() {
return false;
}
void onKeyDown(int keyCode, KeyEvent nativeEvent) {
long time = nativeEvent.getEventTime();
char charCode = (char) nativeEvent.getUnicodeChar();
if (nativeEvent.getKeyCode() == 67) {
charCode = '\b';
}
KeyMake.KeyEvent event = new KeyMake.KeyEvent(0, time, charCode,
keyForCode(keyCode), true);
event.setFlag(mods(nativeEvent));
dispatch(event);
}
void onKeyUp(int keyCode, KeyEvent nativeEvent) {
long time = nativeEvent.getEventTime();
char charCode = (char) nativeEvent.getUnicodeChar();
if (nativeEvent.getKeyCode() == 67) {
charCode = '\b';
}
KeyMake.KeyEvent event = new KeyMake.KeyEvent(0, time, charCode,
keyForCode(keyCode), false);
event.setFlag(mods(nativeEvent));
dispatch(event);
}
boolean onTouch(MotionEvent event) {
int actionType = event.getActionMasked();
TouchMake.Event.Kind kind = (actionType < TO_KIND.length) ? TO_KIND[actionType]
: null;
if (kind != null) {
final TouchMake.Event[] touches = parseMotionEvent(event, kind);
game.asyn().invokeLater(new Runnable() {
@Override
public void run() {
game.input().touchEvents.emit(touches);
}
});
}
return kind != null;
}
private int mods(KeyEvent event) {
return modifierFlags(event.isAltPressed(), event.isCtrlPressed(),
event.isMetaPressed(), event.isShiftPressed());
}
private void dispatch(final KeyMake.Event event) {
game.asyn().invokeLater(new Runnable() {
@Override
public void run() {
keyboardEvents.emit(event);
}
});
}
private static int keyForCode(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_0:
return SysKey.NUM_0;
case KeyEvent.KEYCODE_1:
return SysKey.NUM_1;
case KeyEvent.KEYCODE_2:
return SysKey.NUM_2;
case KeyEvent.KEYCODE_3:
return SysKey.NUM_3;
case KeyEvent.KEYCODE_4:
return SysKey.NUM_4;
case KeyEvent.KEYCODE_5:
return SysKey.NUM_5;
case KeyEvent.KEYCODE_6:
return SysKey.NUM_6;
case KeyEvent.KEYCODE_7:
return SysKey.NUM_7;
case KeyEvent.KEYCODE_8:
return SysKey.NUM_8;
case KeyEvent.KEYCODE_9:
return SysKey.NUM_9;
case KeyEvent.KEYCODE_A:
return SysKey.A;
case KeyEvent.KEYCODE_ALT_LEFT:
return SysKey.ALT_LEFT;
case KeyEvent.KEYCODE_ALT_RIGHT:
return SysKey.ALT_RIGHT;
case KeyEvent.KEYCODE_APOSTROPHE:
return SysKey.APOSTROPHE;
case KeyEvent.KEYCODE_AT:
return SysKey.AT;
case KeyEvent.KEYCODE_B:
return SysKey.B;
case KeyEvent.KEYCODE_BACK:
return SysKey.BACK;
case KeyEvent.KEYCODE_BACKSLASH:
return SysKey.BACKSLASH;
case KeyEvent.KEYCODE_C:
return SysKey.C;
case KeyEvent.KEYCODE_CALL:
return SysKey.CALL;
case KeyEvent.KEYCODE_CAMERA:
return SysKey.CAMERA;
case KeyEvent.KEYCODE_CLEAR:
return SysKey.CLEAR;
case KeyEvent.KEYCODE_COMMA:
return SysKey.COMMA;
case KeyEvent.KEYCODE_D:
return SysKey.D;
case KeyEvent.KEYCODE_DEL:
return SysKey.DEL;
case KeyEvent.KEYCODE_DPAD_CENTER:
return SysKey.DPAD_CENTER;
case KeyEvent.KEYCODE_DPAD_DOWN:
return SysKey.DPAD_DOWN;
case KeyEvent.KEYCODE_DPAD_LEFT:
return SysKey.DPAD_LEFT;
case KeyEvent.KEYCODE_DPAD_RIGHT:
return SysKey.DPAD_RIGHT;
case KeyEvent.KEYCODE_DPAD_UP:
return SysKey.DPAD_UP;
case KeyEvent.KEYCODE_E:
return SysKey.E;
case KeyEvent.KEYCODE_ENDCALL:
return SysKey.ENDCALL;
case KeyEvent.KEYCODE_ENTER:
return SysKey.ENTER;
case KeyEvent.KEYCODE_ENVELOPE:
return SysKey.ENVELOPE;
case KeyEvent.KEYCODE_EQUALS:
return SysKey.EQUALS;
case KeyEvent.KEYCODE_EXPLORER:
return SysKey.EXPLORER;
case KeyEvent.KEYCODE_F:
return SysKey.F;
case KeyEvent.KEYCODE_FOCUS:
return SysKey.FOCUS;
case KeyEvent.KEYCODE_G:
return SysKey.G;
case KeyEvent.KEYCODE_GRAVE:
return SysKey.GRAVE;
case KeyEvent.KEYCODE_H:
return SysKey.H;
case KeyEvent.KEYCODE_HEADSETHOOK:
return SysKey.HEADSETHOOK;
case KeyEvent.KEYCODE_HOME:
return SysKey.HOME;
case KeyEvent.KEYCODE_I:
return SysKey.I;
case KeyEvent.KEYCODE_J:
return SysKey.J;
case KeyEvent.KEYCODE_K:
return SysKey.K;
case KeyEvent.KEYCODE_L:
return SysKey.L;
case KeyEvent.KEYCODE_LEFT_BRACKET:
return SysKey.LEFT_BRACKET;
case KeyEvent.KEYCODE_M:
return SysKey.M;
case KeyEvent.KEYCODE_MENU:
return SysKey.MENU;
case KeyEvent.KEYCODE_MINUS:
return SysKey.MINUS;
case KeyEvent.KEYCODE_MUTE:
return SysKey.MUTE;
case KeyEvent.KEYCODE_N:
return SysKey.N;
case KeyEvent.KEYCODE_NOTIFICATION:
return SysKey.NOTIFICATION;
case KeyEvent.KEYCODE_NUM:
return SysKey.NUM;
case KeyEvent.KEYCODE_O:
return SysKey.O;
case KeyEvent.KEYCODE_P:
return SysKey.P;
case KeyEvent.KEYCODE_PAGE_DOWN:
return SysKey.PAGE_DOWN;
case KeyEvent.KEYCODE_PAGE_UP:
return SysKey.PAGE_UP;
case KeyEvent.KEYCODE_PERIOD:
return SysKey.PERIOD;
case KeyEvent.KEYCODE_PICTSYMBOLS:
return SysKey.PICTSYMBOLS;
case KeyEvent.KEYCODE_PLUS:
return SysKey.PLUS;
case KeyEvent.KEYCODE_POUND:
return SysKey.POUND;
case KeyEvent.KEYCODE_POWER:
return SysKey.POWER;
case KeyEvent.KEYCODE_Q:
return SysKey.Q;
case KeyEvent.KEYCODE_R:
return SysKey.R;
case KeyEvent.KEYCODE_RIGHT_BRACKET:
return SysKey.RIGHT_BRACKET;
case KeyEvent.KEYCODE_S:
return SysKey.S;
case KeyEvent.KEYCODE_SEARCH:
return SysKey.SEARCH;
case KeyEvent.KEYCODE_SEMICOLON:
return SysKey.SEMICOLON;
case KeyEvent.KEYCODE_SHIFT_LEFT:
return SysKey.SHIFT_LEFT;
case KeyEvent.KEYCODE_SHIFT_RIGHT:
return SysKey.SHIFT_RIGHT;
case KeyEvent.KEYCODE_SLASH:
return SysKey.SLASH;
case KeyEvent.KEYCODE_SOFT_LEFT:
return SysKey.SOFT_LEFT;
case KeyEvent.KEYCODE_SOFT_RIGHT:
return SysKey.SOFT_RIGHT;
case KeyEvent.KEYCODE_SPACE:
return SysKey.SPACE;
case KeyEvent.KEYCODE_STAR:
return SysKey.STAR;
case KeyEvent.KEYCODE_SWITCH_CHARSET:
return SysKey.SWITCH_CHARSET;
case KeyEvent.KEYCODE_SYM:
return SysKey.SYM;
case KeyEvent.KEYCODE_T:
return SysKey.T;
case KeyEvent.KEYCODE_TAB:
return SysKey.TAB;
case KeyEvent.KEYCODE_U:
return SysKey.U;
case KeyEvent.KEYCODE_UNKNOWN:
return SysKey.UNKNOWN;
case KeyEvent.KEYCODE_V:
return SysKey.V;
case KeyEvent.KEYCODE_VOLUME_DOWN:
return SysKey.VOLUME_DOWN;
case KeyEvent.KEYCODE_VOLUME_UP:
return SysKey.VOLUME_UP;
case KeyEvent.KEYCODE_W:
return SysKey.W;
case KeyEvent.KEYCODE_X:
return SysKey.X;
case KeyEvent.KEYCODE_Y:
return SysKey.Y;
case KeyEvent.KEYCODE_Z:
return SysKey.Z;
default:
return SysKey.UNKNOWN;
}
}
private TouchMake.Event[] parseMotionEvent(MotionEvent event,
TouchMake.Event.Kind kind) {
int actionType = event.getActionMasked();
boolean isChanged = (actionType == MotionEvent.ACTION_POINTER_UP || actionType == MotionEvent.ACTION_POINTER_DOWN);
int changedIdx = isChanged ? event.getActionIndex() : 0;
int count = event.getPointerCount();
TouchMake.Event[] touches = new TouchMake.Event[isChanged ? 1 : count];
double time = event.getEventTime();
int tidx = 0;
for (int tt = 0; tt < count; tt++) {
if (isChanged && tt != changedIdx) {
continue;
}
float pressure = event.getPressure(tt);
float size = event.getSize(tt);
int id = event.getPointerId(tt);
touches[tidx++] = new TouchMake.Event(0, time, event.getX(tt),
event.getY(tt),
kind, id, pressure, size);
}
return touches;
}
private static TouchMake.Event.Kind[] TO_KIND = new TouchMake.Event.Kind[16];
static {
TO_KIND[MotionEvent.ACTION_DOWN] = TouchMake.Event.Kind.START;
TO_KIND[MotionEvent.ACTION_UP] = TouchMake.Event.Kind.END;
TO_KIND[MotionEvent.ACTION_POINTER_DOWN] = TouchMake.Event.Kind.START;
TO_KIND[MotionEvent.ACTION_POINTER_UP] = TouchMake.Event.Kind.END;
TO_KIND[MotionEvent.ACTION_MOVE] = TouchMake.Event.Kind.MOVE;
TO_KIND[MotionEvent.ACTION_CANCEL] = TouchMake.Event.Kind.CANCEL;
}
@Override
public boolean hasTouch() {
return true;
}
@Override
public void callback(LObject<?> o) {
}
}