123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- /*
- * InputSourceKeyboard.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "InputSourceKeyboard.h"
- #include "../../lib/CConfigHandler.h"
- #include "../CPlayerInterface.h"
- #include "../gui/CGuiHandler.h"
- #include "../gui/EventDispatcher.h"
- #include "../gui/Shortcut.h"
- #include "../gui/ShortcutHandler.h"
- #include "../CServerHandler.h"
- #include "../globalLobby/GlobalLobbyClient.h"
- #include <SDL_clipboard.h>
- #include <SDL_events.h>
- #include <SDL_hints.h>
- InputSourceKeyboard::InputSourceKeyboard()
- : handleBackRightMouseButton(settings["input"]["handleBackRightMouseButton"].Bool())
- {
- #ifdef VCMI_MAC
- // Ctrl+click should be treated as a right click on Mac OS X
- SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
- #endif
- SDL_SetHint(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, handleBackRightMouseButton ? "1" : "0");
- }
- std::string InputSourceKeyboard::getKeyNameWithModifiers(const std::string & keyName, bool keyUp)
- {
- std::string result;
- if(!keyUp)
- {
- wasKeyboardCtrlDown = isKeyboardCtrlDown();
- wasKeyboardAltDown = isKeyboardAltDown();
- wasKeyboardShiftDown = isKeyboardShiftDown();
- }
- if (wasKeyboardCtrlDown)
- result += "Ctrl+";
- if (wasKeyboardAltDown)
- result += "Alt+";
- if (wasKeyboardShiftDown)
- result += "Shift+";
- result += keyName;
- return result;
- }
- void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
- {
- std::string keyName = getKeyNameWithModifiers(SDL_GetKeyName(key.keysym.sym), false);
- logGlobal->trace("keyboard: key '%s' pressed", keyName);
- assert(key.state == SDL_PRESSED);
- if (SDL_IsTextInputActive() == SDL_TRUE)
- {
- if(key.keysym.sym == SDLK_v && isKeyboardCtrlDown())
- {
- char * clipboardBuffer = SDL_GetClipboardText();
- std::string clipboardContent = clipboardBuffer;
- boost::erase_all(clipboardContent, "\r");
- boost::erase_all(clipboardContent, "\n");
- GH.events().dispatchTextInput(clipboardContent);
- SDL_free(clipboardBuffer);
- return;
- }
- if (key.keysym.sym >= ' ' && key.keysym.sym < 0x80)
- return; // printable character - will be handled as text input
- } else {
- if(key.repeat != 0)
- return; // ignore periodic event resends
- }
- if(handleBackRightMouseButton && key.keysym.scancode == SDL_SCANCODE_AC_BACK) // on some android devices right mouse button is "back"
- {
- GH.events().dispatchShowPopup(GH.getCursorPosition(), settings["input"]["mouseToleranceDistance"].Integer());
- return;
- }
- auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
- if (vstd::contains(shortcutsVector, EShortcut::MAIN_MENU_LOBBY))
- CSH->getGlobalLobby().activateInterface();
- if (vstd::contains(shortcutsVector, EShortcut::GLOBAL_FULLSCREEN))
- {
- Settings full = settings.write["video"]["fullscreen"];
- full->Bool() = !full->Bool();
- GH.onScreenResize(true);
- }
- if (vstd::contains(shortcutsVector, EShortcut::SPECTATE_TRACK_HERO))
- {
- Settings s = settings.write["session"];
- s["spectate-ignore-hero"].Bool() = !settings["session"]["spectate-ignore-hero"].Bool();
- }
- if (vstd::contains(shortcutsVector, EShortcut::SPECTATE_SKIP_BATTLE))
- {
- Settings s = settings.write["session"];
- s["spectate-skip-battle"].Bool() = !settings["session"]["spectate-skip-battle"].Bool();
- }
- if (vstd::contains(shortcutsVector, EShortcut::SPECTATE_SKIP_BATTLE_RESULT))
- {
- Settings s = settings.write["session"];
- s["spectate-skip-battle-result"].Bool() = !settings["session"]["spectate-skip-battle-result"].Bool();
- }
- GH.events().dispatchShortcutPressed(shortcutsVector);
- }
- void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key)
- {
- if(key.repeat != 0)
- return; // ignore periodic event resends
- if(handleBackRightMouseButton && key.keysym.scancode == SDL_SCANCODE_AC_BACK) // on some android devices right mouse button is "back"
- {
- GH.events().dispatchClosePopup(GH.getCursorPosition());
- return;
- }
- std::string keyName = getKeyNameWithModifiers(SDL_GetKeyName(key.keysym.sym), true);
- logGlobal->trace("keyboard: key '%s' released", keyName);
- if (SDL_IsTextInputActive() == SDL_TRUE)
- {
- if (key.keysym.sym >= ' ' && key.keysym.sym < 0x80)
- return; // printable character - will be handled as text input
- }
- assert(key.state == SDL_RELEASED);
- auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
- GH.events().dispatchShortcutReleased(shortcutsVector);
- }
- bool InputSourceKeyboard::isKeyboardCmdDown() const
- {
- #ifdef VCMI_APPLE
- return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LGUI] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RGUI];
- #else
- return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LCTRL] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RCTRL];
- #endif
- }
- bool InputSourceKeyboard::isKeyboardCtrlDown() const
- {
- #ifdef VCMI_APPLE
- return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LCTRL] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RCTRL] ||
- SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LGUI] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RGUI];
- #else
- return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LCTRL] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RCTRL];
- #endif
- }
- bool InputSourceKeyboard::isKeyboardAltDown() const
- {
- return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LALT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RALT];
- }
- bool InputSourceKeyboard::isKeyboardShiftDown() const
- {
- return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LSHIFT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RSHIFT];
- }
|