mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-09 13:24:01 +00:00
Change the text input box to use SDL textinput events
Add a cheap replacement for SDL1 that doesn't have textinput events.
This commit is contained in:
parent
22e682cebc
commit
b8a9815de7
4 changed files with 174 additions and 108 deletions
153
Aquaria/DSQ.cpp
153
Aquaria/DSQ.cpp
|
@ -209,6 +209,8 @@ DSQ::DSQ(const std::string& fileSystem, const std::string& extraDataDir)
|
||||||
avgFPS.resize(user.video.fpsSmoothing);
|
avgFPS.resize(user.video.fpsSmoothing);
|
||||||
|
|
||||||
cursor = cursorGlow = 0;
|
cursor = cursorGlow = 0;
|
||||||
|
|
||||||
|
pTextInputHandler = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSQ::~DSQ()
|
DSQ::~DSQ()
|
||||||
|
@ -2816,24 +2818,6 @@ void DSQ::doSaveSlotMenu(SaveSlotMode ssm, const Vector &position)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void doAlphabetInputKey(int d, char c, char map[], std::string *text, char upper=0)
|
|
||||||
{
|
|
||||||
if (core->getKeyState(d) && !map[d])
|
|
||||||
{
|
|
||||||
char usec = c;
|
|
||||||
if (upper != 0 && (core->getKeyState(KEY_LSHIFT) || core->getKeyState(KEY_RSHIFT)))
|
|
||||||
{
|
|
||||||
usec = upper;
|
|
||||||
}
|
|
||||||
*text += usec;
|
|
||||||
map[d] = 1;
|
|
||||||
}
|
|
||||||
else if (!core->getKeyState(d) && map[d])
|
|
||||||
{
|
|
||||||
map[d] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSQ::onConfirmYes()
|
void DSQ::onConfirmYes()
|
||||||
{
|
{
|
||||||
confirmDone = 1;
|
confirmDone = 1;
|
||||||
|
@ -2988,9 +2972,32 @@ bool DSQ::confirm(const std::string &text, const std::string &image, bool ok, fl
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static std::string s_inputText;
|
||||||
|
|
||||||
|
static void enterTextInput(TextInputEvent ti, const char *text)
|
||||||
|
{
|
||||||
|
switch(ti)
|
||||||
|
{
|
||||||
|
case TEXTINP_TEXT:
|
||||||
|
if(*text)
|
||||||
|
s_inputText += text;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEXTINP_BACKSPACE:
|
||||||
|
if(!s_inputText.empty())
|
||||||
|
s_inputText.pop_back(); // FIXME: do proper utf-8 erase?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string DSQ::getUserInputString(std::string labelText, std::string t, bool allowNonLowerCase)
|
std::string DSQ::getUserInputString(std::string labelText, std::string t, bool allowNonLowerCase)
|
||||||
{
|
{
|
||||||
|
const std::string originalt = t;
|
||||||
float trans = 0.1f;
|
float trans = 0.1f;
|
||||||
|
t.swap(s_inputText); // store original text in case of recursive opening
|
||||||
|
const InputTextHandler oldInputHandler = pTextInputHandler;
|
||||||
|
pTextInputHandler = &enterTextInput;
|
||||||
|
|
||||||
bool pauseState = game->isPaused();
|
bool pauseState = game->isPaused();
|
||||||
|
|
||||||
|
@ -3017,16 +3024,15 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
||||||
inputText->position = Vector(-400 + 20,8+8);
|
inputText->position = Vector(-400 + 20,8+8);
|
||||||
bg->addChild(inputText, PM_POINTER);
|
bg->addChild(inputText, PM_POINTER);
|
||||||
|
|
||||||
|
this->beginTextInput();
|
||||||
|
|
||||||
|
|
||||||
bg->show();
|
bg->show();
|
||||||
run(trans);
|
run(trans);
|
||||||
|
|
||||||
|
|
||||||
std::string text = t;
|
s_inputText = t;
|
||||||
char map[256];
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
map[i] = 0;
|
|
||||||
bool delDown = false;
|
|
||||||
bool escDown = false;
|
bool escDown = false;
|
||||||
|
|
||||||
float dt = 1.0f/60.0f;
|
float dt = 1.0f/60.0f;
|
||||||
|
@ -3035,77 +3041,6 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (blink)
|
|
||||||
{
|
|
||||||
text.resize(text.size()-1);
|
|
||||||
inputText->setText(text);
|
|
||||||
}
|
|
||||||
if (inputText->getActualWidth() < 800-60)
|
|
||||||
{
|
|
||||||
doAlphabetInputKey(KEY_A, 'a', (char*)&map, &text, 'A');
|
|
||||||
doAlphabetInputKey(KEY_B, 'b', (char*)&map, &text, 'B');
|
|
||||||
doAlphabetInputKey(KEY_C, 'c', (char*)&map, &text, 'C');
|
|
||||||
doAlphabetInputKey(KEY_D, 'd', (char*)&map, &text, 'D');
|
|
||||||
doAlphabetInputKey(KEY_E, 'e', (char*)&map, &text, 'E');
|
|
||||||
doAlphabetInputKey(KEY_F, 'f', (char*)&map, &text, 'F');
|
|
||||||
doAlphabetInputKey(KEY_G, 'g', (char*)&map, &text, 'G');
|
|
||||||
doAlphabetInputKey(KEY_H, 'h', (char*)&map, &text, 'H');
|
|
||||||
doAlphabetInputKey(KEY_I, 'i', (char*)&map, &text, 'I');
|
|
||||||
doAlphabetInputKey(KEY_J, 'j', (char*)&map, &text, 'J');
|
|
||||||
doAlphabetInputKey(KEY_K, 'k', (char*)&map, &text, 'K');
|
|
||||||
doAlphabetInputKey(KEY_L, 'l', (char*)&map, &text, 'L');
|
|
||||||
doAlphabetInputKey(KEY_M, 'm', (char*)&map, &text, 'M');
|
|
||||||
doAlphabetInputKey(KEY_N, 'n', (char*)&map, &text, 'N');
|
|
||||||
doAlphabetInputKey(KEY_O, 'o', (char*)&map, &text, 'O');
|
|
||||||
doAlphabetInputKey(KEY_P, 'p', (char*)&map, &text, 'P');
|
|
||||||
doAlphabetInputKey(KEY_Q, 'q', (char*)&map, &text, 'Q');
|
|
||||||
doAlphabetInputKey(KEY_R, 'r', (char*)&map, &text, 'R');
|
|
||||||
doAlphabetInputKey(KEY_S, 's', (char*)&map, &text, 'S');
|
|
||||||
doAlphabetInputKey(KEY_T, 't', (char*)&map, &text, 'T');
|
|
||||||
doAlphabetInputKey(KEY_U, 'u', (char*)&map, &text, 'U');
|
|
||||||
doAlphabetInputKey(KEY_V, 'v', (char*)&map, &text, 'V');
|
|
||||||
doAlphabetInputKey(KEY_W, 'w', (char*)&map, &text, 'W');
|
|
||||||
doAlphabetInputKey(KEY_X, 'x', (char*)&map, &text, 'X');
|
|
||||||
doAlphabetInputKey(KEY_Y, 'y', (char*)&map, &text, 'Y');
|
|
||||||
doAlphabetInputKey(KEY_Z, 'z', (char*)&map, &text, 'Z');
|
|
||||||
doAlphabetInputKey(KEY_1, '1', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_2, '2', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_3, '3', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_4, '4', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_5, '5', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_6, '6', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_7, '7', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_8, '8', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_9, '9', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_0, '0', (char*)&map, &text);
|
|
||||||
|
|
||||||
doAlphabetInputKey(KEY_PERIOD, '.', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_SPACE, ' ', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_MINUS, '-', (char*)&map, &text, '_');
|
|
||||||
|
|
||||||
doAlphabetInputKey(KEY_TILDE, '~', (char*)&map, &text, '~');
|
|
||||||
doAlphabetInputKey(KEY_EQUALS, '=', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_LBRACKET, '(', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_RBRACKET, ')', (char*)&map, &text);
|
|
||||||
doAlphabetInputKey(KEY_SEMICOLON, ';', (char*)&map, &text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getKeyState(KEY_BACKSPACE))
|
|
||||||
{
|
|
||||||
if (!delDown)
|
|
||||||
{
|
|
||||||
if (!text.empty())
|
|
||||||
{
|
|
||||||
text.resize(text.size()-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delDown = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
blinkTimer += dt;
|
blinkTimer += dt;
|
||||||
if (blinkTimer > 0.2f)
|
if (blinkTimer > 0.2f)
|
||||||
{
|
{
|
||||||
|
@ -3113,12 +3048,6 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
||||||
blinkTimer = 0;
|
blinkTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blink)
|
|
||||||
{
|
|
||||||
text += "|";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (getKeyState(KEY_RETURN))
|
if (getKeyState(KEY_RETURN))
|
||||||
break;
|
break;
|
||||||
|
@ -3128,16 +3057,13 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
||||||
else if (escDown && !getKeyState(KEY_ESCAPE))
|
else if (escDown && !getKeyState(KEY_ESCAPE))
|
||||||
{
|
{
|
||||||
escDown = false;
|
escDown = false;
|
||||||
text = t;
|
s_inputText = originalt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
inputText->setText(text);
|
inputText->setText(blink ? s_inputText : s_inputText+"|");
|
||||||
run(dt);
|
run(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blink && !text.empty() && (text[text.size()-1] == '|'))
|
|
||||||
text.resize(text.size()-1);
|
|
||||||
|
|
||||||
sound->playSfx("Menu-Close");
|
sound->playSfx("Menu-Close");
|
||||||
|
|
||||||
|
|
||||||
|
@ -3155,11 +3081,16 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
||||||
game->togglePause(pauseState);
|
game->togglePause(pauseState);
|
||||||
|
|
||||||
if (!allowNonLowerCase)
|
if (!allowNonLowerCase)
|
||||||
stringToLower(text);
|
stringToLower(s_inputText);
|
||||||
|
|
||||||
debugLog("getUserInputString returned: " + text);
|
debugLog("getUserInputString returned: " + s_inputText);
|
||||||
|
|
||||||
return text;
|
this->endTextInput();
|
||||||
|
|
||||||
|
t.swap(s_inputText); // put original text back
|
||||||
|
pTextInputHandler = oldInputHandler;
|
||||||
|
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSQ::stopVoice()
|
void DSQ::stopVoice()
|
||||||
|
@ -4385,3 +4316,9 @@ bool DSQ::useJoystickInput() const
|
||||||
{
|
{
|
||||||
return lastInputMode == INPUT_JOYSTICK;
|
return lastInputMode == INPUT_JOYSTICK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DSQ::onTextInput(TextInputEvent ti, const char *text)
|
||||||
|
{
|
||||||
|
if(pTextInputHandler)
|
||||||
|
pTextInputHandler(ti, text);
|
||||||
|
}
|
||||||
|
|
|
@ -423,6 +423,10 @@ protected:
|
||||||
void onPlayVoice();
|
void onPlayVoice();
|
||||||
void onStopVoice();
|
void onStopVoice();
|
||||||
|
|
||||||
|
virtual void onTextInput(TextInputEvent ti, const char *text) OVERRIDE;
|
||||||
|
typedef void (*InputTextHandler)(TextInputEvent ti, const char *text);
|
||||||
|
InputTextHandler pTextInputHandler;
|
||||||
|
|
||||||
Entity **iter;
|
Entity **iter;
|
||||||
PauseQuad *blackout;
|
PauseQuad *blackout;
|
||||||
void updatepecue(float dt);
|
void updatepecue(float dt);
|
||||||
|
|
113
BBGE/Core.cpp
113
BBGE/Core.cpp
|
@ -449,6 +449,8 @@ Core::Core(const std::string &filesystem, const std::string& extraDataDir, int n
|
||||||
initPlatform(filesystem);
|
initPlatform(filesystem);
|
||||||
|
|
||||||
texmgr.spawnThreads(3);
|
texmgr.spawnThreads(3);
|
||||||
|
|
||||||
|
textInputOpenCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::initPlatform(const std::string &filesystem)
|
void Core::initPlatform(const std::string &filesystem)
|
||||||
|
@ -1356,6 +1358,30 @@ bool Core::doMouseConstraint()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::beginTextInput()
|
||||||
|
{
|
||||||
|
if(!textInputOpenCount)
|
||||||
|
{
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
SDL_StartTextInput();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
++textInputOpenCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::endTextInput()
|
||||||
|
{
|
||||||
|
assert(textInputOpenCount > 0);
|
||||||
|
--textInputOpenCount;
|
||||||
|
if(!textInputOpenCount)
|
||||||
|
{
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
SDL_StopTextInput();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector Core::pixelPosToVirtualCoords(int x, int y) const
|
Vector Core::pixelPosToVirtualCoords(int x, int y) const
|
||||||
{
|
{
|
||||||
const float mx = float(virtualWidth)/float(getWindowWidth());
|
const float mx = float(virtualWidth)/float(getWindowWidth());
|
||||||
|
@ -1375,6 +1401,62 @@ void Core::virtualCoordsToPixelPos(int& x, int& y, const Vector& p) const
|
||||||
y = py * (float(getWindowHeight())/float(virtualHeight));
|
y = py * (float(getWindowHeight())/float(virtualHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TextInputMapping
|
||||||
|
{
|
||||||
|
unsigned key;
|
||||||
|
char lower;
|
||||||
|
char upper;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is only used for SDL1, that doesn't have text input functionality
|
||||||
|
static const TextInputMapping textInputMap[]
|
||||||
|
{
|
||||||
|
{ KEY_A, 'a', 'A' },
|
||||||
|
{ KEY_B, 'b', 'B' },
|
||||||
|
{ KEY_C, 'c', 'C' },
|
||||||
|
{ KEY_D, 'd', 'D' },
|
||||||
|
{ KEY_E, 'e', 'E' },
|
||||||
|
{ KEY_F, 'f', 'F' },
|
||||||
|
{ KEY_G, 'g', 'G' },
|
||||||
|
{ KEY_H, 'h', 'H' },
|
||||||
|
{ KEY_I, 'i', 'I' },
|
||||||
|
{ KEY_J, 'j', 'J' },
|
||||||
|
{ KEY_K, 'k', 'K' },
|
||||||
|
{ KEY_L, 'l', 'L' },
|
||||||
|
{ KEY_M, 'm', 'M' },
|
||||||
|
{ KEY_N, 'n', 'N' },
|
||||||
|
{ KEY_O, 'o', 'O' },
|
||||||
|
{ KEY_P, 'p', 'P' },
|
||||||
|
{ KEY_Q, 'q', 'Q' },
|
||||||
|
{ KEY_R, 'r', 'R' },
|
||||||
|
{ KEY_S, 's', 'S' },
|
||||||
|
{ KEY_T, 't', 'T' },
|
||||||
|
{ KEY_U, 'u', 'U' },
|
||||||
|
{ KEY_V, 'v', 'V' },
|
||||||
|
{ KEY_W, 'w', 'W' },
|
||||||
|
{ KEY_X, 'x', 'X' },
|
||||||
|
{ KEY_Y, 'y', 'Y' },
|
||||||
|
{ KEY_Z, 'z', 'Z' },
|
||||||
|
{ KEY_1, '1', 0 },
|
||||||
|
{ KEY_2, '2', 0 },
|
||||||
|
{ KEY_3, '3', 0 },
|
||||||
|
{ KEY_4, '4', 0 },
|
||||||
|
{ KEY_5, '5', 0 },
|
||||||
|
{ KEY_6, '6', 0 },
|
||||||
|
{ KEY_7, '7', 0 },
|
||||||
|
{ KEY_8, '8', 0 },
|
||||||
|
{ KEY_9, '9', 0 },
|
||||||
|
{ KEY_0, '0', 0 },
|
||||||
|
{ KEY_PERIOD, '.', 0 },
|
||||||
|
{ KEY_SPACE, ' ', 0 },
|
||||||
|
{ KEY_MINUS, '-', '_' },
|
||||||
|
{ KEY_TILDE, '~', 0 },
|
||||||
|
{ KEY_EQUALS, '=', 0 },
|
||||||
|
{ KEY_LBRACKET, '(', 0 },
|
||||||
|
{ KEY_RBRACKET, ')', 0 },
|
||||||
|
{ KEY_SEMICOLON, ';', 0 }
|
||||||
|
};
|
||||||
|
|
||||||
void Core::onEvent(const SDL_Event& event)
|
void Core::onEvent(const SDL_Event& event)
|
||||||
{
|
{
|
||||||
const bool focus = window->hasFocus();
|
const bool focus = window->hasFocus();
|
||||||
|
@ -1409,6 +1491,28 @@ void Core::onEvent(const SDL_Event& event)
|
||||||
#endif
|
#endif
|
||||||
if(kidx < KEY_MAXARRAY)
|
if(kidx < KEY_MAXARRAY)
|
||||||
keys[kidx] = 1;
|
keys[kidx] = 1;
|
||||||
|
|
||||||
|
if(kidx == KEY_BACKSPACE && textInputOpenCount)
|
||||||
|
onTextInput(TEXTINP_BACKSPACE, NULL);
|
||||||
|
|
||||||
|
#if !SDL_VERSION_ATLEAST(2,0,0)
|
||||||
|
char c = 0;
|
||||||
|
for(size_t i = 0; i < Countof(textInputMap); ++i)
|
||||||
|
{
|
||||||
|
if(textInputMap[i].key == kidx)
|
||||||
|
{
|
||||||
|
if((event.key.keysym.mod & KMOD_SHIFT) && textInputMap[i].upper)
|
||||||
|
c = textInputMap[i].upper;
|
||||||
|
else
|
||||||
|
c = textInputMap[i].lower;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c)
|
||||||
|
{
|
||||||
|
const char buf[2] = { c, 0 };
|
||||||
|
onTextInput(TEXTINP_TEXT, &buf[0]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1499,6 +1603,15 @@ motion:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||||
|
case SDL_TEXTINPUT:
|
||||||
|
{
|
||||||
|
if(textInputOpenCount)
|
||||||
|
onTextInput(TEXTINP_TEXT, event.text.text);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
BBGE/Core.h
12
BBGE/Core.h
|
@ -60,6 +60,13 @@ enum CoreLayers
|
||||||
LR_NONE = -1
|
LR_NONE = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TextInputEvent
|
||||||
|
{
|
||||||
|
TEXTINP_TEXT,
|
||||||
|
TEXTINP_BACKSPACE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class AfterEffectManager;
|
class AfterEffectManager;
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
@ -463,6 +470,11 @@ protected:
|
||||||
|
|
||||||
bool doMouseConstraint();
|
bool doMouseConstraint();
|
||||||
|
|
||||||
|
virtual void onTextInput(TextInputEvent ti, const char *text) {}
|
||||||
|
void beginTextInput();
|
||||||
|
void endTextInput();
|
||||||
|
int textInputOpenCount;
|
||||||
|
|
||||||
virtual void onMouseInput(){}
|
virtual void onMouseInput(){}
|
||||||
bool doScreenshot;
|
bool doScreenshot;
|
||||||
float baseCullRadius;
|
float baseCullRadius;
|
||||||
|
|
Loading…
Add table
Reference in a new issue