KEYMAPPER: Untangle the dependencies between Action and Keymap

This commit is contained in:
Bastien Bouclet 2020-01-23 10:50:51 +01:00 committed by Filippos Karapetis
parent 03bd7541bd
commit 19de568e24
13 changed files with 71 additions and 55 deletions

View file

@ -28,12 +28,10 @@
namespace Common { namespace Common {
Action::Action(Keymap *boss, const char *i, String des) Action::Action(const char *i, const String &des) :
: _boss(boss), description(des), id(i) { id(i),
description(des) {
assert(i); assert(i);
assert(_boss);
_boss->addAction(this);
} }
void Action::addDefaultInputMapping(const String &hwId) { void Action::addDefaultInputMapping(const String &hwId) {

View file

@ -29,14 +29,10 @@
#include "common/array.h" #include "common/array.h"
#include "common/events.h" #include "common/events.h"
#include "common/func.h"
#include "common/str.h" #include "common/str.h"
namespace Common { namespace Common {
struct HardwareInput;
class Keymap;
struct KeyActionEntry { struct KeyActionEntry {
const char *id; const char *id;
const KeyState ks; const KeyState ks;
@ -54,12 +50,10 @@ struct Action {
Event event; Event event;
private: private:
Keymap *_boss;
Array<String> _defaultInputMapping; Array<String> _defaultInputMapping;
public: public:
Action(Keymap *boss, const char *id, String des = ""); Action(const char *id, const String &description = "");
void setEvent(const Event &evt) { void setEvent(const Event &evt) {
event = evt; event = evt;
@ -103,10 +97,6 @@ public:
return _defaultInputMapping; return _defaultInputMapping;
} }
Keymap *getParent() {
return _boss;
}
}; };
} // End of namespace Common } // End of namespace Common

View file

@ -89,6 +89,15 @@ public:
*/ */
const ActionArray &getMappedActions(const HardwareInput *hardwareInput) const; const ActionArray &getMappedActions(const HardwareInput *hardwareInput) const;
/**
* Adds a new Action to this Map
*
* Takes ownership of the action.
*
* @param action the Action to add
*/
void addAction(Action *action);
/** /**
* Get the list of all the Actions contained in this Keymap * Get the list of all the Actions contained in this Keymap
*/ */
@ -117,14 +126,6 @@ public:
void setEnabled(bool enabled) { _enabled = enabled; } void setEnabled(bool enabled) { _enabled = enabled; }
private: private:
friend struct Action;
/**
* Adds a new Action to this Map,
* adding it at the back of the internal array
* @param action the Action to add
*/
void addAction(Action *action);
const Action *findAction(const char *id) const; const Action *findAction(const char *id) const;

View file

@ -47,8 +47,11 @@ enum {
kReflowCmd = 'REFL' kReflowCmd = 'REFL'
}; };
RemapDialog::RemapDialog() RemapDialog::RemapDialog() :
: Dialog("KeyMapper"), _remapTimeout(0), _remapAction(nullptr) { Dialog("KeyMapper"),
_remapKeymap(nullptr),
_remapAction(nullptr),
_remapTimeout(0) {
_keymapper = g_system->getEventManager()->getKeymapper(); _keymapper = g_system->getEventManager()->getKeymapper();
assert(_keymapper); assert(_keymapper);
@ -162,7 +165,7 @@ void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 d
void RemapDialog::clearMapping(uint i) { void RemapDialog::clearMapping(uint i) {
debug(3, "clear the mapping %u", i); debug(3, "clear the mapping %u", i);
Action *action = _actions[i].action; Action *action = _actions[i].action;
Keymap *keymap = action->getParent(); Keymap *keymap = _actions[i].keymap;
keymap->unregisterMapping(action); keymap->unregisterMapping(action);
_changes = true; _changes = true;
@ -174,7 +177,7 @@ void RemapDialog::clearMapping(uint i) {
void RemapDialog::resetMapping(uint i) { void RemapDialog::resetMapping(uint i) {
debug(3, "Reset the mapping %u", i); debug(3, "Reset the mapping %u", i);
Action *action = _actions[i].action; Action *action = _actions[i].action;
Keymap *keymap = action->getParent(); Keymap *keymap = _actions[i].keymap;
keymap->resetMapping(action); keymap->resetMapping(action);
_changes = true; _changes = true;
@ -190,6 +193,7 @@ void RemapDialog::startRemapping(uint i) {
return; return;
} }
_remapKeymap = _actions[i].keymap;
_remapAction = _actions[i].action; _remapAction = _actions[i].action;
_remapTimeout = g_system->getMillis() + kRemapTimeoutDelay; _remapTimeout = g_system->getMillis() + kRemapTimeoutDelay;
_remapInputWatcher->startWatching(); _remapInputWatcher->startWatching();
@ -199,6 +203,7 @@ void RemapDialog::startRemapping(uint i) {
} }
void RemapDialog::stopRemapping() { void RemapDialog::stopRemapping() {
_remapKeymap = nullptr;
_remapAction = nullptr; _remapAction = nullptr;
refreshKeymap(); refreshKeymap();
@ -216,8 +221,7 @@ void RemapDialog::handleMouseDown(int x, int y, int button, int clickCount) {
void RemapDialog::handleTickle() { void RemapDialog::handleTickle() {
const HardwareInput *hardwareInput = _remapInputWatcher->checkForCapturedInput(); const HardwareInput *hardwareInput = _remapInputWatcher->checkForCapturedInput();
if (hardwareInput) { if (hardwareInput) {
Keymap *keymap = _remapAction->getParent(); _remapKeymap->registerMapping(_remapAction, hardwareInput);
keymap->registerMapping(_remapAction, hardwareInput);
_changes = true; _changes = true;
stopRemapping(); stopRemapping();
@ -251,6 +255,7 @@ void RemapDialog::loadKeymap() {
Keymap *km = _keymapTable[_kmPopUp->getSelectedTag()]; Keymap *km = _keymapTable[_kmPopUp->getSelectedTag()];
for (Keymap::ActionArray::const_iterator it = km->getActions().begin(); it != km->getActions().end(); ++it) { for (Keymap::ActionArray::const_iterator it = km->getActions().begin(); it != km->getActions().end(); ++it) {
ActionRow row; ActionRow row;
row.keymap = km;
row.action = *it; row.action = *it;
_actions.push_back(row); _actions.push_back(row);
@ -273,9 +278,7 @@ void RemapDialog::refreshKeymap() {
row.actionText->setLabel(row.action->description); row.actionText->setLabel(row.action->description);
Keymap *keymap = row.action->getParent(); Array<const HardwareInput *> mappedInputs = row.keymap->getActionMapping(row.action);
Array<const HardwareInput *> mappedInputs = keymap->getActionMapping(row.action);
String keysLabel; String keysLabel;
for (uint j = 0; j < mappedInputs.size(); j++) { for (uint j = 0; j < mappedInputs.size(); j++) {

View file

@ -55,6 +55,7 @@ public:
protected: protected:
struct ActionRow { struct ActionRow {
Keymap *keymap;
Common::Action *action; Common::Action *action;
GUI::StaticTextWidget *actionText; GUI::StaticTextWidget *actionText;
@ -62,7 +63,7 @@ protected:
GUI::ButtonWidget *clearButton; GUI::ButtonWidget *clearButton;
GUI::ButtonWidget *resetButton; GUI::ButtonWidget *resetButton;
ActionRow() : action(nullptr), actionText(nullptr), keyButton(nullptr), clearButton(nullptr), resetButton(nullptr) { } ActionRow() : keymap(nullptr), action(nullptr), actionText(nullptr), keyButton(nullptr), clearButton(nullptr), resetButton(nullptr) { }
}; };
void loadKeymap(); void loadKeymap();
@ -78,6 +79,7 @@ protected:
Common::Array<Keymap *> _keymapTable; Common::Array<Keymap *> _keymapTable;
InputWatcher *_remapInputWatcher; InputWatcher *_remapInputWatcher;
Keymap *_remapKeymap;
Action *_remapAction; Action *_remapAction;
uint32 _remapTimeout; uint32 _remapTimeout;

View file

@ -202,20 +202,24 @@ Common::Keymap *OSystem_SDL_Maemo::getGlobalKeymap() {
Action *act; Action *act;
act = new Action(globalMap, "CLKM", _("Click Mode")); act = new Action("CLKM", _("Click Mode"));
Event evt = Event(); Event evt = Event();
evt.type = EVENT_CUSTOM_BACKEND_ACTION; evt.type = EVENT_CUSTOM_BACKEND_ACTION;
evt.customType = Maemo::kEventClickMode; evt.customType = Maemo::kEventClickMode;
act->setEvent(evt); act->setEvent(evt);
globalMap->addAction(act);
act = new Action(globalMap, "LCLK", _("Left Click")); act = new Action("LCLK", _("Left Click"));
act->setLeftClickEvent(); act->setLeftClickEvent();
globalMap->addAction(act);
act = new Action(globalMap, "MCLK", _("Middle Click")); act = new Action("MCLK", _("Middle Click"));
act->setMiddleClickEvent(); act->setMiddleClickEvent();
globalMap->addAction(act);
act = new Action(globalMap, "RCLK", _("Right Click")); act = new Action("RCLK", _("Right Click"));
act->setRightClickEvent(); act->setRightClickEvent();
globalMap->addAction(act);
return globalMap; return globalMap;
} }

View file

@ -364,33 +364,41 @@ static void setupKeymapper(OSystem &system) {
// Now create the global keymap // Now create the global keymap
Keymap *primaryGlobalKeymap = new Keymap(Keymap::kKeymapTypeGlobal, kGlobalKeymapName); Keymap *primaryGlobalKeymap = new Keymap(Keymap::kKeymapTypeGlobal, kGlobalKeymapName);
Action *act; Action *act;
act = new Action(primaryGlobalKeymap, "MENU", _("Menu")); act = new Action("MENU", _("Menu"));
act->addDefaultInputMapping("C+F5"); act->addDefaultInputMapping("C+F5");
act->setEvent(EVENT_MAINMENU); act->setEvent(EVENT_MAINMENU);
primaryGlobalKeymap->addAction(act);
#ifdef ENABLE_VKEYBD #ifdef ENABLE_VKEYBD
act = new Action(primaryGlobalKeymap, "VIRT", _("Display keyboard")); act = new Action("VIRT", _("Display keyboard"));
act->addDefaultInputMapping("C+F7"); act->addDefaultInputMapping("C+F7");
act->setEvent(EVENT_VIRTUAL_KEYBOARD); act->setEvent(EVENT_VIRTUAL_KEYBOARD);
primaryGlobalKeymap->addAction(act);
#endif #endif
act = new Action(primaryGlobalKeymap, "REMP", _("Remap keys")); act = new Action("REMP", _("Remap keys"));
act->addDefaultInputMapping("C+F8"); act->addDefaultInputMapping("C+F8");
act->setEvent(EVENT_KEYMAPPER_REMAP); act->setEvent(EVENT_KEYMAPPER_REMAP);
primaryGlobalKeymap->addAction(act);
act = new Action(primaryGlobalKeymap, "FULS", _("Toggle fullscreen")); act = new Action("FULS", _("Toggle fullscreen"));
act->addDefaultInputMapping("A+RETURN"); act->addDefaultInputMapping("A+RETURN");
act->setKeyEvent(KeyState(KEYCODE_RETURN, ASCII_RETURN, KBD_ALT)); act->setKeyEvent(KeyState(KEYCODE_RETURN, ASCII_RETURN, KBD_ALT));
primaryGlobalKeymap->addAction(act);
act = new Action(primaryGlobalKeymap, "LCLK", _("Left Click")); act = new Action("LCLK", _("Left Click"));
act->setLeftClickEvent(); act->setLeftClickEvent();
primaryGlobalKeymap->addAction(act);
act = new Action(primaryGlobalKeymap, "MCLK", _("Middle Click")); act = new Action("MCLK", _("Middle Click"));
act->setMiddleClickEvent(); act->setMiddleClickEvent();
primaryGlobalKeymap->addAction(act);
act = new Action(primaryGlobalKeymap, "RCLK", _("Right Click")); act = new Action("RCLK", _("Right Click"));
act->setRightClickEvent(); act->setRightClickEvent();
primaryGlobalKeymap->addAction(act);
mapper->addGlobalKeymap(primaryGlobalKeymap); mapper->addGlobalKeymap(primaryGlobalKeymap);

View file

@ -635,9 +635,10 @@ void Engine::initKeymap() {
}; };
for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) { for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) {
Common::Action *const act = new Common::Action(engineKeyMap, keyActionEntries[i].id, keyActionEntries[i].description); Common::Action *const act = new Common::Action(keyActionEntries[i].id, keyActionEntries[i].description);
act->setKeyEvent(keyActionEntries[i].ks); act->setKeyEvent(keyActionEntries[i].ks);
act->addDefaultInputMapping(keyActionEntries[i].defaultHwId); act->addDefaultInputMapping(keyActionEntries[i].defaultHwId);
engineKeyMap->addAction(act);
} }
mapper->addGameKeymap(engineKeyMap); mapper->addGameKeymap(engineKeyMap);

View file

@ -374,15 +374,17 @@ void EoBCoreEngine::initKeymap() {
}; };
for (uint i = 0; i < ARRAYSIZE(keyActionEntries); ++i) { for (uint i = 0; i < ARRAYSIZE(keyActionEntries); ++i) {
Common::Action *const act = new Common::Action(engineKeyMap, keyActionEntries[i].id, keyActionEntries[i].description); Common::Action *const act = new Common::Action(keyActionEntries[i].id, keyActionEntries[i].description);
act->setKeyEvent(keyActionEntries[i].ks); act->setKeyEvent(keyActionEntries[i].ks);
act->addDefaultInputMapping(keyActionEntries[i].defaultHwId); act->addDefaultInputMapping(keyActionEntries[i].defaultHwId);
engineKeyMap->addAction(act);
} }
if (_flags.gameID == GI_EOB2) { if (_flags.gameID == GI_EOB2) {
Common::Action *const act = new Common::Action(engineKeyMap, "SL6", _("Spell Level 6")); Common::Action *const act = new Common::Action("SL6", _("Spell Level 6"));
act->setKeyEvent(Common::KeyState(Common::KEYCODE_6)); act->setKeyEvent(Common::KeyState(Common::KEYCODE_6));
act->addDefaultInputMapping("6"); act->addDefaultInputMapping("6");
engineKeyMap->addAction(act);
} }
mapper->addGameKeymap(engineKeyMap); mapper->addGameKeymap(engineKeyMap);

View file

@ -488,9 +488,10 @@ void LoLEngine::initKeymap() {
}; };
for (const Common::KeyActionEntry *entry = keyActionEntries; entry->id; ++entry) { for (const Common::KeyActionEntry *entry = keyActionEntries; entry->id; ++entry) {
Common::Action *const act = new Common::Action(engineKeyMap, entry->id, entry->description); Common::Action *const act = new Common::Action(entry->id, entry->description);
act->setKeyEvent(entry->ks); act->setKeyEvent(entry->ks);
act->addDefaultInputMapping(entry->defaultHwId); act->addDefaultInputMapping(entry->defaultHwId);
engineKeyMap->addAction(act);
} }
mapper->addGameKeymap(engineKeyMap); mapper->addGameKeymap(engineKeyMap);

View file

@ -903,27 +903,31 @@ void MohawkEngine_Riven::initKeymap() {
}; };
for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) { for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) {
Common::Action *const act = new Common::Action(engineKeyMap, keyActionEntries[i].id, keyActionEntries[i].description); Common::Action *const act = new Common::Action(keyActionEntries[i].id, keyActionEntries[i].description);
act->setKeyEvent(keyActionEntries[i].ks); act->setKeyEvent(keyActionEntries[i].ks);
act->addDefaultInputMapping(keyActionEntries[i].defaultHwId); act->addDefaultInputMapping(keyActionEntries[i].defaultHwId);
engineKeyMap->addAction(act);
} }
if (getFeatures() & GF_DEMO) { if (getFeatures() & GF_DEMO) {
for (uint i = 0; i < ARRAYSIZE(keyActionEntriesDemo); i++) { for (uint i = 0; i < ARRAYSIZE(keyActionEntriesDemo); i++) {
Common::Action* const act = new Common::Action(engineKeyMap, keyActionEntriesDemo[i].id, keyActionEntriesDemo[i].description); Common::Action* const act = new Common::Action(keyActionEntriesDemo[i].id, keyActionEntriesDemo[i].description);
act->setKeyEvent(keyActionEntriesDemo[i].ks); act->setKeyEvent(keyActionEntriesDemo[i].ks);
act->addDefaultInputMapping(keyActionEntriesDemo[i].defaultHwId); act->addDefaultInputMapping(keyActionEntriesDemo[i].defaultHwId);
engineKeyMap->addAction(act);
} }
} }
if (getFeatures() & GF_25TH) { if (getFeatures() & GF_25TH) {
Common::Action* const act = new Common::Action(engineKeyMap, "SMNU", _("Skip / Open main menu")); Common::Action* const act = new Common::Action("SMNU", _("Skip / Open main menu"));
act->setKeyEvent(Common::KEYCODE_ESCAPE); act->setKeyEvent(Common::KEYCODE_ESCAPE);
act->addDefaultInputMapping("ESCAPE"); act->addDefaultInputMapping("ESCAPE");
engineKeyMap->addAction(act);
} else { } else {
Common::Action* const act = new Common::Action(engineKeyMap, "SKIP", _("Skip")); Common::Action* const act = new Common::Action("SKIP", _("Skip"));
act->setKeyEvent(Common::KEYCODE_ESCAPE); act->setKeyEvent(Common::KEYCODE_ESCAPE);
act->addDefaultInputMapping("ESCAPE"); act->addDefaultInputMapping("ESCAPE");
engineKeyMap->addAction(act);
} }
mapper->addGameKeymap(engineKeyMap); mapper->addGameKeymap(engineKeyMap);

View file

@ -2517,9 +2517,10 @@ void PegasusEngine::initKeymap() {
}; };
for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) { for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) {
Common::Action *const act = new Common::Action(engineKeyMap, keyActionEntries[i].id, keyActionEntries[i].description); Common::Action *const act = new Common::Action(keyActionEntries[i].id, keyActionEntries[i].description);
act->setKeyEvent(keyActionEntries[i].ks); act->setKeyEvent(keyActionEntries[i].ks);
act->addDefaultInputMapping(keyActionEntries[i].defaultHwId); act->addDefaultInputMapping(keyActionEntries[i].defaultHwId);
engineKeyMap->addAction(act);
} }
mapper->addGameKeymap(engineKeyMap); mapper->addGameKeymap(engineKeyMap);

View file

@ -122,9 +122,10 @@ void GuiManager::initKeymap() {
Action *act; Action *act;
Keymap *guiMap = new Keymap(Keymap::kKeymapTypeGui, kGuiKeymapName); Keymap *guiMap = new Keymap(Keymap::kKeymapTypeGui, kGuiKeymapName);
act = new Action(guiMap, "CLOS", _("Close")); act = new Action("CLOS", _("Close"));
act->addDefaultInputMapping("ESCAPE"); act->addDefaultInputMapping("ESCAPE");
act->setKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0)); act->setKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
guiMap->addAction(act);
mapper->addGlobalKeymap(guiMap); mapper->addGlobalKeymap(guiMap);
} }