1
0
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:
AlexVinS
2014-05-23 20:46:54 +04:00
committed by AlexVinS
parent d50976bf4a
commit ac2896da42
13 changed files with 215 additions and 63 deletions

View File

@ -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()