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> cancelKeys;
std::vector<KeyDef> tabLeftKeys;
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) {
confirmKeys = confirm;
cancelKeys = cancel;

View File

@ -240,9 +240,12 @@ private:
extern ButtonTracker g_buttonTracker;
// 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> cancelKeys;
extern std::vector<KeyDef> tabLeftKeys;
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 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?
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) {
if (confirmKeys.empty()) {
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 DispatchEvents();
bool IsDPadKey(const KeyInput &key);
bool IsAcceptKey(const KeyInput &key);
bool IsEscapeKey(const KeyInput &key);
bool IsTabLeftKey(const KeyInput &key);

View File

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