From 58787f5bf02f14aac03169ade9526658df45bc64 Mon Sep 17 00:00:00 2001 From: MatthewColvin Date: Tue, 10 Oct 2023 15:43:36 -0500 Subject: [PATCH] Move logic related to owning widgets into its own class to prepare for a widget type that can own other widgets. --- Platformio/OmoteUI/core/WidgetContainer.cpp | 55 +++++++++++++++++++ Platformio/OmoteUI/core/WidgetContainer.hpp | 38 +++++++++++++ Platformio/OmoteUI/core/page/PageBase.cpp | 52 +----------------- Platformio/OmoteUI/core/page/PageBase.hpp | 25 +-------- Platformio/OmoteUI/core/widget/WidgetBase.hpp | 8 +-- 5 files changed, 101 insertions(+), 77 deletions(-) create mode 100644 Platformio/OmoteUI/core/WidgetContainer.cpp create mode 100644 Platformio/OmoteUI/core/WidgetContainer.hpp diff --git a/Platformio/OmoteUI/core/WidgetContainer.cpp b/Platformio/OmoteUI/core/WidgetContainer.cpp new file mode 100644 index 0000000..015d8b9 --- /dev/null +++ b/Platformio/OmoteUI/core/WidgetContainer.cpp @@ -0,0 +1,55 @@ +#include "WidgetContainer.hpp" + +using namespace UI; + +WidgetContainer::WidgetContainer(lv_obj_t *aLvglSelf, ID aID) + : UIElement(aLvglSelf, aID) {} + +UI::Widget::Base *WidgetContainer::AddWidget(Widget::Base::Ptr aWidget) { + AddElement(aWidget.get()); + mWidgets.push_back(std::move(aWidget)); + return mWidgets[mWidgets.size() - 1].get(); +} + +UI::Widget::Base::Ptr +WidgetContainer::RemoveWidget(Widget::Base *aWidgetRefrence) { + auto widgetToRemoveIter = std::find_if( + mWidgets.begin(), mWidgets.end(), [aWidgetRefrence](auto &aWidget) { + return aWidget.get() == aWidgetRefrence; + }); + if (widgetToRemoveIter != mWidgets.end()) { + auto widget = std::move(*widgetToRemoveIter); + mWidgets.erase(widgetToRemoveIter); + return widget; + } + return nullptr; +} + +bool WidgetContainer::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { + if (OnKeyEvent(aKeyEvent)) { + return true; + } + for (auto &widget : mWidgets) { + auto used = widget->KeyEvent(aKeyEvent); + if (used) { + return true; + } + } + return false; +}; + +void WidgetContainer::OnShow() { + for (auto &widget : mWidgets) { + if (widget->IsVisible()) { + widget->OnShow(); + } + } +}; + +void WidgetContainer::OnHide() { + for (auto &widget : mWidgets) { + if (widget->IsVisible()) { + widget->OnHide(); + } + } +}; \ No newline at end of file diff --git a/Platformio/OmoteUI/core/WidgetContainer.hpp b/Platformio/OmoteUI/core/WidgetContainer.hpp new file mode 100644 index 0000000..e82c2df --- /dev/null +++ b/Platformio/OmoteUI/core/WidgetContainer.hpp @@ -0,0 +1,38 @@ +#pragma once +#include "UIElement.hpp" +#include "WidgetBase.hpp" + +namespace UI { + +class WidgetContainer : public UIElement { +public: + WidgetContainer(lv_obj_t *aLvglSelf, ID aID); + + template ElementTy *AddWidget(Widget::Base::Ptr aWidget); + + Widget::Base *AddWidget(Widget::Base::Ptr aWidget); + Widget::Base::Ptr RemoveWidget(Widget::Base *aWidgetRefrence); + size_t GetNumWidgets() { return mWidgets.size(); } + +protected: + /// @brief Forward To widgets that are visible + void OnShow() override; + + /// @brief Forward To widgets that are visible + void OnHide() override; + + /// @brief Pass Key Events to widgets until one is handled + /// TODO: consider an ability to have a selected widget be the first + /// one to get events. + bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; + +private: + std::vector mWidgets; +}; + +template +ElementTy *WidgetContainer::AddWidget(Widget::Base::Ptr aWidget) { + return static_cast(AddWidget(std::move(aWidget))); +} + +} // namespace UI \ No newline at end of file diff --git a/Platformio/OmoteUI/core/page/PageBase.cpp b/Platformio/OmoteUI/core/page/PageBase.cpp index 49693e5..1f1a7fe 100644 --- a/Platformio/OmoteUI/core/page/PageBase.cpp +++ b/Platformio/OmoteUI/core/page/PageBase.cpp @@ -6,58 +6,8 @@ using namespace UI::Page; Base::Base(ID aID) : Base(lv_obj_create(Screen::BackgroundScreen::getLvInstance()), aID) {} -Base::Base(lv_obj_t *aLvglSelf, ID aID) : UIElement(aLvglSelf, aID) { +Base::Base(lv_obj_t *aLvglSelf, ID aID) : WidgetContainer(aLvglSelf, aID) { SetHeight(lv_pct(100)); SetWidth(lv_pct(100)); SetPadding(Padding()); // Set Padding to default } -// Return non owning refrence to widget -UI::Widget::Base *Base::AddWidget(Widget::Base::Ptr aWidget) { - AddElement(aWidget.get()); - mWidgets.push_back(std::move(aWidget)); - return mWidgets[mWidgets.size() - 1].get(); -} - -UI::Widget::Base::Ptr Base::RemoveWidget(Widget::Base *aWidgetRefrence) { - auto widgetToRemoveIter = std::find_if( - mWidgets.begin(), mWidgets.end(), [aWidgetRefrence](auto &aWidget) { - return aWidget.get() == aWidgetRefrence; - }); - if (widgetToRemoveIter != mWidgets.end()) { - auto widget = std::move(*widgetToRemoveIter); - mWidgets.erase(widgetToRemoveIter); - return widget; - } - return nullptr; -} - -bool Base::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { - if (OnKeyEvent(aKeyEvent)) { - return true; - } - for (auto &widget : mWidgets) { - auto used = widget->KeyEvent(aKeyEvent); - if (used) { - return true; - } - } - return false; -}; - -bool Base::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return false; }; - -void Base::OnShow() { - for (auto &widget : mWidgets) { - if (widget->IsVisible()) { - widget->OnShow(); - } - } -}; - -void Base::OnHide() { - for (auto &widget : mWidgets) { - if (widget->IsVisible()) { - widget->OnHide(); - } - } -}; \ No newline at end of file diff --git a/Platformio/OmoteUI/core/page/PageBase.hpp b/Platformio/OmoteUI/core/page/PageBase.hpp index aab10f2..c8c5705 100644 --- a/Platformio/OmoteUI/core/page/PageBase.hpp +++ b/Platformio/OmoteUI/core/page/PageBase.hpp @@ -1,6 +1,6 @@ #pragma once #include "UIElement.hpp" -#include "WidgetBase.hpp" +#include "WidgetContainer.hpp" #include #include @@ -10,7 +10,7 @@ class PopUpScreen; namespace UI::Page { class Tab; class TabView; -class Base : public UIElement { +class Base : public WidgetContainer { // Classes that Own Pages friend Tab; // Allow Tab to Forward all Key Events to its page friend TabView; // Allow Tab view to call OnShow and OnHide Since it can show @@ -25,32 +25,13 @@ public: Base(lv_obj_t *aLvglSelf, ID aID); virtual ~Base() = default; - template ElementTy *AddWidget(Widget::Base::Ptr aWidget); - - Widget::Base *AddWidget(Widget::Base::Ptr aWidget); - Widget::Base::Ptr RemoveWidget(Widget::Base *aWidgetRefrence); - size_t GetNumWidgets() { return mWidgets.size(); } - // Override to have a title associated with your page. virtual std::string GetTitle() { return ""; }; protected: - /// @brief Forward To widgets that are visible - void OnShow() override; - - /// @brief Forward To widgets that are visible - void OnHide() override; - - bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; - bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; + bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return false; }; private: - std::vector mWidgets; }; -template -ElementTy *Base::AddWidget(Widget::Base::Ptr aWidget) { - return static_cast(AddWidget(std::move(aWidget))); -} - } // namespace UI::Page diff --git a/Platformio/OmoteUI/core/widget/WidgetBase.hpp b/Platformio/OmoteUI/core/widget/WidgetBase.hpp index 4b0e988..3a5f004 100644 --- a/Platformio/OmoteUI/core/widget/WidgetBase.hpp +++ b/Platformio/OmoteUI/core/widget/WidgetBase.hpp @@ -4,9 +4,9 @@ #include namespace UI { -namespace Page { -class Base; -} + +class WidgetContainer; + namespace Screen { class PopUpScreen; } @@ -16,7 +16,7 @@ namespace UI::Widget { class Base : public UIElement { // Classes that Own Widgets - friend class UI::Page::Base; + friend class UI::WidgetContainer; friend class UI::Screen::PopUpScreen; public: