mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 23:55:38 +00:00
Improved the behavior and consistency for the virtual keyboard when using non-standard keyboard mappings.
This commit is contained in:
parent
de747a932d
commit
cfc9d54068
|
@ -22,6 +22,7 @@ TextEditComponent::TextEditComponent()
|
|||
: mRenderer {Renderer::getInstance()}
|
||||
, mFocused {false}
|
||||
, mEditing {false}
|
||||
, mMaskInput {true}
|
||||
, mCursor {0}
|
||||
, mBlinkTime {0}
|
||||
, mCursorRepeatDir {0}
|
||||
|
@ -66,6 +67,9 @@ void TextEditComponent::setValue(const std::string& val)
|
|||
|
||||
void TextEditComponent::textInput(const std::string& text)
|
||||
{
|
||||
if (mMaskInput)
|
||||
return;
|
||||
|
||||
if (mEditing) {
|
||||
mBlinkTime = 0;
|
||||
mCursorRepeatDir = 0;
|
||||
|
@ -114,38 +118,33 @@ void TextEditComponent::stopEditing()
|
|||
{
|
||||
SDL_StopTextInput();
|
||||
mEditing = false;
|
||||
mMaskInput = false;
|
||||
mCursorRepeatDir = 0;
|
||||
updateHelpPrompts();
|
||||
}
|
||||
|
||||
bool TextEditComponent::input(InputConfig* config, Input input)
|
||||
{
|
||||
bool const cursor_left =
|
||||
(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("left", input)) ||
|
||||
(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_LEFT);
|
||||
bool const cursor_right =
|
||||
(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("right", input)) ||
|
||||
(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RIGHT);
|
||||
bool const cursor_up =
|
||||
(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("up", input)) ||
|
||||
(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_UP);
|
||||
bool const cursor_down =
|
||||
(config->getDeviceId() != DEVICE_KEYBOARD && config->isMappedLike("down", input)) ||
|
||||
(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_DOWN);
|
||||
bool const shoulder_left = (config->isMappedLike("leftshoulder", input));
|
||||
bool const shoulder_right = (config->isMappedLike("rightshoulder", input));
|
||||
bool const trigger_left = (config->isMappedLike("lefttrigger", input));
|
||||
bool const trigger_right = (config->isMappedLike("righttrigger", input));
|
||||
bool const cursorLeft {config->isMappedLike("left", input)};
|
||||
bool const cursorRight {config->isMappedLike("right", input)};
|
||||
bool const cursorUp {config->isMappedLike("up", input)};
|
||||
bool const cursorDown {config->isMappedLike("down", input)};
|
||||
bool const shoulderLeft {config->isMappedLike("leftshoulder", input)};
|
||||
bool const shoulderRight {config->isMappedLike("rightshoulder", input)};
|
||||
bool const triggerLeft {config->isMappedLike("lefttrigger", input)};
|
||||
bool const triggerRight {config->isMappedLike("righttrigger", input)};
|
||||
|
||||
if (input.value == 0) {
|
||||
if (cursor_left || cursor_right || cursor_up || cursor_down || shoulder_left ||
|
||||
shoulder_right | trigger_left || trigger_right) {
|
||||
mMaskInput = true;
|
||||
|
||||
if (cursorLeft || cursorRight || cursorUp || cursorDown || shoulderLeft ||
|
||||
shoulderRight | triggerLeft || triggerRight) {
|
||||
if (input.value == 0)
|
||||
mCursorRepeatDir = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input.value == 0)
|
||||
return false;
|
||||
|
||||
if ((config->isMappedTo("a", input) ||
|
||||
(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RETURN)) &&
|
||||
mFocused && !mEditing) {
|
||||
|
@ -154,63 +153,64 @@ bool TextEditComponent::input(InputConfig* config, Input input)
|
|||
}
|
||||
|
||||
if (mEditing) {
|
||||
if (config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_RETURN) {
|
||||
if (isMultiline())
|
||||
textInput("\n");
|
||||
else
|
||||
stopEditing();
|
||||
if (config->getDeviceId() == DEVICE_KEYBOARD) {
|
||||
// Special handling for keyboard input as the "A" and "B" buttons are overridden.
|
||||
if (input.id == SDLK_RETURN) {
|
||||
if (isMultiline())
|
||||
textInput("\n");
|
||||
else
|
||||
stopEditing();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
else if (input.id == SDLK_DELETE) {
|
||||
if (mCursor < static_cast<int>(mText.length())) {
|
||||
// Fake as Backspace one char to the right.
|
||||
mMaskInput = false;
|
||||
moveCursor(1);
|
||||
textInput("\b");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (input.id == SDLK_BACKSPACE) {
|
||||
mMaskInput = false;
|
||||
textInput("\b");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor_left || cursor_right) {
|
||||
if (cursorLeft || cursorRight) {
|
||||
mBlinkTime = 0;
|
||||
mCursorRepeatDir = cursor_left ? -1 : 1;
|
||||
mCursorRepeatDir = cursorLeft ? -1 : 1;
|
||||
mCursorRepeatTimer = -(CURSOR_REPEAT_START_DELAY - CURSOR_REPEAT_SPEED);
|
||||
moveCursor(mCursorRepeatDir);
|
||||
return false;
|
||||
}
|
||||
// Stop editing and let the button down event be captured by the parent component.
|
||||
else if (cursor_down) {
|
||||
else if (cursorDown) {
|
||||
// Stop editing and let the button down event be captured by the parent component.
|
||||
stopEditing();
|
||||
return false;
|
||||
}
|
||||
else if (shoulder_left || shoulder_right) {
|
||||
mBlinkTime = 0;
|
||||
mCursorRepeatDir = shoulder_left ? -10 : 10;
|
||||
mCursorRepeatTimer = -(CURSOR_REPEAT_START_DELAY - CURSOR_REPEAT_SPEED);
|
||||
moveCursor(mCursorRepeatDir);
|
||||
else if (shoulderLeft) {
|
||||
mMaskInput = false;
|
||||
textInput("\b");
|
||||
return true;
|
||||
}
|
||||
// Jump to beginning of text.
|
||||
else if (trigger_left) {
|
||||
else if (triggerLeft) {
|
||||
// Jump to beginning of text.
|
||||
mBlinkTime = 0;
|
||||
setCursor(0);
|
||||
return true;
|
||||
}
|
||||
// Jump to end of text.
|
||||
else if (trigger_right) {
|
||||
else if (triggerRight) {
|
||||
// Jump to end of text.
|
||||
mBlinkTime = 0;
|
||||
setCursor(mText.length());
|
||||
return true;
|
||||
}
|
||||
else if (config->getDeviceId() == DEVICE_KEYBOARD) {
|
||||
switch (input.id) {
|
||||
case SDLK_HOME: {
|
||||
setCursor(0);
|
||||
break;
|
||||
}
|
||||
case SDLK_END: {
|
||||
setCursor(std::string::npos);
|
||||
break;
|
||||
}
|
||||
case SDLK_DELETE: {
|
||||
if (mCursor < static_cast<int>(mText.length())) {
|
||||
// Fake as Backspace one char to the right.
|
||||
moveCursor(1);
|
||||
textInput("\b");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Consume all input when editing text.
|
||||
mMaskInput = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
std::shared_ptr<Font> getFont() const override { return mFont; }
|
||||
|
||||
void setCursor(size_t pos);
|
||||
void setMaskInput(bool state) { mMaskInput = state; }
|
||||
|
||||
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
|
||||
|
@ -61,6 +62,7 @@ private:
|
|||
std::string mTextOrig;
|
||||
bool mFocused;
|
||||
bool mEditing;
|
||||
bool mMaskInput;
|
||||
int mCursor; // Cursor position in characters.
|
||||
int mBlinkTime;
|
||||
|
||||
|
|
|
@ -340,15 +340,13 @@ bool GuiTextEditKeyboardPopup::input(InputConfig* config, Input input)
|
|||
mNavigationRepeatDirY = 0;
|
||||
}
|
||||
|
||||
// If the keyboard has been configured with backspace as the back button (which is the default
|
||||
// configuration) then ignore this key if we're currently editing or otherwise it would be
|
||||
// impossible to erase characters using this key.
|
||||
bool keyboardBackspace = (config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() &&
|
||||
input.id == SDLK_BACKSPACE);
|
||||
// Ignore whatever key is mapped to the back button so it can be used for text input.
|
||||
bool keyboardBack {config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() &&
|
||||
config->isMappedLike("b", input)};
|
||||
|
||||
// Pressing back (or the escape key if using keyboard input) closes us.
|
||||
if ((config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_ESCAPE) ||
|
||||
(!keyboardBackspace && input.value && config->isMappedTo("b", input))) {
|
||||
(!keyboardBack && input.value && config->isMappedTo("b", input))) {
|
||||
if (mText->getValue() != mInitValue) {
|
||||
// Changes were made, ask if the user wants to save them.
|
||||
mWindow->pushGui(new GuiMsgBox(
|
||||
|
@ -393,7 +391,9 @@ bool GuiTextEditKeyboardPopup::input(InputConfig* config, Input input)
|
|||
if (!editing)
|
||||
mText->startEditing();
|
||||
|
||||
mText->setMaskInput(false);
|
||||
mText->textInput("\b");
|
||||
mText->setMaskInput(true);
|
||||
|
||||
if (!editing)
|
||||
mText->stopEditing();
|
||||
|
@ -410,7 +410,9 @@ bool GuiTextEditKeyboardPopup::input(InputConfig* config, Input input)
|
|||
if (!editing)
|
||||
mText->startEditing();
|
||||
|
||||
mText->setMaskInput(false);
|
||||
mText->textInput(" ");
|
||||
mText->setMaskInput(true);
|
||||
|
||||
if (!editing)
|
||||
mText->stopEditing();
|
||||
|
@ -523,7 +525,9 @@ void GuiTextEditKeyboardPopup::updateDeleteRepeat(int deltaTime)
|
|||
if (!editing)
|
||||
mText->startEditing();
|
||||
|
||||
mText->setMaskInput(false);
|
||||
mText->textInput("\b");
|
||||
mText->setMaskInput(true);
|
||||
|
||||
if (!editing)
|
||||
mText->stopEditing();
|
||||
|
|
|
@ -165,15 +165,13 @@ bool GuiTextEditPopup::input(InputConfig* config, Input input)
|
|||
return true;
|
||||
}
|
||||
|
||||
// If the keyboard has been configured with backspace as the back button (which is the default
|
||||
// configuration) then ignore this key if we're currently editing or otherwise it would be
|
||||
// impossible to erase characters using this key.
|
||||
bool keyboardBackspace = (config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() &&
|
||||
input.id == SDLK_BACKSPACE);
|
||||
// Ignore whatever key is mapped to the back button so it can be used for text input.
|
||||
bool keyboardBack {config->getDeviceId() == DEVICE_KEYBOARD && mText->isEditing() &&
|
||||
config->isMappedLike("b", input)};
|
||||
|
||||
// Pressing back (or the escape key if using keyboard input) closes us.
|
||||
if ((config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_ESCAPE) ||
|
||||
(!keyboardBackspace && input.value && config->isMappedTo("b", input))) {
|
||||
(!keyboardBack && input.value && config->isMappedTo("b", input))) {
|
||||
if (mText->getValue() != mInitValue) {
|
||||
// Changes were made, ask if the user wants to save them.
|
||||
mWindow->pushGui(new GuiMsgBox(
|
||||
|
@ -210,7 +208,9 @@ bool GuiTextEditPopup::input(InputConfig* config, Input input)
|
|||
if (!editing)
|
||||
mText->startEditing();
|
||||
|
||||
mText->setMaskInput(false);
|
||||
mText->textInput("\b");
|
||||
mText->setMaskInput(true);
|
||||
|
||||
if (!editing)
|
||||
mText->stopEditing();
|
||||
|
@ -227,7 +227,9 @@ bool GuiTextEditPopup::input(InputConfig* config, Input input)
|
|||
if (!editing)
|
||||
mText->startEditing();
|
||||
|
||||
mText->setMaskInput(false);
|
||||
mText->textInput(" ");
|
||||
mText->setMaskInput(true);
|
||||
|
||||
if (!editing)
|
||||
mText->stopEditing();
|
||||
|
@ -272,7 +274,9 @@ void GuiTextEditPopup::updateDeleteRepeat(int deltaTime)
|
|||
if (!editing)
|
||||
mText->startEditing();
|
||||
|
||||
mText->setMaskInput(false);
|
||||
mText->textInput("\b");
|
||||
mText->setMaskInput(true);
|
||||
|
||||
if (!editing)
|
||||
mText->stopEditing();
|
||||
|
|
Loading…
Reference in a new issue