diff --git a/radio/src/thirdparty/libopenui/src/form.cpp b/radio/src/thirdparty/libopenui/src/form.cpp index 47d0e7e46..708ed35cb 100644 --- a/radio/src/thirdparty/libopenui/src/form.cpp +++ b/radio/src/thirdparty/libopenui/src/form.cpp @@ -210,19 +210,16 @@ void FormGroup::onEvent(event_t event) TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString("FormGroup").c_str(), event); if (event == EVT_KEY_BREAK(KEY_ENTER)) { - if (first) - first->setFocus(SET_FOCUS_FIRST); + setFocusOnFirstVisibleField(SET_FOCUS_FIRST); } else if (event == EVT_KEY_BREAK(KEY_EXIT) && !hasFocus() && !(windowFlags & FORM_FORWARD_FOCUS)) { setFocus(SET_FOCUS_DEFAULT); // opentx - model - timers settings } else if (event == EVT_ROTARY_RIGHT && !next) { - if (first) - first->setFocus(SET_FOCUS_FIRST); + setFocusOnFirstVisibleField(SET_FOCUS_FIRST); } else if (event == EVT_ROTARY_LEFT && !previous) { - if (last) - last->setFocus(SET_FOCUS_BACKWARD); + setFocusOnLastVisibleField(SET_FOCUS_BACKWARD); } else { FormField::onEvent(event); diff --git a/radio/src/thirdparty/libopenui/src/form.h b/radio/src/thirdparty/libopenui/src/form.h index 4105a9832..d2ccdd437 100644 --- a/radio/src/thirdparty/libopenui/src/form.h +++ b/radio/src/thirdparty/libopenui/src/form.h @@ -27,7 +27,8 @@ constexpr WindowFlags FORM_BORDER_FOCUS_ONLY = WINDOW_FLAGS_LAST << 3; constexpr WindowFlags FORM_NO_BORDER = WINDOW_FLAGS_LAST << 4; constexpr WindowFlags FORM_FLAGS_LAST = FORM_NO_BORDER; -class FormField: public Window { +class FormField: public Window +{ public: FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0); @@ -105,7 +106,8 @@ class FormField: public Window { bool enabled = true; }; -class FormGroup: public FormField { +class FormGroup: public FormField +{ public: FormGroup(Window * parent, const rect_t & rect, WindowFlags windowflags = 0) : FormField(parent, rect, windowflags) @@ -138,6 +140,38 @@ class FormGroup: public FormField { last = field; } + FormField * getFirstField() const + { + return first; + } + + FormField * getLastField() const + { + return last; + } + + void setFocusOnFirstVisibleField(uint8_t flag) const + { + auto field = getFirstField(); + while (field && !field->isInsideParentScrollingArea()) { + field = field->getNextField(); + } + if (field) { + field->setFocus(flag); + } + } + + void setFocusOnLastVisibleField(uint8_t flag) const + { + auto field = getLastField(); + while (field && !field->isInsideParentScrollingArea()) { + field = field->getPreviousField(); + } + if (field) { + field->setFocus(flag); + } + } + protected: FormField * first = nullptr; FormField * last = nullptr; @@ -149,7 +183,8 @@ class FormGroup: public FormField { void paint(BitmapBuffer * dc) override; }; -class FormWindow: public FormGroup { +class FormWindow: public FormGroup +{ public: FormWindow(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0) : FormGroup(parent, rect, windowFlags) @@ -172,4 +207,3 @@ class FormWindow: public FormGroup { void onEvent(event_t event) override; #endif }; - diff --git a/radio/src/thirdparty/libopenui/src/window.h b/radio/src/thirdparty/libopenui/src/window.h index d30cc2d62..08e013840 100644 --- a/radio/src/thirdparty/libopenui/src/window.h +++ b/radio/src/thirdparty/libopenui/src/window.h @@ -327,6 +327,11 @@ class Window return parent && parent->isChildVisible(this); } + bool isInsideParentScrollingArea() const + { + return parent && right() >= parent->getScrollPositionX() && left() <= parent->getScrollPositionX() + parent->width(); + } + void drawVerticalScrollbar(BitmapBuffer * dc); void drawHorizontalScrollbar(BitmapBuffer * dc);