1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Simplified text input handling, fixes hotkeys on windows with text input

This commit is contained in:
Ivan Savenko 2023-07-04 18:42:52 +03:00
parent 81b9aec527
commit 900b1c1763
8 changed files with 58 additions and 41 deletions

View File

@ -96,7 +96,7 @@ void CInGameConsole::print(const std::string & txt)
auto splitText = CMessage::breakText(txt, maxWidth, FONT_MEDIUM);
for (auto const & entry : splitText)
for(const auto & entry : splitText)
texts.push_back({entry, 0});
while(texts.size() > maxDisplayedTexts)
@ -107,23 +107,43 @@ void CInGameConsole::print(const std::string & txt)
CCS->soundh->playSound("CHAT");
}
bool CInGameConsole::captureThisKey(EShortcut key)
{
if (enteredText.empty())
return false;
switch (key)
{
case EShortcut::GLOBAL_ACCEPT:
case EShortcut::GLOBAL_CANCEL:
case EShortcut::GAME_ACTIVATE_CONSOLE:
case EShortcut::GLOBAL_BACKSPACE:
case EShortcut::MOVE_UP:
case EShortcut::MOVE_DOWN:
return true;
default:
return false;
}
}
void CInGameConsole::keyPressed (EShortcut key)
{
if (LOCPLINT->cingconsole != this)
return;
if(!captureAllKeys && key != EShortcut::GAME_ACTIVATE_CONSOLE)
if(enteredText.empty() && key != EShortcut::GAME_ACTIVATE_CONSOLE)
return; //because user is not entering any text
switch(key)
{
case EShortcut::GLOBAL_CANCEL:
if(captureAllKeys)
if(!enteredText.empty())
endEnteringText(false);
break;
case EShortcut::GAME_ACTIVATE_CONSOLE:
if(captureAllKeys)
if(!enteredText.empty())
endEnteringText(false);
else
startEnteringText();
@ -131,7 +151,7 @@ void CInGameConsole::keyPressed (EShortcut key)
case EShortcut::GLOBAL_ACCEPT:
{
if(!enteredText.empty() && captureAllKeys)
if(!enteredText.empty())
{
bool anyTextExceptCaret = enteredText.size() > 1;
endEnteringText(anyTextExceptCaret);
@ -191,8 +211,9 @@ void CInGameConsole::textInputed(const std::string & inputtedText)
if (LOCPLINT->cingconsole != this)
return;
if(!captureAllKeys || enteredText.empty())
if(enteredText.empty())
return;
enteredText.resize(enteredText.size()-1);
enteredText += inputtedText;
@ -211,14 +232,10 @@ void CInGameConsole::startEnteringText()
if (!isActive())
return;
if (captureAllKeys)
return;
assert(currentStatusBar.expired());//effectively, nullptr check
currentStatusBar = GH.statusbar();
captureAllKeys = true;
enteredText = "_";
GH.statusbar()->setEnteringMode(true);
@ -227,7 +244,6 @@ void CInGameConsole::startEnteringText()
void CInGameConsole::endEnteringText(bool processEnteredText)
{
captureAllKeys = false;
prevEntDisp = -1;
if(processEnteredText)
{

View File

@ -50,6 +50,7 @@ public:
void keyPressed(EShortcut key) override;
void textInputed(const std::string & enteredText) override;
void textEdited(const std::string & enteredText) override;
bool captureThisKey(EShortcut key) override;
void startEnteringText();
void endEnteringText(bool processEnteredText);

View File

@ -33,6 +33,12 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
if(key.repeat != 0)
return; // ignore periodic event resends
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_PRESSED);
if(key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool())
@ -77,6 +83,12 @@ void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key)
if(key.repeat != 0)
return; // ignore periodic event resends
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(key.keysym.sym);

View File

@ -12,6 +12,7 @@
#include "CGuiHandler.h"
#include "WindowHandler.h"
#include "EventDispatcher.h"
#include "Shortcut.h"
#include "../render/Canvas.h"
#include "../windows/CMessage.h"
@ -22,7 +23,6 @@ CIntObject::CIntObject(int used_, Point pos_):
parent(parent_m),
redrawParent(false),
inputEnabled(true),
captureAllKeys(false),
used(used_),
recActions(GH.defActionsDef),
defActions(GH.defActionsDef),
@ -37,6 +37,8 @@ CIntObject::~CIntObject()
if(isActive())
deactivate();
GH.events().assertElementInactive(this);
while(!children.empty())
{
if((defActions & DISPOSE) && (children.front()->recActions & DISPOSE))
@ -148,15 +150,15 @@ void CIntObject::setInputEnabled(bool on)
inputEnabled = on;
if (!isActive())
return;
if (isActive())
{
assert((used & GENERAL) == 0);
assert((used & GENERAL) == 0);
if (on)
activateEvents(used);
else
deactivateEvents(used);
if (on)
activateEvents(used);
else
deactivateEvents(used);
}
for(auto & elem : children)
elem->setInputEnabled(on);
@ -207,6 +209,9 @@ void CIntObject::addChild(CIntObject * child, bool adjustPosition)
if(adjustPosition)
child->moveBy(pos.topLeft(), adjustPosition);
if (inputEnabled != child->inputEnabled)
child->setInputEnabled(inputEnabled);
if (!isActive() && child->isActive())
child->deactivate();
if (isActive()&& !child->isActive())
@ -292,7 +297,7 @@ const Rect & CIntObject::center(const Point & p, bool propagate)
bool CIntObject::captureThisKey(EShortcut key)
{
return captureAllKeys;
return false;
}
CKeyShortcut::CKeyShortcut()

View File

@ -62,10 +62,8 @@ public:
CIntObject(int used=0, Point offset=Point());
virtual ~CIntObject();
//keyboard handling
bool captureAllKeys; //if true, only this object should get info about pressed keys
bool captureThisKey(EShortcut key) override; //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
/// allows capturing key input so it will be delivered only to this element
bool captureThisKey(EShortcut key) override;
void addUsedEvents(ui16 newActions);
void removeUsedEvents(ui16 newActions);

View File

@ -310,7 +310,6 @@ CChatBox::CChatBox(const Rect & rect)
{
OBJ_CONSTRUCTION;
pos += rect.topLeft();
captureAllKeys = true;
setRedrawParent(true);
const int height = static_cast<int>(graphics->fonts[FONT_SMALL]->getLineHeight());

View File

@ -495,7 +495,6 @@ CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList<void(c
setRedrawParent(true);
pos.h = Pos.h;
pos.w = Pos.w;
captureAllKeys = true;
background.reset();
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
@ -511,7 +510,6 @@ CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const std::stri
pos.h = Pos.h;
pos.w = Pos.w;
captureAllKeys = true;
OBJ_CONSTRUCTION;
background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y);
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
@ -525,7 +523,6 @@ CTextInput::CTextInput(const Rect & Pos, std::shared_ptr<IImage> srf)
:CFocusable(std::make_shared<CKeyboardFocusListener>(this))
{
pos += Pos.topLeft();
captureAllKeys = true;
OBJ_CONSTRUCTION;
background = std::make_shared<CPicture>(srf, Pos);
pos.w = background->pos.w;
@ -620,17 +617,6 @@ void CTextInput::setText(const std::string & nText, bool callCb)
cb(text);
}
bool CTextInput::captureThisKey(EShortcut key)
{
if(key == EShortcut::GLOBAL_RETURN)
return false;
if (!focus)
return false;
return true;
}
void CTextInput::textInputed(const std::string & enteredText)
{
if(!focus)

View File

@ -227,7 +227,7 @@ public:
void clickLeft(tribool down, bool previousState) override;
void keyPressed(EShortcut key) override;
bool captureThisKey(EShortcut key) override;
//bool captureThisKey(EShortcut key) override;
void textInputed(const std::string & enteredText) override;
void textEdited(const std::string & enteredText) override;