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

View File

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

View File

@@ -33,6 +33,12 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
if(key.repeat != 0) if(key.repeat != 0)
return; // ignore periodic event resends 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); assert(key.state == SDL_PRESSED);
if(key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool()) 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) if(key.repeat != 0)
return; // ignore periodic event resends 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); assert(key.state == SDL_RELEASED);
auto shortcutsVector = GH.shortcuts().translateKeycode(key.keysym.sym); auto shortcutsVector = GH.shortcuts().translateKeycode(key.keysym.sym);

View File

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

View File

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

View File

@@ -310,7 +310,6 @@ CChatBox::CChatBox(const Rect & rect)
{ {
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
pos += rect.topLeft(); pos += rect.topLeft();
captureAllKeys = true;
setRedrawParent(true); setRedrawParent(true);
const int height = static_cast<int>(graphics->fonts[FONT_SMALL]->getLineHeight()); 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); setRedrawParent(true);
pos.h = Pos.h; pos.h = Pos.h;
pos.w = Pos.w; pos.w = Pos.w;
captureAllKeys = true;
background.reset(); background.reset();
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT); addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
@@ -511,7 +510,6 @@ CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const std::stri
pos.h = Pos.h; pos.h = Pos.h;
pos.w = Pos.w; pos.w = Pos.w;
captureAllKeys = true;
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y); background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y);
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT); addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
@@ -525,7 +523,6 @@ CTextInput::CTextInput(const Rect & Pos, std::shared_ptr<IImage> srf)
:CFocusable(std::make_shared<CKeyboardFocusListener>(this)) :CFocusable(std::make_shared<CKeyboardFocusListener>(this))
{ {
pos += Pos.topLeft(); pos += Pos.topLeft();
captureAllKeys = true;
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
background = std::make_shared<CPicture>(srf, Pos); background = std::make_shared<CPicture>(srf, Pos);
pos.w = background->pos.w; pos.w = background->pos.w;
@@ -620,17 +617,6 @@ void CTextInput::setText(const std::string & nText, bool callCb)
cb(text); 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) void CTextInput::textInputed(const std::string & enteredText)
{ {
if(!focus) if(!focus)

View File

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