From 23f87c10db7e6b149e9e1f351e1a82516c545df7 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 18 Apr 2012 02:58:23 +0300 Subject: First step for dehardcode input handling in widgets. Now widgets can check for input event. --- src/CMakeLists.txt | 4 + src/Makefile.am | 4 + src/gui/gui.cpp | 16 ++-- src/gui/sdlinput.cpp | 198 +++++++++++++++++++++++++------------------------ src/gui/sdlinput.h | 10 ++- src/inputevent.h | 3 + src/inputmanager.cpp | 26 ++++++- src/inputmanager.h | 5 +- src/joystick.cpp | 2 +- src/joystick.h | 2 + src/keyboardconfig.cpp | 11 ++- src/keyboardconfig.h | 4 + src/keyevent.cpp | 42 +++++++++++ src/keyevent.h | 52 +++++++++++++ src/keyinput.cpp | 32 ++++++++ src/keyinput.h | 45 +++++++++++ 16 files changed, 345 insertions(+), 111 deletions(-) create mode 100644 src/keyevent.cpp create mode 100644 src/keyevent.h create mode 100644 src/keyinput.cpp create mode 100644 src/keyinput.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d2a97f67..216538041 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -563,6 +563,10 @@ SET(SRCS keyboardconfig.h keyboarddata.h keydata.h + keyevent.cpp + keyevent.h + keyinput.cpp + keyinput.h listener.cpp listener.h localconsts.h diff --git a/src/Makefile.am b/src/Makefile.am index c1766628e..d56b0a537 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -581,6 +581,10 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ keyboardconfig.h \ keyboarddata.h \ keydata.h \ + keyevent.cpp \ + keyevent.h \ + keyinput.cpp \ + keyinput.h \ listener.cpp \ listener.h \ localconsts.h \ diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index e45bc71c0..61e434d77 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -35,6 +35,8 @@ #include "configlistener.h" #include "configuration.h" #include "graphics.h" +#include "keyevent.h" +#include "keyinput.h" #include "logger.h" #include "resources/image.h" @@ -284,11 +286,14 @@ bool Gui::handleInput() bool Gui::handleKeyInput2() { + if (!guiInput) + return false; + bool consumed(false); while (!mInput->isKeyQueueEmpty()) { - gcn::KeyInput keyInput = mInput->dequeueKeyInput(); + KeyInput keyInput = guiInput->dequeueKeyInput2(); // Save modifiers state mShiftPressed = keyInput.isShiftPressed(); @@ -296,9 +301,10 @@ bool Gui::handleKeyInput2() mControlPressed = keyInput.isControlPressed(); mAltPressed = keyInput.isAltPressed(); - gcn::KeyEvent keyEventToGlobalKeyListeners(nullptr, + KeyEvent keyEventToGlobalKeyListeners(nullptr, mShiftPressed, mControlPressed, mAltPressed, mMetaPressed, - keyInput.getType(), keyInput.isNumericPad(), keyInput.getKey()); + keyInput.getType(), keyInput.isNumericPad(), + keyInput.getActionId(), keyInput.getKey()); distributeKeyEventToGlobalKeyListeners( keyEventToGlobalKeyListeners); @@ -318,10 +324,10 @@ bool Gui::handleKeyInput2() // Send key inputs to the focused widgets if (mFocusHandler->getFocused()) { - gcn::KeyEvent keyEvent(getKeyEventSource(), + KeyEvent keyEvent(getKeyEventSource(), mShiftPressed, mControlPressed, mAltPressed, mMetaPressed, keyInput.getType(), keyInput.isNumericPad(), - keyInput.getKey()); + keyInput.getActionId(), keyInput.getKey()); if (!mFocusHandler->getFocused()->isFocusable()) mFocusHandler->focusNone(); diff --git a/src/gui/sdlinput.cpp b/src/gui/sdlinput.cpp index 3a4940d8b..94519469b 100644 --- a/src/gui/sdlinput.cpp +++ b/src/gui/sdlinput.cpp @@ -58,6 +58,10 @@ #include "sdlinput.h" +#include "keyinput.h" + +#include "inputmanager.h" + #include SDLInput::SDLInput() @@ -71,9 +75,9 @@ bool SDLInput::isKeyQueueEmpty() return mKeyInputQueue.empty(); } -gcn::KeyInput SDLInput::dequeueKeyInput() +KeyInput SDLInput::dequeueKeyInput2() { - gcn::KeyInput keyInput; + KeyInput keyInput; if (mKeyInputQueue.empty()) { @@ -108,107 +112,105 @@ gcn::MouseInput SDLInput::dequeueMouseInput() void SDLInput::pushInput(const SDL_Event &event) { - gcn::KeyInput keyInput; + KeyInput keyInput; gcn::MouseInput mouseInput; switch (event.type) { - case SDL_KEYDOWN: - keyInput.setKey(gcn::Key(convertKeyCharacter(event))); - keyInput.setType(gcn::KeyInput::PRESSED); - keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT); - keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL); - keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT); - keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META); - keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0 - && event.key.keysym.sym <= SDLK_KP_EQUALS); - - mKeyInputQueue.push(keyInput); - break; - - case SDL_KEYUP: - keyInput.setKey(gcn::Key(convertKeyCharacter(event))); - keyInput.setType(gcn::KeyInput::RELEASED); - keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT); - keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL); - keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT); - keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META); - keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0 - && event.key.keysym.sym <= SDLK_KP_EQUALS); - - mKeyInputQueue.push(keyInput); - break; - - case SDL_MOUSEBUTTONDOWN: - mMouseDown = true; - mouseInput.setX(event.button.x); - mouseInput.setY(event.button.y); - mouseInput.setButton(convertMouseButton(event.button.button)); - - if (event.button.button == SDL_BUTTON_WHEELDOWN) - { - mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_DOWN); - } - else if (event.button.button == SDL_BUTTON_WHEELUP) - { - mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_UP); - } - else - { - mouseInput.setType(gcn::MouseInput::PRESSED); - } - mouseInput.setTimeStamp(SDL_GetTicks()); - mMouseInputQueue.push(mouseInput); - break; - - case SDL_MOUSEBUTTONUP: - mMouseDown = false; - mouseInput.setX(event.button.x); - mouseInput.setY(event.button.y); - mouseInput.setButton(convertMouseButton(event.button.button)); - mouseInput.setType(gcn::MouseInput::RELEASED); - mouseInput.setTimeStamp(SDL_GetTicks()); - mMouseInputQueue.push(mouseInput); - break; - - case SDL_MOUSEMOTION: - mouseInput.setX(event.button.x); - mouseInput.setY(event.button.y); - mouseInput.setButton(gcn::MouseInput::EMPTY); - mouseInput.setType(gcn::MouseInput::MOVED); - mouseInput.setTimeStamp(SDL_GetTicks()); - mMouseInputQueue.push(mouseInput); - break; - - case SDL_ACTIVEEVENT: - /* - * This occurs when the mouse leaves the window and the Gui-chan - * application loses its mousefocus. - */ - if ((event.active.state & SDL_APPMOUSEFOCUS) - && !event.active.gain) - { - mMouseInWindow = false; - - if (!mMouseDown) - { - mouseInput.setX(-1); - mouseInput.setY(-1); - mouseInput.setButton(gcn::MouseInput::EMPTY); - mouseInput.setType(gcn::MouseInput::MOVED); - mMouseInputQueue.push(mouseInput); - } - } - - if ((event.active.state & SDL_APPMOUSEFOCUS) - && event.active.gain) - { - mMouseInWindow = true; - } - break; + case SDL_KEYDOWN: + { + keyInput.setKey(gcn::Key(convertKeyCharacter(event))); + keyInput.setType(gcn::KeyInput::PRESSED); + keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT); + keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL); + keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT); + keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META); + keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0 + && event.key.keysym.sym <= SDLK_KP_EQUALS); + int actionId = inputManager.getActionByKey(event); + if (actionId >= 0) + keyInput.setActionId(actionId); + mKeyInputQueue.push(keyInput); + break; + } - default: - break; + case SDL_KEYUP: + keyInput.setKey(gcn::Key(convertKeyCharacter(event))); + keyInput.setType(gcn::KeyInput::RELEASED); + keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT); + keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL); + keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT); + keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META); + keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0 + && event.key.keysym.sym <= SDLK_KP_EQUALS); + + mKeyInputQueue.push(keyInput); + break; + + case SDL_MOUSEBUTTONDOWN: + mMouseDown = true; + mouseInput.setX(event.button.x); + mouseInput.setY(event.button.y); + mouseInput.setButton(convertMouseButton(event.button.button)); + + if (event.button.button == SDL_BUTTON_WHEELDOWN) + mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_DOWN); + else if (event.button.button == SDL_BUTTON_WHEELUP) + mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_UP); + else + mouseInput.setType(gcn::MouseInput::PRESSED); + mouseInput.setTimeStamp(SDL_GetTicks()); + mMouseInputQueue.push(mouseInput); + break; + + case SDL_MOUSEBUTTONUP: + mMouseDown = false; + mouseInput.setX(event.button.x); + mouseInput.setY(event.button.y); + mouseInput.setButton(convertMouseButton(event.button.button)); + mouseInput.setType(gcn::MouseInput::RELEASED); + mouseInput.setTimeStamp(SDL_GetTicks()); + mMouseInputQueue.push(mouseInput); + break; + + case SDL_MOUSEMOTION: + mouseInput.setX(event.button.x); + mouseInput.setY(event.button.y); + mouseInput.setButton(gcn::MouseInput::EMPTY); + mouseInput.setType(gcn::MouseInput::MOVED); + mouseInput.setTimeStamp(SDL_GetTicks()); + mMouseInputQueue.push(mouseInput); + break; + + case SDL_ACTIVEEVENT: + /* + * This occurs when the mouse leaves the window and the Gui-chan + * application loses its mousefocus. + */ + if ((event.active.state & SDL_APPMOUSEFOCUS) + && !event.active.gain) + { + mMouseInWindow = false; + + if (!mMouseDown) + { + mouseInput.setX(-1); + mouseInput.setY(-1); + mouseInput.setButton(gcn::MouseInput::EMPTY); + mouseInput.setType(gcn::MouseInput::MOVED); + mMouseInputQueue.push(mouseInput); + } + } + + if ((event.active.state & SDL_APPMOUSEFOCUS) + && event.active.gain) + { + mMouseInWindow = true; + } + break; + + default: + break; } // end switch } diff --git a/src/gui/sdlinput.h b/src/gui/sdlinput.h index af74534c3..c3c0628ff 100644 --- a/src/gui/sdlinput.h +++ b/src/gui/sdlinput.h @@ -68,6 +68,8 @@ #include #include +class KeyInput; + namespace Key { enum @@ -150,13 +152,15 @@ public: virtual void _pollInput() { } + virtual KeyInput dequeueKeyInput2(); + + virtual gcn::KeyInput dequeueKeyInput() + { return gcn::KeyInput(); } // Inherited from Input virtual bool isKeyQueueEmpty(); - virtual gcn::KeyInput dequeueKeyInput(); - virtual bool isMouseQueueEmpty(); virtual gcn::MouseInput dequeueMouseInput(); @@ -180,7 +184,7 @@ protected: */ int convertKeyCharacter(SDL_Event event); - std::queue mKeyInputQueue; + std::queue mKeyInputQueue; std::queue mMouseInputQueue; bool mMouseDown; diff --git a/src/inputevent.h b/src/inputevent.h index b03c59669..b8e4ebd1b 100644 --- a/src/inputevent.h +++ b/src/inputevent.h @@ -31,6 +31,9 @@ typedef KeysVector::const_iterator KeysVectorCIter; typedef std::map KeyToActionMap; typedef KeyToActionMap::iterator KeyToActionMapIter; +typedef std::map KeyToIdMap; +typedef KeyToIdMap::iterator KeyToIdMapIter; + struct InputEvent { InputEvent(int action0, int mask0); diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp index 283b07d6c..fcb40d4ea 100644 --- a/src/inputmanager.cpp +++ b/src/inputmanager.cpp @@ -590,15 +590,16 @@ bool InputManager::invokeKey(const KeyData *key, int keyNum) return false; } -void InputManager::updateKeyActionMap(KeyToActionMap &actionMap, int type) +void InputManager::updateKeyActionMap(KeyToActionMap &actionMap, + KeyToIdMap &idMap, int type) { actionMap.clear(); for (size_t i = 0; i < Input::KEY_TOTAL; i ++) { + KeyFunction &key = mKey[i]; if (keyData[i].action) { - KeyFunction &key = mKey[i]; for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++) { const KeyItem &ki = key.values[i2]; @@ -606,6 +607,15 @@ void InputManager::updateKeyActionMap(KeyToActionMap &actionMap, int type) actionMap[ki.value].push_back(i); } } + if (keyData[i].configField && (keyData[i].grp & Input::GRP_GUI)) + { + for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++) + { + const KeyItem &ki = key.values[i2]; + if (ki.type == type && ki.value != -1) + idMap[ki.value] = i; + } + } } keySorter.keys = &keyData[0]; @@ -657,3 +667,15 @@ int InputManager::getKeyIndex(int value, int grp, int type) const } return Input::KEY_NO_VALUE; } + +int InputManager::getActionByKey(const SDL_Event &event) +{ + // for now support only keyboard events + if (event.type == SDL_KEYDOWN) + { + int idx = keyboard.getActionId(event); + if (idx >= 0 && checkKey(&keyData[idx])) + return idx; + } + return -1; +} diff --git a/src/inputmanager.h b/src/inputmanager.h index b8114d906..82e5fd5b7 100644 --- a/src/inputmanager.h +++ b/src/inputmanager.h @@ -134,7 +134,8 @@ class InputManager int getNewKeyIndex() const { return mNewKeyIndex; } - void updateKeyActionMap(KeyToActionMap &actionMap, int type); + void updateKeyActionMap(KeyToActionMap &actionMap, + KeyToIdMap &idMap, int type); bool invokeKey(const KeyData *key, int keyNum); @@ -148,6 +149,8 @@ class InputManager void updateConditionMask(); + int getActionByKey(const SDL_Event &event); + protected: Setup_Input *mSetupInput; /**< Reference to setup window */ diff --git a/src/joystick.cpp b/src/joystick.cpp index 3222c9825..694ac1526 100644 --- a/src/joystick.cpp +++ b/src/joystick.cpp @@ -260,7 +260,7 @@ void Joystick::getNames(std::vector &names) void Joystick::update() { - inputManager.updateKeyActionMap(mKeyToAction, INPUT_JOYSTICK); + inputManager.updateKeyActionMap(mKeyToAction, mKeyToId, INPUT_JOYSTICK); } KeysVector *Joystick::getActionVector(const SDL_Event &event) diff --git a/src/joystick.h b/src/joystick.h index 740fa7cbd..39e96964f 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -147,6 +147,8 @@ class Joystick KeyToActionMap mKeyToAction; + KeyToIdMap mKeyToId; + /** * Is joystick support enabled. */ diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp index c9f4fef38..1dc68df79 100644 --- a/src/keyboardconfig.cpp +++ b/src/keyboardconfig.cpp @@ -108,6 +108,15 @@ KeysVector *KeyboardConfig::getActionVector(const SDL_Event &event) return nullptr; } +int KeyboardConfig::getActionId(const SDL_Event &event) +{ + const int i = getKeyValueFromEvent(event); +// logger->log("getActionId: %d", i); + if (i != 0 && i < SDLK_LAST && mKeyToId.find(i) != mKeyToId.end()) + return mKeyToId[i]; + return -1; +} + bool KeyboardConfig::isActionActive(int index) const { if (!mActiveKeys) @@ -136,7 +145,7 @@ bool KeyboardConfig::isActionActive(int index) const void KeyboardConfig::update() { - inputManager.updateKeyActionMap(mKeyToAction, INPUT_KEYBOARD); + inputManager.updateKeyActionMap(mKeyToAction, mKeyToId, INPUT_KEYBOARD); } void KeyboardConfig::handleActicateKey(const SDL_Event &event) diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h index c06699b21..88d525522 100644 --- a/src/keyboardconfig.h +++ b/src/keyboardconfig.h @@ -85,6 +85,8 @@ class KeyboardConfig void handleDeActicateKey(const SDL_Event &event); + int getActionId(const SDL_Event &event); + private: bool mEnabled; /**< Flag to respond to key input */ @@ -93,6 +95,8 @@ class KeyboardConfig Uint8 *mActiveKeys2; /**< Stores a list of all the keys */ KeyToActionMap mKeyToAction; + + KeyToIdMap mKeyToId; }; extern KeyboardConfig keyboard; diff --git a/src/keyevent.cpp b/src/keyevent.cpp new file mode 100644 index 000000000..ca8635626 --- /dev/null +++ b/src/keyevent.cpp @@ -0,0 +1,42 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "keyevent.h" + +#include "debug.h" + +KeyEvent::KeyEvent(gcn::Widget* source, + bool shiftPressed, + bool controlPressed, + bool altPressed, + bool metaPressed, + unsigned int type, + bool numericPad, + int actionId, + const gcn::Key& key) : + gcn::KeyEvent(source, shiftPressed, controlPressed, altPressed, + metaPressed, type, numericPad, key), + mActionId(actionId) +{ +} + +KeyEvent::~KeyEvent() +{ +} diff --git a/src/keyevent.h b/src/keyevent.h new file mode 100644 index 000000000..b4a4e5b36 --- /dev/null +++ b/src/keyevent.h @@ -0,0 +1,52 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEYEVENT_H +#define KEYEVENT_H + +#include +#include +#include + +#include + +class KeyEvent : public gcn::KeyEvent +{ + public: + KeyEvent(gcn::Widget* source, + bool shiftPressed, + bool controlPressed, + bool altPressed, + bool metaPressed, + unsigned int type, + bool numericPad, + int actionId, + const gcn::Key& key); + + virtual ~KeyEvent(); + + int getActionId() + { return mActionId; } + + protected: + int mActionId; +}; + +#endif diff --git a/src/keyinput.cpp b/src/keyinput.cpp new file mode 100644 index 000000000..929b2da86 --- /dev/null +++ b/src/keyinput.cpp @@ -0,0 +1,32 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "keyinput.h" + +#include "debug.h" + +KeyInput::KeyInput() : + mActionId(-2) +{ +} + +KeyInput::~KeyInput() +{ +} diff --git a/src/keyinput.h b/src/keyinput.h new file mode 100644 index 000000000..c650bddad --- /dev/null +++ b/src/keyinput.h @@ -0,0 +1,45 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEYINPUT_H +#define KEYINPUT_H + +#include + +#include + +class KeyInput : public gcn::KeyInput +{ + public: + KeyInput(); + + ~KeyInput(); + + void setActionId(int n) + { mActionId = n; } + + int getActionId() + { return mActionId; } + + protected: + int mActionId; +}; + +#endif -- cgit v1.2.3-60-g2f50