From 93cc6c20a006f5118effa08da46562f0a584a97a Mon Sep 17 00:00:00 2001 From: nILS Date: Fri, 27 Feb 2026 11:25:18 +0100 Subject: [PATCH 1/2] improves textfield handling by remembering last char and adding 'jump to next block' --- .../Views/BaseClasses/UITextField.h | 2 + .../Views/BaseClasses/UITextField.ipp | 84 +++++++++++-------- 2 files changed, 50 insertions(+), 36 deletions(-) diff --git a/sources/Application/Views/BaseClasses/UITextField.h b/sources/Application/Views/BaseClasses/UITextField.h index c51092cc0..7208af44c 100644 --- a/sources/Application/Views/BaseClasses/UITextField.h +++ b/sources/Application/Views/BaseClasses/UITextField.h @@ -26,6 +26,7 @@ class UITextField : public UIField, public Observable { virtual ~UITextField(); void Draw(GUIWindow &w, int offset = 0); void ProcessArrow(unsigned short mask); + void ProcessClear(); void OnClick(); void OnEditClick(); etl::string GetString(); @@ -36,6 +37,7 @@ class UITextField : public UIField, public Observable { private: int selected_; uint8_t currentChar_ = 0; + uint8_t lastUsedChar_ = 'A'; Variable *src_; // Pointer instead of reference const etl::string label_; uint8_t fourcc_; diff --git a/sources/Application/Views/BaseClasses/UITextField.ipp b/sources/Application/Views/BaseClasses/UITextField.ipp index 10095b1ff..44c2d4250 100644 --- a/sources/Application/Views/BaseClasses/UITextField.ipp +++ b/sources/Application/Views/BaseClasses/UITextField.ipp @@ -80,9 +80,43 @@ template void UITextField::OnEditClick() { reinterpret_cast(static_cast(fourcc_))); }; +template +void UITextField::ProcessClear() { + etl::string buffer(src_->GetString()); + + if (buffer.empty() || buffer.compare(defaultValue_) == 0) { + // handle empty state + buffer = "A"; + currentChar_ = 0; + } else { + // jump to lastUsedChar_character block depending on the current character + if (lastUsedChar_>= 'A' && lastUsedChar_<= 'Z') { + lastUsedChar_= 'a'; + } else if (lastUsedChar_>= 'a' && lastUsedChar_<= 'z') { + lastUsedChar_= '0'; + } else if (lastUsedChar_>= '0' && lastUsedChar_<= '9') { + lastUsedChar_= '-'; + } else { + lastUsedChar_= 'A'; + } + } + + buffer[currentChar_] = lastUsedChar_; + src_->SetString(buffer.c_str(), true); + SetChanged(); + NotifyObservers( + reinterpret_cast(static_cast(fourcc_))); +}; + template void UITextField::ProcessArrow(unsigned short mask) { - auto buffer(src_->GetString()); + etl::string buffer(src_->GetString()); + auto applyAndNotify = [&]() { + src_->SetString(buffer.c_str(), true); + SetChanged(); + NotifyObservers( + reinterpret_cast(static_cast(fourcc_))); + }; // If the variable's value is empty, we need to initialize it when the user // starts editing @@ -90,44 +124,23 @@ void UITextField::ProcessArrow(unsigned short mask) { switch (mask) { case EPBM_UP: - // If buffer is empty or matches default, initialize with 'A' - if (isEmptyBuffer || buffer.compare(defaultValue_) == 0) { - currentChar_ = 0; - buffer.clear(); - buffer.append("A"); - src_->SetString(buffer.c_str(), true); - } else { - buffer[currentChar_] = getNext(buffer.c_str()[currentChar_], false); - src_->SetString(buffer.c_str(), true); - } - SetChanged(); - NotifyObservers( - reinterpret_cast(static_cast(fourcc_))); - break; case EPBM_DOWN: // If buffer is empty or matches default, initialize with 'A' if (isEmptyBuffer || buffer.compare(defaultValue_) == 0) { currentChar_ = 0; - buffer.clear(); - buffer.append("A"); - src_->SetString(buffer.c_str(), true); + buffer = "A"; } else { - buffer[currentChar_] = getNext((char)buffer.c_str()[currentChar_], true); - src_->SetString(buffer.c_str(), true); + buffer[currentChar_] = + getNext(buffer.c_str()[currentChar_], mask == EPBM_DOWN); } - SetChanged(); - NotifyObservers( - reinterpret_cast(static_cast(fourcc_))); + applyAndNotify(); break; case EPBM_LEFT: // If we're showing the default value and user presses left, initialize with // the default if (isEmptyBuffer) { buffer = defaultValue_; - src_->SetString(buffer.c_str(), true); - SetChanged(); - NotifyObservers(reinterpret_cast( - static_cast(fourcc_))); + applyAndNotify(); } if (currentChar_ > 0) { currentChar_--; @@ -138,24 +151,23 @@ void UITextField::ProcessArrow(unsigned short mask) { // with the default if (isEmptyBuffer) { buffer = defaultValue_; - src_->SetString(buffer.c_str(), true); - SetChanged(); - NotifyObservers(reinterpret_cast( - static_cast(fourcc_))); + applyAndNotify(); } if (currentChar_ < (buffer.length() - 1)) { currentChar_++; // -1 to allow for adding 1 more char } else if (currentChar_ < (MaxLength - 1)) { currentChar_++; - buffer.append("A"); - src_->SetString(buffer.c_str(), true); - SetChanged(); - NotifyObservers(reinterpret_cast( - static_cast(fourcc_))); + char str[2] = {lastUsedChar_, 0}; + buffer.append(str); + applyAndNotify(); } break; }; + + // remember last used char for appending when user moves right at the end + // of the string + lastUsedChar_= buffer.c_str()[currentChar_]; }; template From ca58448fbdd837a0265b1e0cc1a3a530bf5318e1 Mon Sep 17 00:00:00 2001 From: nILS Date: Fri, 10 Apr 2026 17:41:35 +0200 Subject: [PATCH 2/2] removes 'jump to section' --- .../Views/BaseClasses/UITextField.h | 1 - .../Views/BaseClasses/UITextField.ipp | 28 ------------------- 2 files changed, 29 deletions(-) diff --git a/sources/Application/Views/BaseClasses/UITextField.h b/sources/Application/Views/BaseClasses/UITextField.h index 7208af44c..6ba48e35d 100644 --- a/sources/Application/Views/BaseClasses/UITextField.h +++ b/sources/Application/Views/BaseClasses/UITextField.h @@ -26,7 +26,6 @@ class UITextField : public UIField, public Observable { virtual ~UITextField(); void Draw(GUIWindow &w, int offset = 0); void ProcessArrow(unsigned short mask); - void ProcessClear(); void OnClick(); void OnEditClick(); etl::string GetString(); diff --git a/sources/Application/Views/BaseClasses/UITextField.ipp b/sources/Application/Views/BaseClasses/UITextField.ipp index 44c2d4250..8285a2155 100644 --- a/sources/Application/Views/BaseClasses/UITextField.ipp +++ b/sources/Application/Views/BaseClasses/UITextField.ipp @@ -80,34 +80,6 @@ template void UITextField::OnEditClick() { reinterpret_cast(static_cast(fourcc_))); }; -template -void UITextField::ProcessClear() { - etl::string buffer(src_->GetString()); - - if (buffer.empty() || buffer.compare(defaultValue_) == 0) { - // handle empty state - buffer = "A"; - currentChar_ = 0; - } else { - // jump to lastUsedChar_character block depending on the current character - if (lastUsedChar_>= 'A' && lastUsedChar_<= 'Z') { - lastUsedChar_= 'a'; - } else if (lastUsedChar_>= 'a' && lastUsedChar_<= 'z') { - lastUsedChar_= '0'; - } else if (lastUsedChar_>= '0' && lastUsedChar_<= '9') { - lastUsedChar_= '-'; - } else { - lastUsedChar_= 'A'; - } - } - - buffer[currentChar_] = lastUsedChar_; - src_->SetString(buffer.c_str(), true); - SetChanged(); - NotifyObservers( - reinterpret_cast(static_cast(fourcc_))); -}; - template void UITextField::ProcessArrow(unsigned short mask) { etl::string buffer(src_->GetString());