From 44c5fc22b42b8bbb5276daaa4645658e917d2139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 1 May 2026 20:04:22 +0200 Subject: [PATCH 1/4] Add a symbols page to the soft keyboard. Fixes #21624 --- Common/UI/PopupScreens.cpp | 38 +++++++++++++++++++++++--------------- Common/UI/PopupScreens.h | 11 +++++++++-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index bb8b97d033d9..2535899b624e 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -833,7 +833,7 @@ std::string PopupTextInputChoice::ValueText(bool *shadow) const { } } -ViewGroup *CreateSoftKeyboard(TextEdit *edit, bool *upperCase) { +ViewGroup *CreateSoftKeyboard(TextEdit *edit, SoftKeyboardState *state) { ScrollView *scrollView = new ScrollView(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); LinearLayout *keyboard = scrollView->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT))); @@ -841,17 +841,20 @@ ViewGroup *CreateSoftKeyboard(TextEdit *edit, bool *upperCase) { static struct { std::string_view v; const char *tag; } kbRows[] = { - {"1234567890-=", "A"}, - {"qwertyuiop'[]", "L"}, - {"asdfghjkl()", "L"}, + {"1234567890-_", "A"}, + {"qwertyuiop", "L"}, + {"asdfghjkl", "L"}, {"zxcvbnm,.", "L"}, - {"QWERTYUIOP'[]", "U"}, - {"ASDFGHJKL()", "U"}, + {"QWERTYUIOP", "U"}, + {"ASDFGHJKL", "U"}, {"ZXCVBNM,.", "U"}, + {"@#$_&()/-+_", "S"}, + {"*\"':;!?[]", "S"}, + {"={}~<>|", "S"}, {"", "A"}, }; static const float space[] = { - 0.0f, 10.0f, 20.0f, 30.0f, 10.0f, 20.0f, 30.0f, 30.0f, + 0.0f, 10.0f, 20.0f, 30.0f, 10.0f, 20.0f, 30.0f, 10.0f, 20.0f, 30.0f, 30.0f, }; static_assert(ARRAY_SIZE(kbRows) == ARRAY_SIZE(space)); @@ -871,8 +874,9 @@ ViewGroup *CreateSoftKeyboard(TextEdit *edit, bool *upperCase) { bool visible = false; switch (kbRows[i].tag[0]) { - case 'L': visible = !(*upperCase); break; - case 'U': visible = *upperCase; break; + case 'L': visible = (*state == SoftKeyboardState::Lower); break; + case 'U': visible = (*state == SoftKeyboardState::Upper); break; + case 'S': visible = (*state == SoftKeyboardState::Symbols); break; case 'A': visible = true; break; default: visible = false; break; } @@ -885,16 +889,20 @@ ViewGroup *CreateSoftKeyboard(TextEdit *edit, bool *upperCase) { edit->Backspace(); }); break; - case 7: + case 10: // Special keys. - row->Add(new Button("Aa", new LinearLayoutParams(80.0f, 50.0f)))->OnClick.Add([keyboard, upperCase](EventParams &) { - *upperCase = !(*upperCase); + row->Add(new Button("Aa", new LinearLayoutParams(80.0f, 50.0f)))->OnClick.Add([keyboard, state](EventParams &) { + *state = (SoftKeyboardState)((int)*state + 1); + if (*state == SoftKeyboardState::MAX) { + *state = SoftKeyboardState::Upper; + } // Work through visibility. for (int i = 0; i < keyboard->GetNumSubviews(); i++) { LinearLayout *row = (LinearLayout *)keyboard->GetViewByIndex(i); switch (row->Tag()[0]) { - case 'L': row->SetVisibility(*upperCase ? V_GONE : V_VISIBLE); break; - case 'U': row->SetVisibility(*upperCase ? V_VISIBLE : V_GONE); break; + case 'L': row->SetVisibility((*state == SoftKeyboardState::Lower) ? V_VISIBLE : V_GONE); break; + case 'U': row->SetVisibility((*state == SoftKeyboardState::Upper) ? V_VISIBLE : V_GONE); break; + case 'S': row->SetVisibility((*state == SoftKeyboardState::Symbols) ? V_VISIBLE : V_GONE); break; case 'A': row->SetVisibility(V_VISIBLE); break; default: row->SetVisibility(V_GONE); break; } @@ -930,7 +938,7 @@ void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { parent->Add(new Spacer(8.0f)); - keyboard_ = parent->Add(CreateSoftKeyboard(edit_, &upperCase_)); + keyboard_ = parent->Add(CreateSoftKeyboard(edit_, &kbState_)); if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) { keyboard_->SetVisibility(V_GONE); lin->Add(new Spacer(5.0f)); diff --git a/Common/UI/PopupScreens.h b/Common/UI/PopupScreens.h index 739f0bc573ae..2491417c78ca 100644 --- a/Common/UI/PopupScreens.h +++ b/Common/UI/PopupScreens.h @@ -222,7 +222,14 @@ class SliderFloatPopupScreen : public PopupScreen { bool liveUpdate_; }; -ViewGroup *CreateSoftKeyboard(TextEdit *edit, bool *upperCase); +enum class SoftKeyboardState { + Upper = 0, + Lower, + Symbols, + MAX, +}; + +ViewGroup *CreateSoftKeyboard(TextEdit *edit, SoftKeyboardState *state); class TextEditPopupScreen : public PopupScreen { public: @@ -249,7 +256,7 @@ class TextEditPopupScreen : public PopupScreen { std::string textEditValue_; std::string placeholder_; int maxLen_; - bool upperCase_ = false; + SoftKeyboardState kbState_{}; bool passwordMasking_ = false; }; From 77ce936c7d180f52a1a2fe238e56e75a7f79c743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 1 May 2026 20:04:56 +0200 Subject: [PATCH 2/4] Add a "Paste" icon to the UIAtlas --- UI/UIAtlas.cpp | 1 + assets/ui_images/images.svg | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/UI/UIAtlas.cpp b/UI/UIAtlas.cpp index 34f4f483b512..65c359a6d67e 100644 --- a/UI/UIAtlas.cpp +++ b/UI/UIAtlas.cpp @@ -151,6 +151,7 @@ static const ImageMeta g_uiImageIDs[] = { {"I_FOLDER_UPLOAD", false}, {"I_FILE", false}, {"I_FILE_COPY", false}, + {"I_FILE_PASTE", false}, {"I_WEB_BROWSER", false}, {"I_WIFI", false}, {"I_LOGO_X", false}, diff --git a/assets/ui_images/images.svg b/assets/ui_images/images.svg index f54b38da2c8e..56747c9229d2 100644 --- a/assets/ui_images/images.svg +++ b/assets/ui_images/images.svg @@ -23,9 +23,9 @@ inkscape:pagecheckerboard="true" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" - inkscape:zoom="2" - inkscape:cx="245.5" - inkscape:cy="307.75" + inkscape:zoom="5.6568542" + inkscape:cx="272.05933" + inkscape:cy="562.76861" inkscape:window-width="3840" inkscape:window-height="2071" inkscape:window-x="-9" @@ -1022,10 +1022,10 @@ sodipodi:nodetypes="ccccccccccccccccccccccccccccc" /> @@ -1568,7 +1568,16 @@ id="path97" />