From 2c5ed7e3ad332a7fa380089649155c9a8c1e13fa Mon Sep 17 00:00:00 2001 From: kevinkoenig Date: Wed, 1 Sep 2021 07:20:56 -0400 Subject: [PATCH] fix crash in number kebyoard when NumericKeyboard looses focus --- .../libopenui/src/keyboard_base.cpp | 39 ++++++++++++++----- .../thirdparty/libopenui/src/keyboard_base.h | 2 +- .../thirdparty/libopenui/src/numberedit.cpp | 10 +++++ .../src/thirdparty/libopenui/src/numberedit.h | 1 + 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.cpp b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp index 81efb7a2f..10c80d526 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_base.cpp +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.cpp @@ -49,17 +49,25 @@ void Keyboard::attachKeyboard() // this routine finds the window that is a FormWindow. This is the window // that contains all of the editable fields. This is the window that needs // to be scrolled into view. -FormWindow *Keyboard::findFormWindow() +FormWindow *Keyboard::findFormWindow(Window *parent) { - if (fieldContainer) { - auto children = fieldContainer->getChildren(); - auto k = children.begin(); - while (k != children.end()) + if (parent) { + auto children = parent->getChildren(); + auto childIterator = children.begin(); + while (childIterator != children.end()) { - FormWindow *a = dynamic_cast(*k); - if (a) - return a; - k++; +#if defined(DEBUG_WINDOWS) + std::string windowName; + Window *window = dynamic_cast(*childIterator); + if (window) + windowName = window->getName(); +#endif + + FormWindow *formWindow = dynamic_cast(*childIterator); + if (formWindow) + return formWindow; + + childIterator++; } } @@ -72,11 +80,18 @@ void Keyboard::setField(FormField* newField) fieldContainer = getFieldContainer(newField); if (fieldContainer) { +#if defined(DEBUG_WINDOWS) + auto windowName = fieldContainer->getName(); +#endif coord_t newHeight = LCD_H - height(); fieldContainer->setHeight(newHeight); - fields = findFormWindow(); + fields = findFormWindow(fieldContainer); + if (fields) { +#if defined(DEBUG_WINDOWS) + windowName = fields->getName(); +#endif // scroll the header of the window out of view to get more space to // see the field being edited fieldContainer->setScrollPositionY(fields->top()); @@ -85,6 +100,10 @@ void Keyboard::setField(FormField* newField) coord_t offsetY = calcScrollOffsetForField(newField, fields); fields->setScrollPositionY(offsetY); + } else { + // TODO: what happens if field container is null. + // we will need to interrogate the fieldContainer for its + // FormGroup. That is really how it should work anyway. } invalidate(); diff --git a/radio/src/thirdparty/libopenui/src/keyboard_base.h b/radio/src/thirdparty/libopenui/src/keyboard_base.h index 4f3cfcd78..b30c76a05 100644 --- a/radio/src/thirdparty/libopenui/src/keyboard_base.h +++ b/radio/src/thirdparty/libopenui/src/keyboard_base.h @@ -65,6 +65,6 @@ class Keyboard: public FormWindow void setField(FormField *newField); Window *getFieldContainer(FormField * field); void attachKeyboard(); - FormWindow *findFormWindow(); + FormWindow *findFormWindow(Window *parent); }; diff --git a/radio/src/thirdparty/libopenui/src/numberedit.cpp b/radio/src/thirdparty/libopenui/src/numberedit.cpp index f9d56fbbd..48cd71e44 100644 --- a/radio/src/thirdparty/libopenui/src/numberedit.cpp +++ b/radio/src/thirdparty/libopenui/src/numberedit.cpp @@ -150,6 +150,16 @@ void NumberEdit::onEvent(event_t event) FormField::onEvent(event); } +void NumberEdit::onFocusLost() +{ +#if defined(SOFTWARE_KEYBOARD) + Keyboard::hide(); +#endif + + FormField::onFocusLost(); +} + + #if defined(HARDWARE_TOUCH) bool NumberEdit::onTouchEnd(coord_t, coord_t) { diff --git a/radio/src/thirdparty/libopenui/src/numberedit.h b/radio/src/thirdparty/libopenui/src/numberedit.h index 180889c90..a44d35fbd 100644 --- a/radio/src/thirdparty/libopenui/src/numberedit.h +++ b/radio/src/thirdparty/libopenui/src/numberedit.h @@ -62,6 +62,7 @@ class NumberEdit : public BaseNumberEdit } void onEvent(event_t event) override; + void onFocusLost() override; #if defined(HARDWARE_TOUCH) bool onTouchEnd(coord_t x, coord_t y) override;