Update key repeat logic to use provided DPad keys

Implements a SetDPadKeys function akin to the Confirm/Cancel/TabLeft/TabRight
keys, and uses this vector of DPad keys to decide whether a KeyInput is a DPad
key or not.  Rewrites the held-key release logic in such a way that it still
ignores the deviceId, to handle the Ouya quirk where repeated events have
deviceId 0.
This commit is contained in:
Jonas Höglund 2015-08-28 20:51:33 +02:00
parent 32617ae17c
commit a57a838c93
5 changed files with 38 additions and 6 deletions

View File

@ -51,11 +51,30 @@ int MapPadButtonFixed(int keycode) {
} }
} }
std::vector<KeyDef> dpadKeys;
std::vector<KeyDef> confirmKeys; std::vector<KeyDef> confirmKeys;
std::vector<KeyDef> cancelKeys; std::vector<KeyDef> cancelKeys;
std::vector<KeyDef> tabLeftKeys; std::vector<KeyDef> tabLeftKeys;
std::vector<KeyDef> tabRightKeys; std::vector<KeyDef> tabRightKeys;
static void AppendKeys(std::vector<KeyDef> &keys, const std::vector<KeyDef> &newKeys) {
for (auto iter = newKeys.begin(); iter != newKeys.end(); ++iter) {
keys.push_back(*iter);
}
}
void SetDPadKeys(const std::vector<KeyDef> &leftKey, const std::vector<KeyDef> &rightKey,
const std::vector<KeyDef> &upKey, const std::vector<KeyDef> &downKey) {
dpadKeys.clear();
// Store all directions into one vector for now. In the future it might be
// useful to keep track of the different directions separately.
AppendKeys(dpadKeys, leftKey);
AppendKeys(dpadKeys, rightKey);
AppendKeys(dpadKeys, upKey);
AppendKeys(dpadKeys, downKey);
}
void SetConfirmCancelKeys(const std::vector<KeyDef> &confirm, const std::vector<KeyDef> &cancel) { void SetConfirmCancelKeys(const std::vector<KeyDef> &confirm, const std::vector<KeyDef> &cancel) {
confirmKeys = confirm; confirmKeys = confirm;
cancelKeys = cancel; cancelKeys = cancel;

View File

@ -240,9 +240,12 @@ private:
extern ButtonTracker g_buttonTracker; extern ButtonTracker g_buttonTracker;
// Is there a nicer place for this stuff? It's here to avoid dozens of linking errors in UnitTest.. // Is there a nicer place for this stuff? It's here to avoid dozens of linking errors in UnitTest..
extern std::vector<KeyDef> dpadKeys;
extern std::vector<KeyDef> confirmKeys; extern std::vector<KeyDef> confirmKeys;
extern std::vector<KeyDef> cancelKeys; extern std::vector<KeyDef> cancelKeys;
extern std::vector<KeyDef> tabLeftKeys; extern std::vector<KeyDef> tabLeftKeys;
extern std::vector<KeyDef> tabRightKeys; extern std::vector<KeyDef> tabRightKeys;
void SetDPadKeys(const std::vector<KeyDef> &leftKey, const std::vector<KeyDef> &rightKey,
const std::vector<KeyDef> &upKey, const std::vector<KeyDef> &downKey);
void SetConfirmCancelKeys(const std::vector<KeyDef> &confirm, const std::vector<KeyDef> &cancel); void SetConfirmCancelKeys(const std::vector<KeyDef> &confirm, const std::vector<KeyDef> &cancel);
void SetTabLeftRightKeys(const std::vector<KeyDef> &tabLeft, const std::vector<KeyDef> &tabRight); void SetTabLeftRightKeys(const std::vector<KeyDef> &tabLeft, const std::vector<KeyDef> &tabRight);

View File

@ -222,6 +222,14 @@ void Clickable::Touch(const TouchInput &input) {
// TODO: O/X confirm preference for xperia play? // TODO: O/X confirm preference for xperia play?
bool IsDPadKey(const KeyInput &key) {
if (dpadKeys.empty()) {
return key.keyCode >= NKCODE_DPAD_UP && key.keyCode <= NKCODE_DPAD_RIGHT;
} else {
return std::find(dpadKeys.begin(), dpadKeys.end(), KeyDef(key.deviceId, key.keyCode)) != dpadKeys.end();
}
}
bool IsAcceptKey(const KeyInput &key) { bool IsAcceptKey(const KeyInput &key) {
if (confirmKeys.empty()) { if (confirmKeys.empty()) {
if (key.deviceId == DEVICE_ID_KEYBOARD) { if (key.deviceId == DEVICE_ID_KEYBOARD) {

View File

@ -801,6 +801,7 @@ void MeasureBySpec(Size sz, float contentWidth, MeasureSpec spec, float *measure
void EventTriggered(Event *e, EventParams params); void EventTriggered(Event *e, EventParams params);
void DispatchEvents(); void DispatchEvents();
bool IsDPadKey(const KeyInput &key);
bool IsAcceptKey(const KeyInput &key); bool IsAcceptKey(const KeyInput &key);
bool IsEscapeKey(const KeyInput &key); bool IsEscapeKey(const KeyInput &key);
bool IsTabLeftKey(const KeyInput &key); bool IsTabLeftKey(const KeyInput &key);

View File

@ -1192,8 +1192,7 @@ bool KeyEvent(const KeyInput &key, ViewGroup *root) {
bool retval = false; bool retval = false;
// Ignore repeats for focus moves. // Ignore repeats for focus moves.
if ((key.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) { if ((key.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) {
// We ignore the device ID here. Anything with a DPAD is OK. if (IsDPadKey(key)) {
if (key.keyCode >= NKCODE_DPAD_UP && key.keyCode <= NKCODE_DPAD_RIGHT) {
// Let's only repeat DPAD initially. // Let's only repeat DPAD initially.
HeldKey hk; HeldKey hk;
hk.key = key.keyCode; hk.key = key.keyCode;
@ -1213,14 +1212,16 @@ bool KeyEvent(const KeyInput &key, ViewGroup *root) {
} }
} }
if (key.flags & KEY_UP) { if (key.flags & KEY_UP) {
// We ignore the device ID here. Anything with a DPAD is OK. // We ignore the device ID here (in the comparator for HeldKey), due to the Ouya quirk mentioned above.
if (key.keyCode >= NKCODE_DPAD_UP && key.keyCode <= NKCODE_DPAD_RIGHT) { if (!heldKeys.empty()) {
HeldKey hk; HeldKey hk;
hk.key = key.keyCode; hk.key = key.keyCode;
hk.deviceId = key.deviceId; hk.deviceId = key.deviceId;
hk.triggerTime = 0.0; // irrelevant hk.triggerTime = 0.0; // irrelevant
heldKeys.erase(hk); if (heldKeys.find(hk) != heldKeys.end()) {
retval = true; heldKeys.erase(hk);
retval = true;
}
} }
} }