From 30ef016b0a14f36dc480284e2d775295b5501dd4 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 8 Apr 2012 19:41:19 +0300 Subject: Move most input code from keyboardconfig to inputmanager. --- src/inputmanager.cpp | 317 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 308 insertions(+), 9 deletions(-) (limited to 'src/inputmanager.cpp') diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp index 7610acf29..3a0b22f3e 100644 --- a/src/inputmanager.cpp +++ b/src/inputmanager.cpp @@ -20,9 +20,10 @@ #include "inputmanager.h" +#include "configuration.h" #include "game.h" #include "keyboardconfig.h" -#include "keydata.h" +#include "keyboarddata.h" #include "localplayer.h" #include "gui/chatwindow.h" @@ -31,6 +32,7 @@ #include "gui/npcdialog.h" #include "gui/npcpostdialog.h" #include "gui/setup.h" +#include "gui/setup_keyboard.h" #include "gui/textdialog.h" #include "gui/tradewindow.h" @@ -43,20 +45,317 @@ InputManager inputManager; extern QuitDialog *quitDialog; -InputManager::InputManager() +InputManager::InputManager() : + mSetupKey(nullptr), + mNewKeyIndex(Input::KEY_NO_VALUE) { } +void InputManager::init() +{ + for (int i = 0; i < Input::KEY_TOTAL; i++) + { + for (int f = 0; f < KeyFunctionSize; f ++) + { + mKey[i].values[f].type = INPUT_UNKNOWN; + mKey[i].values[f].value = -1; + } + } + + mNewKeyIndex = Input::KEY_NO_VALUE; + + makeDefault(); + retrieve(); + keyboard.updateKeyActionMap(); +} + +void InputManager::retrieve() +{ + for (int i = 0; i < Input::KEY_TOTAL; i++) + { + if (*keyData[i].configField) + { + KeyFunction &kf = mKey[i]; + std::string keyStr = config.getValue(keyData[i].configField, + toString(keyData[i].defaultValue)); + StringVect keys; + splitToStringVector(keys, keyStr, ','); + StringVectCIter it = keys.begin(); + StringVectCIter it_end = keys.end(); + int i2 = 0; + for (; it != it_end && i2 < KeyFunctionSize; ++ it) + { + std::string keyStr2 = *it; + if (keyStr.size() < 2) + continue; + int type = INPUT_KEYBOARD; + if ((keyStr2[0] < '0' || keyStr2[0] > '9') + && keyStr2[0] != '-') + { + switch (keyStr2[0]) + { + case 'm': + type = INPUT_MOUSE; + break; + case 'j': + type = INPUT_JOYSTICK; + break; + default: + break; + } + keyStr2 = keyStr2.substr(1); + } + int key = atoi(keyStr2.c_str()); + if (key >= -255 && key < SDLK_LAST) + { + kf.values[i2] = KeyItem(type, key); + i2 ++; + } + } + } + } +} + +void InputManager::store() +{ + for (int i = 0; i < Input::KEY_TOTAL; i++) + { + if (*keyData[i].configField) + { + std::string keyStr; + + for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++) + { + const KeyItem &key = mKey[i].values[i2]; + if (key.type != INPUT_UNKNOWN) + { + std::string tmp = "k"; + switch(key.type) + { + case INPUT_MOUSE: + tmp = "m"; + break; + case INPUT_JOYSTICK: + tmp = "j"; + break; + default: + break; + } + if (key.value >= 0) + { + if (keyStr.empty()) + { + keyStr = tmp + toString(key.value); + } + else + { + keyStr += strprintf(",%s%d", tmp.c_str(), key.value); + } + } + } + } + if (keyStr.empty()) + keyStr = "-1"; + + config.setValue(keyData[i].configField, keyStr); + } + } +} + +void InputManager::makeDefault() +{ + for (int i = 0; i < Input::KEY_TOTAL; i++) + { + for (size_t i2 = 1; i2 < KeyFunctionSize; i2 ++) + { + mKey[i].values[i2].type = INPUT_UNKNOWN; + mKey[i].values[i2].value = -1; + } + mKey[i].values[0].type = INPUT_KEYBOARD; + mKey[i].values[0].value = keyData[i].defaultValue; + } +} + +bool InputManager::hasConflicts(int &key1, int &key2) +{ + size_t i; + size_t j; + /** + * No need to parse the square matrix: only check one triangle + * that's enough to detect conflicts + */ + for (i = 0; i < Input::KEY_TOTAL; i++) + { + if (!*keyData[i].configField) + continue; + + for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++) + { + if (mKey[i].values[i2].value == Input::KEY_NO_VALUE) + continue; + + for (j = i, j++; j < Input::KEY_TOTAL; j++) + { + + if ((keyData[i].grp & keyData[j].grp) == 0 || + !*keyData[i].configField) + { + continue; + } + + for (size_t j2 = 0; j2 < KeyFunctionSize; j2 ++) + { + // Allow for item shortcut and emote keys to overlap + // as well as emote and ignore keys, but no other keys + if (mKey[j].values[j2].type != INPUT_UNKNOWN + && mKey[i].values[i2].value == mKey[j].values[j2].value + && mKey[i].values[i2].type == mKey[j].values[j2].type) + { + key1 = i; + key2 = j; + return true; + } + } + } + } + } + return false; +} + +void InputManager::callbackNewKey() +{ + mSetupKey->newKeyCallback(mNewKeyIndex); +} + +bool InputManager::isActionActive(int index) const +{ + return keyboard.isActionActive(index); +} + +KeyFunction &InputManager::getKey(int index) +{ + if (index < 0 || index >= Input::KEY_TOTAL) + index = 0; + return mKey[index]; +} + +std::string InputManager::getKeyStringLong(int index) const +{ + std::string keyStr; + + for (size_t i = 0; i < KeyFunctionSize; i ++) + { + const KeyItem &key = mKey[index].values[i]; + if (key.type == INPUT_KEYBOARD) + { + if (key.value >= 0) + { + std::string str = keyboard.getKeyName(key.value); + if (!str.empty()) + { + if (keyStr.empty()) + keyStr = str; + else + keyStr += std::string(" ") + str; + } + } + } + } + + if (keyStr.empty()) + return _("unknown key"); + return keyStr; +} + +std::string InputManager::getKeyValueString(int index) const +{ + std::string keyStr; + + for (size_t i = 0; i < KeyFunctionSize; i ++) + { + const KeyItem &key = mKey[index].values[i]; + if (key.type == INPUT_KEYBOARD) + { + if (key.value >= 0) + { + std::string str = keyboard.getKeyShortString( + keyboard.getKeyName(key.value)); + if (!str.empty()) + { + if (keyStr.empty()) + keyStr = str; + else + keyStr += std::string(" ") + str; + } + } + } + } + + if (keyStr.empty()) + return _("u key"); + return keyStr; +} + +void InputManager::addActionKey(int action, int type, int val) +{ + if (action < 0 || action >= Input::KEY_TOTAL) + return; + + int idx = -1; + KeyFunction &key = mKey[action]; + for (size_t i = 0; i < KeyFunctionSize; i ++) + { + if (key.values[i].type == INPUT_UNKNOWN + || (key.values[i].type == INPUT_KEYBOARD + && key.values[i].value == val)) + { + idx = i; + break; + } + } + if (idx == -1) + { + for (size_t i = 1; i < KeyFunctionSize; i ++) + { + key.values[i - 1].type = key.values[i].type; + key.values[i - 1].value = key.values[i].value; + } + idx = KeyFunctionSize - 1; + } + + key.values[idx] = KeyItem(type, val); +} + +void InputManager::setNewKey(const SDL_Event &event) +{ + int val = keyboard.getKeyValueFromEvent(event); + + addActionKey(mNewKeyIndex, INPUT_KEYBOARD, val); + + keyboard.updateKeyActionMap(); +} + +void InputManager::unassignKey() +{ + KeyFunction &key = mKey[mNewKeyIndex]; + for (size_t i = 0; i < KeyFunctionSize; i ++) + { + key.values[i].type = INPUT_UNKNOWN; + key.values[i].value = -1; + } + keyboard.updateKeyActionMap(); +} + bool InputManager::handleEvent(const SDL_Event &event) { if (event.type == SDL_KEYDOWN) { if (setupWindow && setupWindow->isVisible() && - keyboard.getNewKeyIndex() > Input::KEY_NO_VALUE) + getNewKeyIndex() > Input::KEY_NO_VALUE) { - keyboard.setNewKey(event); - keyboard.callbackNewKey(); - keyboard.setNewKeyIndex(Input::KEY_NO_VALUE); + setNewKey(event); + callbackNewKey(); + setNewKeyIndex(Input::KEY_NO_VALUE); return true; } @@ -143,8 +442,8 @@ int InputManager::getInputConditionMask() if (!player_node || !player_node->getDisableGameModifiers()) mask += COND_EMODS; - if (!keyboard.isActionActive(Input::KEY_TARGET) - && !keyboard.isActionActive(Input::KEY_UNTARGET)) + if (!isActionActive(Input::KEY_TARGET) + && !isActionActive(Input::KEY_UNTARGET)) { mask += COND_NOTARGET; } @@ -158,5 +457,5 @@ bool InputManager::checkKey(const KeyData *key, int mask) return false; return (key->modKeyIndex == Input::KEY_NO_VALUE - || keyboard.isActionActive(key->modKeyIndex)); + || isActionActive(key->modKeyIndex)); } -- cgit v1.2.3-60-g2f50