mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-03 10:04: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);
|
||||
|
||||
cursor = cursorGlow = 0;
|
||||
|
||||
pTextInputHandler = 0;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
confirmDone = 1;
|
||||
|
@ -2988,9 +2972,32 @@ bool DSQ::confirm(const std::string &text, const std::string &image, bool ok, fl
|
|||
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)
|
||||
{
|
||||
const std::string originalt = t;
|
||||
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();
|
||||
|
||||
|
@ -3017,16 +3024,15 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
|||
inputText->position = Vector(-400 + 20,8+8);
|
||||
bg->addChild(inputText, PM_POINTER);
|
||||
|
||||
this->beginTextInput();
|
||||
|
||||
|
||||
bg->show();
|
||||
run(trans);
|
||||
|
||||
|
||||
std::string text = t;
|
||||
char map[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
map[i] = 0;
|
||||
bool delDown = false;
|
||||
s_inputText = t;
|
||||
|
||||
bool escDown = false;
|
||||
|
||||
float dt = 1.0f/60.0f;
|
||||
|
@ -3035,77 +3041,6 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
|||
|
||||
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;
|
||||
if (blinkTimer > 0.2f)
|
||||
{
|
||||
|
@ -3113,12 +3048,6 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
|||
blinkTimer = 0;
|
||||
}
|
||||
|
||||
if (blink)
|
||||
{
|
||||
text += "|";
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (getKeyState(KEY_RETURN))
|
||||
break;
|
||||
|
@ -3128,16 +3057,13 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
|||
else if (escDown && !getKeyState(KEY_ESCAPE))
|
||||
{
|
||||
escDown = false;
|
||||
text = t;
|
||||
s_inputText = originalt;
|
||||
break;
|
||||
}
|
||||
inputText->setText(text);
|
||||
inputText->setText(blink ? s_inputText : s_inputText+"|");
|
||||
run(dt);
|
||||
}
|
||||
|
||||
if (blink && !text.empty() && (text[text.size()-1] == '|'))
|
||||
text.resize(text.size()-1);
|
||||
|
||||
sound->playSfx("Menu-Close");
|
||||
|
||||
|
||||
|
@ -3155,11 +3081,16 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
|
|||
game->togglePause(pauseState);
|
||||
|
||||
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()
|
||||
|
@ -4385,3 +4316,9 @@ bool DSQ::useJoystickInput() const
|
|||
{
|
||||
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 onStopVoice();
|
||||
|
||||
virtual void onTextInput(TextInputEvent ti, const char *text) OVERRIDE;
|
||||
typedef void (*InputTextHandler)(TextInputEvent ti, const char *text);
|
||||
InputTextHandler pTextInputHandler;
|
||||
|
||||
Entity **iter;
|
||||
PauseQuad *blackout;
|
||||
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);
|
||||
|
||||
texmgr.spawnThreads(3);
|
||||
|
||||
textInputOpenCount = 0;
|
||||
}
|
||||
|
||||
void Core::initPlatform(const std::string &filesystem)
|
||||
|
@ -1356,6 +1358,30 @@ bool Core::doMouseConstraint()
|
|||
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
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const bool focus = window->hasFocus();
|
||||
|
@ -1409,6 +1491,28 @@ void Core::onEvent(const SDL_Event& event)
|
|||
#endif
|
||||
if(kidx < KEY_MAXARRAY)
|
||||
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;
|
||||
|
@ -1499,6 +1603,15 @@ motion:
|
|||
}
|
||||
break;
|
||||
#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
|
||||
};
|
||||
|
||||
enum TextInputEvent
|
||||
{
|
||||
TEXTINP_TEXT,
|
||||
TEXTINP_BACKSPACE,
|
||||
};
|
||||
|
||||
|
||||
class AfterEffectManager;
|
||||
|
||||
class Texture;
|
||||
|
@ -463,6 +470,11 @@ protected:
|
|||
|
||||
bool doMouseConstraint();
|
||||
|
||||
virtual void onTextInput(TextInputEvent ti, const char *text) {}
|
||||
void beginTextInput();
|
||||
void endTextInput();
|
||||
int textInputOpenCount;
|
||||
|
||||
virtual void onMouseInput(){}
|
||||
bool doScreenshot;
|
||||
float baseCullRadius;
|
||||
|
|
Loading…
Add table
Reference in a new issue