From 8d8e7c395be6efcb36a22ab395f191812368a46a Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 24 Feb 2021 18:51:45 +0100 Subject: [PATCH] Window::setFocus() refactoring --- radio/src/thirdparty/libopenui/src/checkbox.h | 11 +++-- .../libopenui/src/expansion_panel.cpp | 10 ++-- .../libopenui/src/expansion_panel.h | 2 +- radio/src/thirdparty/libopenui/src/form.cpp | 48 +++++++++---------- radio/src/thirdparty/libopenui/src/form.h | 8 ++-- radio/src/thirdparty/libopenui/src/table.cpp | 6 ++- radio/src/thirdparty/libopenui/src/table.h | 25 +++++++--- radio/src/thirdparty/libopenui/src/window.cpp | 3 +- radio/src/thirdparty/libopenui/src/window.h | 2 +- 9 files changed, 66 insertions(+), 49 deletions(-) diff --git a/radio/src/thirdparty/libopenui/src/checkbox.h b/radio/src/thirdparty/libopenui/src/checkbox.h index 411f588b6..444d7f381 100644 --- a/radio/src/thirdparty/libopenui/src/checkbox.h +++ b/radio/src/thirdparty/libopenui/src/checkbox.h @@ -19,14 +19,15 @@ #pragma once +#include #include "form.h" class CheckBox : public FormField { public: CheckBox(Window * parent, const rect_t & rect, std::function getValue, std::function setValue, WindowFlags flags = 0) : FormField(parent, rect, flags), - _getValue(getValue), - _setValue(setValue) + _getValue(std::move(getValue)), + _setValue(std::move(setValue)) { } @@ -62,9 +63,13 @@ class CheckBox : public FormField { return _getValue(); } + void setSetValueHandler(std::function handler) + { + _setValue = std::move(handler); + } + protected: std::string label; std::function _getValue; std::function _setValue; }; - diff --git a/radio/src/thirdparty/libopenui/src/expansion_panel.cpp b/radio/src/thirdparty/libopenui/src/expansion_panel.cpp index 624931dd5..99a8c7e43 100644 --- a/radio/src/thirdparty/libopenui/src/expansion_panel.cpp +++ b/radio/src/thirdparty/libopenui/src/expansion_panel.cpp @@ -28,12 +28,12 @@ void ExpansionPanel::updateHeight(bool move) setHeight(newHeight); } -void ExpansionPanel::setFocus(uint8_t flag) +void ExpansionPanel::setFocus(uint8_t flag, Window * from) { if (!enabled || isOpen) - FormGroup::setFocus(flag); + FormGroup::setFocus(flag, from); else - header->setFocus(flag); + header->setFocus(flag, from); } ExpansionPanelHeader::ExpansionPanelHeader(ExpansionPanel * parent): @@ -51,12 +51,12 @@ void ExpansionPanelHeader::onEvent(event_t event) else if (event == EVT_ROTARY_RIGHT && !panel->isOpen) { auto next = panel->getNextField(); if (next) - next->setFocus(SET_FOCUS_FORWARD); + next->setFocus(SET_FOCUS_FORWARD, this); } else if (event == EVT_ROTARY_LEFT) { auto previous = panel->getPreviousField(); if (previous) { - previous->setFocus(SET_FOCUS_BACKWARD); + previous->setFocus(SET_FOCUS_BACKWARD, this); } } else { diff --git a/radio/src/thirdparty/libopenui/src/expansion_panel.h b/radio/src/thirdparty/libopenui/src/expansion_panel.h index ff22c859d..9dd965ac5 100644 --- a/radio/src/thirdparty/libopenui/src/expansion_panel.h +++ b/radio/src/thirdparty/libopenui/src/expansion_panel.h @@ -89,7 +89,7 @@ class ExpansionPanel: public FormGroup void updateHeight(bool move = true); - void setFocus(uint8_t flag) override; + void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override; FormGroup * body = nullptr; diff --git a/radio/src/thirdparty/libopenui/src/form.cpp b/radio/src/thirdparty/libopenui/src/form.cpp index 5494960ff..04a13a8bb 100644 --- a/radio/src/thirdparty/libopenui/src/form.cpp +++ b/radio/src/thirdparty/libopenui/src/form.cpp @@ -40,13 +40,13 @@ void FormField::onEvent(event_t event) if (event == EVT_ROTARY_RIGHT/*EVT_KEY_BREAK(KEY_DOWN)*/) { if (next) { onKeyPress(); - next->setFocus(SET_FOCUS_FORWARD); + next->setFocus(SET_FOCUS_FORWARD, this); } } else if (event == EVT_ROTARY_LEFT/*EVT_KEY_BREAK(KEY_UP)*/) { if (previous) { onKeyPress(); - previous->setFocus(SET_FOCUS_BACKWARD); + previous->setFocus(SET_FOCUS_BACKWARD, this); } } else if (event == EVT_KEY_BREAK(KEY_ENTER)) { @@ -65,22 +65,20 @@ void FormField::onEvent(event_t event) } #endif -void FormField::setFocus(uint8_t flag) +void FormField::setFocus(uint8_t flag, Window * from) { if (enabled) { - Window::setFocus(flag); + Window::setFocus(flag, from); } else { - clearFocus(); - focusWindow = this; if (flag == SET_FOCUS_BACKWARD) { if (previous) { - previous->setFocus(flag); + previous->setFocus(flag, this); } } else { if (next) { - next->setFocus(flag); + next->setFocus(flag, this); } } } @@ -146,29 +144,27 @@ void FormGroup::addField(FormField * field, bool front) } } -void FormGroup::setFocus(uint8_t flag) +void FormGroup::setFocus(uint8_t flag, Window * from) { TRACE_WINDOWS("%s setFocus(%d)", getWindowDebugString("FormGroup").c_str(), flag); if (windowFlags & FORM_FORWARD_FOCUS) { switch (flag) { case SET_FOCUS_BACKWARD: - if (focusWindow->isChild(first)) { + if (from && from->isChild(first)) { if (previous == this) { - last->setFocus(SET_FOCUS_BACKWARD); + last->setFocus(SET_FOCUS_BACKWARD, this); } else if (previous) { - previous->setFocus(SET_FOCUS_BACKWARD); + previous->setFocus(SET_FOCUS_BACKWARD, this); } } else { if (last) { - last->setFocus(SET_FOCUS_BACKWARD); + last->setFocus(SET_FOCUS_BACKWARD, this); } else if (previous) { - clearFocus(); - focusWindow = this; - previous->setFocus(SET_FOCUS_BACKWARD); + previous->setFocus(SET_FOCUS_BACKWARD, this); } } break; @@ -178,31 +174,33 @@ void FormGroup::setFocus(uint8_t flag) // no break; case SET_FOCUS_FORWARD: - if (focusWindow && focusWindow->isChild(this)) { + if (from && from->isChild(this)) { if (next == this) { - first->setFocus(SET_FOCUS_FORWARD); + first->setFocus(SET_FOCUS_FORWARD, this); } else if (next) { - next->setFocus(SET_FOCUS_FORWARD); + next->setFocus(SET_FOCUS_FORWARD, this); } } else { if (first) { - first->setFocus(SET_FOCUS_FORWARD); + first->setFocus(SET_FOCUS_FORWARD, this); } else if (next) { - clearFocus(); - focusWindow = this; - next->setFocus(SET_FOCUS_FORWARD); + next->setFocus(SET_FOCUS_FORWARD, this); } } break; default: - if (focusWindow == previous) { + if (from == previous) { if (first) { first->setFocus(SET_FOCUS_DEFAULT); } + else { + clearFocus(); + focusWindow = this; + } } else if (next) { next->setFocus(SET_FOCUS_FORWARD); @@ -215,7 +213,7 @@ void FormGroup::setFocus(uint8_t flag) } } else if (!(windowFlags & NO_FOCUS)) { - FormField::setFocus(flag); + FormField::setFocus(flag, from); } } diff --git a/radio/src/thirdparty/libopenui/src/form.h b/radio/src/thirdparty/libopenui/src/form.h index 602c5d155..8bbf4e517 100644 --- a/radio/src/thirdparty/libopenui/src/form.h +++ b/radio/src/thirdparty/libopenui/src/form.h @@ -79,7 +79,7 @@ class FormField: public Window enable(false); } - void setFocus(uint8_t flag) override; + void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override; void onFocusLost() override { @@ -131,7 +131,7 @@ class FormGroup: public FormField } } - void setFocus(uint8_t flag) override; + void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override; virtual void addField(FormField * field, bool front = false); // NOLINT(google-default-arguments) @@ -155,7 +155,7 @@ class FormGroup: public FormField return last; } - void setFocusOnFirstVisibleField(uint8_t flag) const + void setFocusOnFirstVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const { auto field = getFirstField(); while (field && !field->isInsideParentScrollingArea()) { @@ -166,7 +166,7 @@ class FormGroup: public FormField } } - void setFocusOnLastVisibleField(uint8_t flag) const + void setFocusOnLastVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const { auto field = getLastField(); while (field && !field->isInsideParentScrollingArea()) { diff --git a/radio/src/thirdparty/libopenui/src/table.cpp b/radio/src/thirdparty/libopenui/src/table.cpp index bbb5d2226..257eda06b 100644 --- a/radio/src/thirdparty/libopenui/src/table.cpp +++ b/radio/src/thirdparty/libopenui/src/table.cpp @@ -117,8 +117,10 @@ void Table::Body::onEvent(event_t event) else { auto next = table->getNextField(); if (next) { - select(-1, false); - next->setFocus(SET_FOCUS_FORWARD); + next->setFocus(SET_FOCUS_FORWARD, this); + if (!hasFocus()) { + select(-1, false); + } } } } diff --git a/radio/src/thirdparty/libopenui/src/table.h b/radio/src/thirdparty/libopenui/src/table.h index 200ea9141..db392f906 100644 --- a/radio/src/thirdparty/libopenui/src/table.h +++ b/radio/src/thirdparty/libopenui/src/table.h @@ -239,9 +239,6 @@ class Table: public FormField header(this, {0, 0, width(), 0}, columnsCount), body(this, {0, 0, width(), height()}, windowFlags) { - if (hasFocus()) { - setFocus(SET_FOCUS_DEFAULT); - } } #if defined(DEBUG_WINDOWS) @@ -292,11 +289,25 @@ class Table: public FormField body.invalidate(); } - void setFocus(uint8_t flag) override + void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override { - body.setFocus(flag); - if (body.selection < 0 && !body.lines.empty()) { - select(flag == SET_FOCUS_BACKWARD ? body.lines.size() - 1 : 0); + if (body.lines.empty()) { + if (flag == SET_FOCUS_BACKWARD) { + if (previous) { + previous->setFocus(flag, this); + } + } + else { + if (next) { + next->setFocus(flag, this); + } + } + } + else { + body.setFocus(flag, from); + if (body.selection < 0) { + select(flag == SET_FOCUS_BACKWARD ? body.lines.size() - 1 : 0); + } } } diff --git a/radio/src/thirdparty/libopenui/src/window.cpp b/radio/src/thirdparty/libopenui/src/window.cpp index 7eff84a83..5fa606e96 100644 --- a/radio/src/thirdparty/libopenui/src/window.cpp +++ b/radio/src/thirdparty/libopenui/src/window.cpp @@ -122,7 +122,7 @@ void Window::clearFocus() } } -void Window::setFocus(uint8_t flag) +void Window::setFocus(uint8_t flag, Window * from) { if (deleted()) return; @@ -139,6 +139,7 @@ void Window::setFocus(uint8_t flag) parent->scrollTo(this); invalidate(); } + clearFocus(); focusWindow = this; if (focusHandler) { diff --git a/radio/src/thirdparty/libopenui/src/window.h b/radio/src/thirdparty/libopenui/src/window.h index 89ca45a18..888f3c245 100644 --- a/radio/src/thirdparty/libopenui/src/window.h +++ b/radio/src/thirdparty/libopenui/src/window.h @@ -164,7 +164,7 @@ class Window static void clearFocus(); - virtual void setFocus(uint8_t flag); + virtual void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr); void setRect(rect_t value) {