mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Simplified text input handling, fixes hotkeys on windows with text input
This commit is contained in:
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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()
|
||||||
|
@@ -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);
|
||||||
|
@@ -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());
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user