2023-05-18 19:32:29 +02:00
|
|
|
/*
|
|
|
|
* 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"
|
2024-04-30 18:10:10 +02:00
|
|
|
#include "../gui/Shortcut.h"
|
2023-05-18 19:32:29 +02:00
|
|
|
#include "../gui/ShortcutHandler.h"
|
2024-01-21 16:48:36 +02:00
|
|
|
#include "../CServerHandler.h"
|
|
|
|
#include "../globalLobby/GlobalLobbyClient.h"
|
2023-05-18 19:32:29 +02:00
|
|
|
|
2023-07-22 13:17:16 +02:00
|
|
|
#include <SDL_clipboard.h>
|
2023-05-18 19:32:29 +02:00
|
|
|
#include <SDL_events.h>
|
2023-05-19 17:56:20 +02:00
|
|
|
#include <SDL_hints.h>
|
|
|
|
|
|
|
|
InputSourceKeyboard::InputSourceKeyboard()
|
|
|
|
{
|
|
|
|
#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
|
|
|
|
}
|
2023-05-18 19:32:29 +02:00
|
|
|
|
|
|
|
void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
|
|
|
|
{
|
2024-04-11 20:13:26 +02:00
|
|
|
std::string keyName = SDL_GetKeyName(key.keysym.sym);
|
|
|
|
logGlobal->trace("keyboard: key '%s' pressed", keyName);
|
2024-01-21 16:48:36 +02:00
|
|
|
assert(key.state == SDL_PRESSED);
|
|
|
|
|
2023-07-04 17:42:52 +02:00
|
|
|
if (SDL_IsTextInputActive() == SDL_TRUE)
|
|
|
|
{
|
2023-07-22 14:36:13 +02:00
|
|
|
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;
|
2023-07-22 13:17:16 +02:00
|
|
|
}
|
|
|
|
|
2023-07-04 17:42:52 +02:00
|
|
|
if (key.keysym.sym >= ' ' && key.keysym.sym < 0x80)
|
|
|
|
return; // printable character - will be handled as text input
|
2023-07-22 13:17:16 +02:00
|
|
|
} else {
|
|
|
|
if(key.repeat != 0)
|
|
|
|
return; // ignore periodic event resends
|
2023-07-04 17:42:52 +02:00
|
|
|
}
|
|
|
|
|
2024-04-30 18:10:10 +02:00
|
|
|
auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
|
2024-01-21 16:48:36 +02:00
|
|
|
|
2024-04-30 18:10:10 +02:00
|
|
|
if (vstd::contains(shortcutsVector, EShortcut::LOBBY_ACTIVATE_INTERFACE))
|
2024-01-21 16:48:36 +02:00
|
|
|
CSH->getGlobalLobby().activateInterface();
|
2023-05-18 19:32:29 +02:00
|
|
|
|
2024-04-30 18:10:10 +02:00
|
|
|
if (vstd::contains(shortcutsVector, EShortcut::SPECTATE_TRACK_HERO))
|
2023-05-18 19:32:29 +02:00
|
|
|
{
|
|
|
|
Settings s = settings.write["session"];
|
2024-04-30 18:10:10 +02:00
|
|
|
s["spectate-ignore-hero"].Bool() = !settings["session"]["spectate-ignore-hero"].Bool();
|
|
|
|
}
|
2023-05-18 19:32:29 +02:00
|
|
|
|
2024-04-30 18:10:10 +02:00
|
|
|
if (vstd::contains(shortcutsVector, EShortcut::SPECTATE_SKIP_BATTLE))
|
|
|
|
{
|
|
|
|
Settings s = settings.write["session"];
|
|
|
|
s["spectate-skip-battle"].Bool() = !settings["session"]["spectate-skip-battle"].Bool();
|
|
|
|
}
|
2023-05-18 19:32:29 +02:00
|
|
|
|
2024-04-30 18:10:10 +02:00
|
|
|
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();
|
2023-05-18 19:32:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
GH.events().dispatchShortcutPressed(shortcutsVector);
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key)
|
|
|
|
{
|
|
|
|
if(key.repeat != 0)
|
|
|
|
return; // ignore periodic event resends
|
|
|
|
|
2024-04-11 20:13:26 +02:00
|
|
|
std::string keyName = SDL_GetKeyName(key.keysym.sym);
|
|
|
|
logGlobal->trace("keyboard: key '%s' released", keyName);
|
|
|
|
|
2023-07-04 17:42:52 +02:00
|
|
|
if (SDL_IsTextInputActive() == SDL_TRUE)
|
|
|
|
{
|
|
|
|
if (key.keysym.sym >= ' ' && key.keysym.sym < 0x80)
|
|
|
|
return; // printable character - will be handled as text input
|
|
|
|
}
|
|
|
|
|
2023-05-18 19:32:29 +02:00
|
|
|
assert(key.state == SDL_RELEASED);
|
|
|
|
|
2024-04-11 20:13:26 +02:00
|
|
|
auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
|
2023-05-18 19:32:29 +02:00
|
|
|
|
|
|
|
GH.events().dispatchShortcutReleased(shortcutsVector);
|
|
|
|
}
|
2023-05-26 14:57:53 +02:00
|
|
|
|
|
|
|
bool InputSourceKeyboard::isKeyboardCtrlDown() const
|
|
|
|
{
|
|
|
|
#ifdef VCMI_MAC
|
|
|
|
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::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];
|
|
|
|
}
|