mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-25 11:20:55 +00:00
Propagate input even return values in more places. Handle repeats better.
This commit is contained in:
parent
6739fc5654
commit
a3e23f0ac6
@ -412,11 +412,15 @@ extern "C" jboolean JNICALL Java_com_henrikrydgard_libnative_NativeApp_touch
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_keyDown(JNIEnv *, jclass, jint deviceId, jint key) {
|
||||
extern "C" jboolean Java_com_henrikrydgard_libnative_NativeApp_keyDown(JNIEnv *, jclass, jint deviceId, jint key, jboolean isRepeat) {
|
||||
KeyInput keyInput;
|
||||
keyInput.deviceId = deviceId;
|
||||
keyInput.keyCode = key;
|
||||
keyInput.flags = KEY_DOWN;
|
||||
if (isRepeat) {
|
||||
ILOG("Is repeat! %i", key);
|
||||
keyInput.flags |= KEY_IS_REPEAT;
|
||||
}
|
||||
return NativeKey(keyInput);
|
||||
}
|
||||
|
||||
|
@ -14,12 +14,12 @@ public class InputDeviceState {
|
||||
|
||||
// DEVICE_ID_PAD_0 from the cpp code. TODO: allocate these sequentially if we get more controllers.
|
||||
private static int deviceId = 10;
|
||||
|
||||
|
||||
private InputDevice mDevice;
|
||||
private int[] mAxes;
|
||||
|
||||
|
||||
InputDevice getDevice() { return mDevice; }
|
||||
|
||||
|
||||
@TargetApi(19)
|
||||
void logAdvanced(InputDevice device) {
|
||||
Log.i(TAG, "Vendor ID:" + device.getVendorId() + " productId: " + device.getProductId());
|
||||
@ -68,17 +68,13 @@ public class InputDeviceState {
|
||||
|
||||
public boolean onKeyDown(KeyEvent event) {
|
||||
int keyCode = event.getKeyCode();
|
||||
if (event.getRepeatCount() == 0) {
|
||||
NativeApp.keyDown(deviceId, keyCode);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
boolean repeat = event.getRepeatCount() > 0;
|
||||
return NativeApp.keyDown(deviceId, keyCode, repeat);
|
||||
}
|
||||
|
||||
public boolean onKeyUp(KeyEvent event) {
|
||||
int keyCode = event.getKeyCode();
|
||||
NativeApp.keyUp(deviceId, keyCode);
|
||||
return true;
|
||||
int keyCode = event.getKeyCode();
|
||||
return NativeApp.keyUp(deviceId, keyCode);
|
||||
}
|
||||
|
||||
public boolean onJoystickMotion(MotionEvent event) {
|
||||
|
@ -532,9 +532,6 @@ public class NativeActivity extends Activity {
|
||||
boolean passThrough = false;
|
||||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
||||
case KeyEvent.KEYCODE_VOLUME_UP:
|
||||
case KeyEvent.KEYCODE_VOLUME_MUTE:
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
passThrough = true;
|
||||
break;
|
||||
@ -608,25 +605,22 @@ public class NativeActivity extends Activity {
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
// Eat these keys, to avoid accidental exits / other screwups.
|
||||
// Maybe there's even more we need to eat on tablets?
|
||||
boolean repeat = event.getRepeatCount() > 0;
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (event.isAltPressed()) {
|
||||
NativeApp.keyDown(0, 1004); // special custom keycode
|
||||
NativeApp.keyDown(0, 1004, repeat); // special custom keycode
|
||||
} else if (NativeApp.isAtTopLevel()) {
|
||||
Log.i(TAG, "IsAtTopLevel returned true.");
|
||||
return super.onKeyDown(keyCode, event);
|
||||
} else {
|
||||
NativeApp.keyDown(0, keyCode);
|
||||
NativeApp.keyDown(0, keyCode, repeat);
|
||||
}
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
case KeyEvent.KEYCODE_SEARCH:
|
||||
NativeApp.keyDown(0, keyCode);
|
||||
NativeApp.keyDown(0, keyCode, repeat);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
||||
case KeyEvent.KEYCODE_VOLUME_UP:
|
||||
// NativeApp should ignore these.
|
||||
return super.onKeyDown(keyCode, event);
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
@ -641,8 +635,7 @@ public class NativeActivity extends Activity {
|
||||
// send the rest of the keys through.
|
||||
// TODO: get rid of the three special cases above by adjusting the native side of the code.
|
||||
// Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event);
|
||||
NativeApp.keyDown(0, keyCode);
|
||||
return true;
|
||||
return NativeApp.keyDown(0, keyCode, repeat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -665,9 +658,7 @@ public class NativeActivity extends Activity {
|
||||
// Search probably should also be ignored. We send it to the app.
|
||||
NativeApp.keyUp(0, keyCode);
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
||||
case KeyEvent.KEYCODE_VOLUME_UP:
|
||||
return super.onKeyUp(keyCode, event);
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
@ -681,8 +672,7 @@ public class NativeActivity extends Activity {
|
||||
// send the rest of the keys through.
|
||||
// TODO: get rid of the three special cases above by adjusting the native side of the code.
|
||||
// Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event);
|
||||
NativeApp.keyUp(0, keyCode);
|
||||
return true;
|
||||
return NativeApp.keyUp(0, keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ public class NativeApp {
|
||||
// There's not really any reason to ever call shutdown as we can recover from a killed activity.
|
||||
public static native void shutdown();
|
||||
|
||||
public static native boolean keyDown(int deviceId, int key);
|
||||
public static native boolean keyDown(int deviceId, int key, boolean isRepeat);
|
||||
public static native boolean keyUp(int deviceId, int key);
|
||||
|
||||
public static native void beginJoystickEvent();
|
||||
|
@ -71,6 +71,8 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener,
|
||||
|
||||
public boolean onTouchEvent(final MotionEvent ev) {
|
||||
boolean canReadToolType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
||||
|
||||
boolean retval = false;
|
||||
for (int i = 0; i < ev.getPointerCount(); i++) {
|
||||
int pid = ev.getPointerId(i);
|
||||
int code = 0;
|
||||
@ -101,11 +103,11 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener,
|
||||
int tool = getToolType(ev, i);
|
||||
code |= tool << 10; // We use the Android tool type codes
|
||||
}
|
||||
NativeApp.touch(ev.getX(i), ev.getY(i), code, pid);
|
||||
retval = retval || NativeApp.touch(ev.getX(i), ev.getY(i), code, pid);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Sensor management
|
||||
public void onAccuracyChanged(Sensor sensor, int arg1) {
|
||||
@ -165,9 +167,10 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener,
|
||||
}
|
||||
}
|
||||
|
||||
boolean repeat = false; // Moga has no repeats?
|
||||
switch (event.getAction()) {
|
||||
case KeyEvent.ACTION_DOWN:
|
||||
NativeApp.keyDown(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode());
|
||||
NativeApp.keyDown(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode(), repeat);
|
||||
break;
|
||||
case KeyEvent.ACTION_UP:
|
||||
NativeApp.keyUp(NativeApp.DEVICE_ID_PAD_0, event.getKeyCode());
|
||||
|
@ -65,4 +65,4 @@ public class NativeRenderer implements GLSurfaceView.Renderer {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -159,6 +159,7 @@ enum {
|
||||
KEY_DOWN = 1 << 0,
|
||||
KEY_UP = 1 << 1,
|
||||
KEY_HASWHEELDELTA = 1 << 2,
|
||||
KEY_IS_REPEAT = 1 << 3,
|
||||
};
|
||||
|
||||
struct KeyInput {
|
||||
|
@ -64,19 +64,28 @@ void ScreenManager::switchToNext() {
|
||||
UI::SetFocusedView(0);
|
||||
}
|
||||
|
||||
void ScreenManager::touch(const TouchInput &touch) {
|
||||
if (!stack_.empty())
|
||||
stack_.back().screen->touch(touch);
|
||||
bool ScreenManager::touch(const TouchInput &touch) {
|
||||
if (!stack_.empty()) {
|
||||
return stack_.back().screen->touch(touch);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::key(const KeyInput &key) {
|
||||
if (!stack_.empty())
|
||||
stack_.back().screen->key(key);
|
||||
bool ScreenManager::key(const KeyInput &key) {
|
||||
if (!stack_.empty()) {
|
||||
return stack_.back().screen->key(key);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::axis(const AxisInput &axis) {
|
||||
if (!stack_.empty())
|
||||
stack_.back().screen->axis(axis);
|
||||
bool ScreenManager::axis(const AxisInput &axis) {
|
||||
if (!stack_.empty()) {
|
||||
return stack_.back().screen->axis(axis);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::resized() {
|
||||
|
12
ui/screen.h
12
ui/screen.h
@ -49,9 +49,9 @@ public:
|
||||
virtual void deviceLost() {}
|
||||
virtual void resized() {}
|
||||
virtual void dialogFinished(const Screen *dialog, DialogResult result) {}
|
||||
virtual void touch(const TouchInput &touch) {}
|
||||
virtual void key(const KeyInput &key) {}
|
||||
virtual void axis(const AxisInput &touch) {}
|
||||
virtual bool touch(const TouchInput &touch) { return false; }
|
||||
virtual bool key(const KeyInput &key) { return false; }
|
||||
virtual bool axis(const AxisInput &touch) { return false; }
|
||||
virtual void sendMessage(const char *msg, const char *value) {}
|
||||
|
||||
virtual void RecreateViews() {}
|
||||
@ -109,9 +109,9 @@ public:
|
||||
void finishDialog(Screen *dialog, DialogResult result = DR_OK);
|
||||
|
||||
// Instant touch, separate from the update() mechanism.
|
||||
void touch(const TouchInput &touch);
|
||||
void key(const KeyInput &key);
|
||||
void axis(const AxisInput &touch);
|
||||
bool touch(const TouchInput &touch);
|
||||
bool key(const KeyInput &key);
|
||||
bool axis(const AxisInput &touch);
|
||||
|
||||
// Generic facility for gross hacks :P
|
||||
void sendMessage(const char *msg, const char *value);
|
||||
|
@ -48,19 +48,22 @@ void UIScreen::render() {
|
||||
}
|
||||
}
|
||||
|
||||
void UIScreen::touch(const TouchInput &touch) {
|
||||
bool UIScreen::touch(const TouchInput &touch) {
|
||||
if (root_) {
|
||||
UI::TouchEvent(touch, root_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UIScreen::key(const KeyInput &key) {
|
||||
bool UIScreen::key(const KeyInput &key) {
|
||||
if (root_) {
|
||||
UI::KeyEvent(key, root_);
|
||||
return UI::KeyEvent(key, root_);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UIDialogScreen::key(const KeyInput &key) {
|
||||
bool UIDialogScreen::key(const KeyInput &key) {
|
||||
if ((key.flags & KEY_DOWN) && UI::IsEscapeKeyCode(key.keyCode)) {
|
||||
if (finished_) {
|
||||
ELOG("Screen already finished");
|
||||
@ -68,12 +71,13 @@ void UIDialogScreen::key(const KeyInput &key) {
|
||||
finished_ = true;
|
||||
screenManager()->finishDialog(this, DR_BACK);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
UIScreen::key(key);
|
||||
return UIScreen::key(key);
|
||||
}
|
||||
}
|
||||
|
||||
void UIScreen::axis(const AxisInput &axis) {
|
||||
bool UIScreen::axis(const AxisInput &axis) {
|
||||
// Simple translation of hat to keys for Shield and other modern pads.
|
||||
// TODO: Use some variant of keymap?
|
||||
int flags = 0;
|
||||
@ -104,7 +108,9 @@ void UIScreen::axis(const AxisInput &axis) {
|
||||
hatDown_ = flags;
|
||||
if (root_) {
|
||||
UI::AxisEvent(axis, root_);
|
||||
return true;
|
||||
}
|
||||
return (pressed & (PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_UP | PAD_BUTTON_DOWN)) != 0;
|
||||
}
|
||||
|
||||
UI::EventReturn UIScreen::OnBack(UI::EventParams &e) {
|
||||
@ -131,16 +137,15 @@ PopupScreen::PopupScreen(std::string title, std::string button1, std::string but
|
||||
button2_ = d->T(button2.c_str());
|
||||
}
|
||||
|
||||
void PopupScreen::touch(const TouchInput &touch) {
|
||||
bool PopupScreen::touch(const TouchInput &touch) {
|
||||
if (!box_ || (touch.flags & TOUCH_DOWN) == 0 || touch.id != 0) {
|
||||
UIDialogScreen::touch(touch);
|
||||
return;
|
||||
return UIDialogScreen::touch(touch);
|
||||
}
|
||||
|
||||
if (!box_->GetBounds().Contains(touch.x, touch.y))
|
||||
screenManager()->finishDialog(this, DR_BACK);
|
||||
|
||||
UIDialogScreen::touch(touch);
|
||||
return UIDialogScreen::touch(touch);
|
||||
}
|
||||
|
||||
void PopupScreen::CreateViews() {
|
||||
|
@ -10,11 +10,12 @@ public:
|
||||
UIScreen();
|
||||
~UIScreen();
|
||||
|
||||
virtual void update(InputState &input);
|
||||
virtual void render();
|
||||
virtual void touch(const TouchInput &touch);
|
||||
virtual void key(const KeyInput &touch);
|
||||
virtual void axis(const AxisInput &touch);
|
||||
virtual void update(InputState &input) override;
|
||||
virtual void render() override;
|
||||
|
||||
virtual bool touch(const TouchInput &touch) override;
|
||||
virtual bool key(const KeyInput &touch) override;
|
||||
virtual bool axis(const AxisInput &touch) override;
|
||||
|
||||
// Some useful default event handlers
|
||||
UI::EventReturn OnOK(UI::EventParams &e);
|
||||
@ -39,7 +40,7 @@ private:
|
||||
class UIDialogScreen : public UIScreen {
|
||||
public:
|
||||
UIDialogScreen() : UIScreen(), finished_(false) {}
|
||||
virtual void key(const KeyInput &key);
|
||||
virtual bool key(const KeyInput &key) override;
|
||||
|
||||
private:
|
||||
bool finished_;
|
||||
@ -51,9 +52,9 @@ public:
|
||||
PopupScreen(std::string title, std::string button1 = "", std::string button2 = "");
|
||||
|
||||
virtual void CreatePopupContents(UI::ViewGroup *parent) = 0;
|
||||
virtual void CreateViews();
|
||||
virtual bool isTransparent() const { return true; }
|
||||
virtual void touch(const TouchInput &touch);
|
||||
virtual void CreateViews() override;
|
||||
virtual bool isTransparent() const override { return true; }
|
||||
virtual bool touch(const TouchInput &touch) override;
|
||||
|
||||
protected:
|
||||
virtual bool FillVertical() const { return false; }
|
||||
|
@ -1122,8 +1122,10 @@ static std::set<HeldKey> heldKeys;
|
||||
static const int repeatDelay = 15; // 250ms
|
||||
static const int repeatInterval = 5; // 66ms
|
||||
|
||||
void KeyEvent(const KeyInput &key, ViewGroup *root) {
|
||||
if (key.flags & KEY_DOWN) {
|
||||
bool KeyEvent(const KeyInput &key, ViewGroup *root) {
|
||||
bool retval = false;
|
||||
// Ignore repeats for focus moves.
|
||||
if ((key.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) {
|
||||
// We ignore the device ID here. Anything with a DPAD is OK.
|
||||
if (key.keyCode >= NKCODE_DPAD_UP && key.keyCode <= NKCODE_DPAD_RIGHT) {
|
||||
// Let's only repeat DPAD initially.
|
||||
@ -1135,12 +1137,13 @@ void KeyEvent(const KeyInput &key, ViewGroup *root) {
|
||||
// Check if the key is already held. If it is, ignore it. This is to avoid
|
||||
// multiple key repeat mechanisms colliding.
|
||||
if (heldKeys.find(hk) != heldKeys.end()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
heldKeys.insert(hk);
|
||||
lock_guard lock(focusLock);
|
||||
focusMoves.push_back(key.keyCode);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
if (key.flags & KEY_UP) {
|
||||
@ -1151,9 +1154,23 @@ void KeyEvent(const KeyInput &key, ViewGroup *root) {
|
||||
hk.deviceId = key.deviceId;
|
||||
hk.startFrame = 0; // irrelevant
|
||||
heldKeys.erase(hk);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
|
||||
root->Key(key);
|
||||
retval = true;
|
||||
|
||||
// Ignore volume keys and stuff here. Not elegant but need to propagate bools through the view hierarchy as well...
|
||||
switch (key.keyCode) {
|
||||
case NKCODE_VOLUME_DOWN:
|
||||
case NKCODE_VOLUME_UP:
|
||||
case NKCODE_VOLUME_MUTE:
|
||||
retval = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ProcessHeldKeys(ViewGroup *root) {
|
||||
@ -1174,14 +1191,16 @@ static void ProcessHeldKeys(ViewGroup *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void TouchEvent(const TouchInput &touch, ViewGroup *root) {
|
||||
bool TouchEvent(const TouchInput &touch, ViewGroup *root) {
|
||||
EnableFocusMovement(false);
|
||||
|
||||
root->Touch(touch);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AxisEvent(const AxisInput &axis, ViewGroup *root) {
|
||||
bool AxisEvent(const AxisInput &axis, ViewGroup *root) {
|
||||
root->Axis(axis);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateViewHierarchy(const InputState &input_state, ViewGroup *root) {
|
||||
|
@ -377,9 +377,9 @@ private:
|
||||
void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root);
|
||||
void UpdateViewHierarchy(const InputState &input_state, ViewGroup *root);
|
||||
// Hooks arrow keys for navigation
|
||||
void KeyEvent(const KeyInput &key, ViewGroup *root);
|
||||
void TouchEvent(const TouchInput &touch, ViewGroup *root);
|
||||
void AxisEvent(const AxisInput &axis, ViewGroup *root);
|
||||
bool KeyEvent(const KeyInput &key, ViewGroup *root);
|
||||
bool TouchEvent(const TouchInput &touch, ViewGroup *root);
|
||||
bool AxisEvent(const AxisInput &axis, ViewGroup *root);
|
||||
|
||||
void CaptureDrag(int id);
|
||||
void ReleaseDrag(int id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user