mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-03 00:46:55 +02:00
Implemented SDL2 unicode input. Hotkeys are sill broken.
This commit is contained in:
@ -18,6 +18,7 @@
|
||||
#include "../GUIClasses.h"
|
||||
#include "CGuiHandler.h"
|
||||
#include "../CAdvmapInterface.h"
|
||||
#include "../../lib/CGeneralTextHandler.h" //for Unicode related stuff
|
||||
|
||||
CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free )
|
||||
{
|
||||
@ -1545,7 +1546,7 @@ CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(co
|
||||
pos.w = Pos.w;
|
||||
captureAllKeys = true;
|
||||
bg = nullptr;
|
||||
addUsedEvents(LCLICK | KEYBOARD);
|
||||
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
||||
giveFocus();
|
||||
}
|
||||
|
||||
@ -1557,7 +1558,7 @@ CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::strin
|
||||
captureAllKeys = true;
|
||||
OBJ_CONSTRUCTION;
|
||||
bg = new CPicture(bgName, bgOffset.x, bgOffset.y);
|
||||
addUsedEvents(LCLICK | KEYBOARD);
|
||||
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
||||
giveFocus();
|
||||
}
|
||||
|
||||
@ -1576,13 +1577,35 @@ CTextInput::CTextInput(const Rect &Pos, SDL_Surface *srf)
|
||||
pos.w = bg->pos.w;
|
||||
pos.h = bg->pos.h;
|
||||
bg->pos = pos;
|
||||
addUsedEvents(LCLICK | KEYBOARD);
|
||||
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
|
||||
giveFocus();
|
||||
}
|
||||
|
||||
void CTextInput::focusGot()
|
||||
{
|
||||
#ifndef VCMI_SDL1
|
||||
if (SDL_IsTextInputActive() == SDL_FALSE)
|
||||
{
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
SDL_SetTextInputRect(&pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CTextInput::focusLost()
|
||||
{
|
||||
#ifndef VCMI_SDL1
|
||||
if (SDL_IsTextInputActive() == SDL_TRUE)
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::string CTextInput::visibleText()
|
||||
{
|
||||
return focus ? text + "_" : text;
|
||||
return focus ? text + newText + "_" : text;
|
||||
}
|
||||
|
||||
void CTextInput::clickLeft( tribool down, bool previousState )
|
||||
@ -1593,6 +1616,30 @@ void CTextInput::clickLeft( tribool down, bool previousState )
|
||||
|
||||
void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
|
||||
{
|
||||
auto trim = [](std::string & s){
|
||||
if(s.empty())
|
||||
return;
|
||||
auto b = s.begin();
|
||||
auto e = s.end();
|
||||
size_t lastLen = 0;
|
||||
size_t len = 0;
|
||||
while (b != e) {
|
||||
lastLen = len;
|
||||
size_t n = Unicode::getCharacterSize(*b);
|
||||
|
||||
if(!Unicode::isValidCharacter(&(*b),e-b))
|
||||
{
|
||||
logGlobal->errorStream() << "Invalid UTF8 sequence";
|
||||
break;//invalid sequence will be trimmed
|
||||
}
|
||||
|
||||
len += n;
|
||||
b += n;
|
||||
}
|
||||
|
||||
s.resize(lastLen);
|
||||
};
|
||||
|
||||
if(!focus || key.state != SDL_PRESSED)
|
||||
return;
|
||||
|
||||
@ -1603,32 +1650,43 @@ void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
|
||||
return;
|
||||
}
|
||||
|
||||
std::string oldText = text;
|
||||
bool redrawNeeded = false;
|
||||
switch(key.keysym.sym)
|
||||
{
|
||||
case SDLK_DELETE: // have index > ' ' so it won't be filtered out by default section
|
||||
return;
|
||||
case SDLK_BACKSPACE:
|
||||
if(!text.empty())
|
||||
text.resize(text.size()-1);
|
||||
if(!newText.empty())
|
||||
{
|
||||
trim(newText);
|
||||
redrawNeeded = true;
|
||||
}
|
||||
else if(!text.empty())
|
||||
{
|
||||
trim(text);
|
||||
redrawNeeded = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#ifdef VCMI_SDL1
|
||||
if (key.keysym.unicode < ' ')
|
||||
return;
|
||||
else
|
||||
{
|
||||
text += key.keysym.unicode; //TODO 16-/>8
|
||||
redrawNeeded = true;
|
||||
}
|
||||
#endif // 0
|
||||
break;
|
||||
}
|
||||
#ifdef VCMI_SDL1
|
||||
filters(text, oldText);
|
||||
if (text != oldText)
|
||||
#endif // 0
|
||||
if (redrawNeeded)
|
||||
{
|
||||
redraw();
|
||||
cb(text);
|
||||
}
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
//todo: handle text input for SDL2
|
||||
}
|
||||
@ -1652,10 +1710,41 @@ bool CTextInput::captureThisEvent(const SDL_KeyboardEvent & key)
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false; //todo:CTextInput::captureThisEvent
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef VCMI_SDL1
|
||||
void CTextInput::textInputed(const SDL_TextInputEvent & event)
|
||||
{
|
||||
if(!focus)
|
||||
return;
|
||||
std::string oldText = text;
|
||||
|
||||
text += event.text;
|
||||
|
||||
filters(text,oldText);
|
||||
if (text != oldText)
|
||||
{
|
||||
redraw();
|
||||
cb(text);
|
||||
}
|
||||
newText = "";
|
||||
}
|
||||
|
||||
void CTextInput::textEdited(const SDL_TextEditingEvent & event)
|
||||
{
|
||||
if(!focus)
|
||||
return;
|
||||
|
||||
newText = event.text;
|
||||
redraw();
|
||||
cb(text+newText);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void CTextInput::filenameFilter(std::string & text, const std::string &)
|
||||
{
|
||||
static const std::string forbiddenChars = "<>:\"/\\|?*\r\n"; //if we are entering a filename, some special characters won't be allowed
|
||||
@ -1708,7 +1797,10 @@ CFocusable::CFocusable()
|
||||
CFocusable::~CFocusable()
|
||||
{
|
||||
if(inputWithFocus == this)
|
||||
{
|
||||
focusLost();
|
||||
inputWithFocus = nullptr;
|
||||
}
|
||||
|
||||
focusables -= this;
|
||||
}
|
||||
@ -1717,12 +1809,14 @@ void CFocusable::giveFocus()
|
||||
if(inputWithFocus)
|
||||
{
|
||||
inputWithFocus->focus = false;
|
||||
inputWithFocus->focusLost();
|
||||
inputWithFocus->redraw();
|
||||
}
|
||||
|
||||
focus = true;
|
||||
inputWithFocus = this;
|
||||
redraw();
|
||||
focusGot();
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CFocusable::moveFocus()
|
||||
|
Reference in New Issue
Block a user