diff --git a/Platformio/OmoteUI/core/UIElement.cpp b/Platformio/OmoteUI/core/UIElement.cpp index 6ba472a..def1a98 100644 --- a/Platformio/OmoteUI/core/UIElement.cpp +++ b/Platformio/OmoteUI/core/UIElement.cpp @@ -24,12 +24,39 @@ UIElement::~UIElement() { } } -void UIElement::AddElement(UIElement *anUIElement) { - LvglResourceManger::GetInstance().AttemptNow([this, anUIElement] { - lv_obj_set_parent(anUIElement->mLvglSelf, mLvglSelf); - }); +UIElement *UIElement::AddElement(UIElement::Ptr anUIElement) { + auto lock = LvglResourceManger::GetInstance().scopeLock(); + lv_obj_set_parent(anUIElement->mLvglSelf, mLvglSelf); + mContainedElements.push_back(std::move(anUIElement)); + return mContainedElements[mContainedElements.size() - 1].get(); } +UIElement::Ptr UIElement::RemoveElement(UIElement *anElementRef) { + auto ElemToRemoveIter = + std::find_if(mContainedElements.begin(), mContainedElements.end(), + [anElementRef](auto &anElement) { + return anElement.get() == anElementRef; + }); + if (ElemToRemoveIter != mContainedElements.end()) { + auto widget = std::move(*ElemToRemoveIter); + mContainedElements.erase(ElemToRemoveIter); + return widget; + } + return nullptr; +} + +bool UIElement::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { + if (OnKeyEvent(aKeyEvent)) { + return true; + } + for (auto &elem : mContainedElements) { + if (elem->KeyEvent(aKeyEvent)) { + return true; + } + } + return false; +}; + bool UIElement::IsVisible() { auto lock = LvglResourceManger::GetInstance().scopeLock(); return lv_obj_is_visible(mLvglSelf); @@ -220,6 +247,9 @@ void UIElement::Show() { if (IsVisible()) { return; } + for (auto &elem : mContainedElements) { + elem->OnShow(); + } { auto lock = LvglResourceManger::GetInstance().scopeLock(); lv_obj_clear_flag(mLvglSelf, LV_OBJ_FLAG_HIDDEN); @@ -231,6 +261,9 @@ void UIElement::Hide() { if (!IsVisible()) { return; } + for (auto &elem : mContainedElements) { + elem->OnHide(); + } { auto lock = LvglResourceManger::GetInstance().scopeLock(); lv_obj_add_flag(mLvglSelf, LV_OBJ_FLAG_HIDDEN); @@ -238,10 +271,6 @@ void UIElement::Hide() { OnHide(); } -bool UIElement::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { - return OnKeyEvent(aKeyEvent); -} - //////////////////// Statics ////////////////////////// void UIElement::LvglEventHandler(lv_event_t *anEvent) { diff --git a/Platformio/OmoteUI/core/UIElement.hpp b/Platformio/OmoteUI/core/UIElement.hpp index 20b93be..537619b 100644 --- a/Platformio/OmoteUI/core/UIElement.hpp +++ b/Platformio/OmoteUI/core/UIElement.hpp @@ -6,12 +6,15 @@ #include #include "KeyPressAbstract.hpp" +#include namespace UI { class UIElement { public: + using Ptr = std::unique_ptr; + UIElement(lv_obj_t *aLvglSelf, const ID aId = ID()); virtual ~UIElement(); @@ -61,7 +64,12 @@ public: lv_style_selector_t aStyle = LV_PART_MAIN); TextStyle GetTextStyle(lv_style_selector_t aStyle = LV_PART_MAIN); - virtual void AddElement(UIElement *anElement); + UIElement *AddElement(UIElement::Ptr anElement); + template UIElemTy *AddElement(UIElement::Ptr aWidget); + + UIElement::Ptr RemoveElement(UIElement *aUIElementRef); + + size_t GetNumContainedElements() { return mContainedElements.size(); } ID GetID() { return mId; }; @@ -107,6 +115,9 @@ private: lv_obj_t *mLvglSelf; const ID mId; uint32_t mLvglKeepAliveTime = 0; + + /// @brief Elements that are currently in this element + std::vector mContainedElements; }; /** @@ -130,4 +141,9 @@ UIElemTy UIElement::GetElement(lv_obj_t *aLvglObject) { return nullptr; } +template +UIElemTy *UIElement::AddElement(UIElement::Ptr anElement) { + return static_cast(AddElement(std::move(anElement))); +} + } // namespace UI \ No newline at end of file diff --git a/Platformio/OmoteUI/core/WidgetContainer.cpp b/Platformio/OmoteUI/core/WidgetContainer.cpp deleted file mode 100644 index 015d8b9..0000000 --- a/Platformio/OmoteUI/core/WidgetContainer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#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 deleted file mode 100644 index e82c2df..0000000 --- a/Platformio/OmoteUI/core/WidgetContainer.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#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/DisplaySettings.cpp b/Platformio/OmoteUI/core/page/DisplaySettings.cpp index 7d0dfa6..bbb3d57 100644 --- a/Platformio/OmoteUI/core/page/DisplaySettings.cpp +++ b/Platformio/OmoteUI/core/page/DisplaySettings.cpp @@ -6,7 +6,7 @@ using namespace UI::Page; DisplaySettings::DisplaySettings(std::shared_ptr aDisplay) : Base(UI::ID::Pages::DisplaySettings), mDisplay(aDisplay), mBrightnessSlider( - AddWidget(std::make_unique( + AddElement(std::make_unique( [this](auto aNewBrightness) { mDisplay->setBrightness(aNewBrightness); }, diff --git a/Platformio/OmoteUI/core/page/PageBase.cpp b/Platformio/OmoteUI/core/page/PageBase.cpp index 1f1a7fe..bc74a4b 100644 --- a/Platformio/OmoteUI/core/page/PageBase.cpp +++ b/Platformio/OmoteUI/core/page/PageBase.cpp @@ -6,7 +6,7 @@ using namespace UI::Page; Base::Base(ID aID) : Base(lv_obj_create(Screen::BackgroundScreen::getLvInstance()), aID) {} -Base::Base(lv_obj_t *aLvglSelf, ID aID) : WidgetContainer(aLvglSelf, aID) { +Base::Base(lv_obj_t *aLvglSelf, ID aID) : UIElement(aLvglSelf, aID) { SetHeight(lv_pct(100)); SetWidth(lv_pct(100)); SetPadding(Padding()); // Set Padding to default diff --git a/Platformio/OmoteUI/core/page/PageBase.hpp b/Platformio/OmoteUI/core/page/PageBase.hpp index c8c5705..8a649bd 100644 --- a/Platformio/OmoteUI/core/page/PageBase.hpp +++ b/Platformio/OmoteUI/core/page/PageBase.hpp @@ -1,6 +1,5 @@ #pragma once #include "UIElement.hpp" -#include "WidgetContainer.hpp" #include #include @@ -10,7 +9,7 @@ class PopUpScreen; namespace UI::Page { class Tab; class TabView; -class Base : public WidgetContainer { +class Base : public UIElement { // 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 diff --git a/Platformio/OmoteUI/core/page/SettingsPage.cpp b/Platformio/OmoteUI/core/page/SettingsPage.cpp index 329437a..d617110 100644 --- a/Platformio/OmoteUI/core/page/SettingsPage.cpp +++ b/Platformio/OmoteUI/core/page/SettingsPage.cpp @@ -19,7 +19,7 @@ SettingsPage::SettingsPage(std::shared_ptr aHardware) button->SetHeight(lv_pct(10)); button->SetWidth(lv_pct(10)); - mButton = AddWidget(std::move(button)); + mButton = AddElement(std::move(button)); } void SettingsPage::OnShow() {} @@ -41,7 +41,7 @@ void SettingsPage::AddSlider() { fakeSlider->SetY(nextY + 10); } - sliders.push_back(AddWidget(std::move(fakeSlider))); + sliders.push_back(AddElement(std::move(fakeSlider))); } bool SettingsPage::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { @@ -57,7 +57,7 @@ bool SettingsPage::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { case id::Aux2: if (aKeyEvent.mType == eventType::Release) { if (sliders.size() > 0) { - auto widget = RemoveWidget(sliders[0]); + RemoveElement(sliders[0]); sliders.erase( sliders.begin()); // sliders is non owning so after removing delete // it from non owning array diff --git a/Platformio/OmoteUI/core/page/SettingsPage.hpp b/Platformio/OmoteUI/core/page/SettingsPage.hpp index 623d71a..6908b26 100644 --- a/Platformio/OmoteUI/core/page/SettingsPage.hpp +++ b/Platformio/OmoteUI/core/page/SettingsPage.hpp @@ -13,8 +13,9 @@ public: protected: void OnShow() override; + void OnHide() override{}; - std::vector sliders; + std::vector sliders; Widget::Base *mButton; std::shared_ptr mHardware; }; diff --git a/Platformio/OmoteUI/core/page/TabView.cpp b/Platformio/OmoteUI/core/page/TabView.cpp index 4504830..a82fc65 100644 --- a/Platformio/OmoteUI/core/page/TabView.cpp +++ b/Platformio/OmoteUI/core/page/TabView.cpp @@ -7,12 +7,9 @@ using namespace UI::Page; Tab::Tab(lv_obj_t *aTab, ID aId) : Base(aTab, aId) {} void Tab::GiveContent(Page::Base::Ptr aContent) { - AddElement(aContent.get()); - mContent = std::move(aContent); + mContent = AddElement(std::move(aContent)); } -Base::Ptr Tab::TakeContent() { return std::move(mContent); } - bool Tab::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return mContent->OnKeyEvent(aKeyEvent); } diff --git a/Platformio/OmoteUI/core/page/TabView.hpp b/Platformio/OmoteUI/core/page/TabView.hpp index 5045dc6..c6f103b 100644 --- a/Platformio/OmoteUI/core/page/TabView.hpp +++ b/Platformio/OmoteUI/core/page/TabView.hpp @@ -22,7 +22,7 @@ public: void OnHide() override; private: - Base::Ptr mContent; + Base *mContent; }; class TabView : public Base { diff --git a/Platformio/OmoteUI/core/screen/HomeScreen.cpp b/Platformio/OmoteUI/core/screen/HomeScreen.cpp index c8b34b5..d8fdd61 100644 --- a/Platformio/OmoteUI/core/screen/HomeScreen.cpp +++ b/Platformio/OmoteUI/core/screen/HomeScreen.cpp @@ -5,33 +5,24 @@ using namespace UI::Screen; HomeScreen::HomeScreen(std::shared_ptr aHardware) - : Base(UI::ID::Screens::Home), mHardware(aHardware), - mTabView(ID(ID::Pages::INVALID_PAGE_ID)) { + : Base(UI::ID::Screens::Home), mHardware(aHardware) { SetBgColor(UI::Color::BLACK); SetPushAnimation(LV_SCR_LOAD_ANIM_FADE_IN); - AddElement(&mTabView); // Adds Tabview to Homescreen + mTabView = AddElement(std::make_unique( + ID(ID::Pages::INVALID_PAGE_ID))); // Adds Tabview to Homescreen // Adds pages to the Tab view - mTabView.AddTab(std::make_unique(aHardware), "Settings"); - mTabView.AddTab(std::make_unique(aHardware), "Settings1"); + mTabView->AddTab(std::make_unique(aHardware), "Settings"); + mTabView->AddTab(std::make_unique(aHardware), + "Settings1"); } void HomeScreen::SetBgColor(lv_color_t value, lv_style_selector_t selector) { - mTabView.SetBgColor(value, selector); + mTabView->SetBgColor(value, selector); UI::UIElement::SetBgColor(value, selector); } bool HomeScreen::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return false; }; - -void HomeScreen::OnShow() { mTabView.OnShow(); }; -void HomeScreen::OnHide() { mTabView.OnHide(); }; - -bool HomeScreen::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { - if (OnKeyEvent(aKeyEvent)) { - return true; - } - return mTabView.KeyEvent(aKeyEvent); -}; diff --git a/Platformio/OmoteUI/core/screen/HomeScreen.hpp b/Platformio/OmoteUI/core/screen/HomeScreen.hpp index 5e940b4..e4fab26 100644 --- a/Platformio/OmoteUI/core/screen/HomeScreen.hpp +++ b/Platformio/OmoteUI/core/screen/HomeScreen.hpp @@ -13,15 +13,13 @@ public: void SetBgColor(lv_color_t value, lv_style_selector_t selector = LV_PART_MAIN) override; - bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; - protected: - void OnShow() override; - void OnHide() override; + void OnShow() override{}; + void OnHide() override{}; bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; private: - Page::TabView mTabView; + Page::TabView *mTabView; std::shared_ptr mHardware = nullptr; }; diff --git a/Platformio/OmoteUI/core/screen/PopUpScreen.cpp b/Platformio/OmoteUI/core/screen/PopUpScreen.cpp index 6e108d2..b61d321 100644 --- a/Platformio/OmoteUI/core/screen/PopUpScreen.cpp +++ b/Platformio/OmoteUI/core/screen/PopUpScreen.cpp @@ -6,10 +6,15 @@ using namespace UI; using namespace UI::Screen; PopUpScreen::PopUpScreen(Page::Base::Ptr aPage) - : Screen::Base(UI::ID::Screens::PopUp), mContentPage(std::move(aPage)), - mExitButton(std::make_unique( - [this] { UI::Screen::Manager::getInstance().popScreen(this); })), - mTitle(std::make_unique(mContentPage->GetTitle())) { + : Screen::Base(UI::ID::Screens::PopUp) { + + mContentPage = AddElement(std::move(aPage)); + + mExitButton = AddElement(std::make_unique( + [this] { UI::Screen::Manager::getInstance().popScreen(this); })); + + mTitle = AddElement( + std::make_unique(mContentPage->GetTitle())); mExitButton->SetWidth(lv_pct(10)); mExitButton->SetHeight(mExitButton->GetWidth()); @@ -18,28 +23,13 @@ PopUpScreen::PopUpScreen(Page::Base::Ptr aPage) mTitle->SetWidth(mExitButton->GetX()); mTitle->SetHeight(mExitButton->GetHeight()); - mTitle->AlignTo(mExitButton.get(), LV_ALIGN_OUT_LEFT_BOTTOM); + mTitle->AlignTo(mExitButton, LV_ALIGN_OUT_LEFT_BOTTOM); mTitle->SetTextStyle(mTitle->GetTextStyle().Align(LV_TEXT_ALIGN_CENTER)); mContentPage->SetHeight(GetHeight() - mExitButton->GetBottom() - 5); mContentPage->SetY(mExitButton->GetBottom() + 5); - - AddElement(mContentPage.get()); - AddElement(mExitButton.get()); - AddElement(mTitle.get()); } bool PopUpScreen::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return mContentPage->OnKeyEvent(aKeyEvent); } - -void PopUpScreen::OnShow() { - mContentPage->OnShow(); - mExitButton->OnShow(); - mTitle->OnShow(); -}; -void PopUpScreen::OnHide() { - mContentPage->OnHide(); - mExitButton->OnHide(); - mTitle->OnHide(); -}; \ No newline at end of file diff --git a/Platformio/OmoteUI/core/screen/PopUpScreen.hpp b/Platformio/OmoteUI/core/screen/PopUpScreen.hpp index 069b345..3128017 100644 --- a/Platformio/OmoteUI/core/screen/PopUpScreen.hpp +++ b/Platformio/OmoteUI/core/screen/PopUpScreen.hpp @@ -14,14 +14,10 @@ public: bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; -protected: - void OnShow() override; - void OnHide() override; - private: - UI::Page::Base::Ptr mContentPage; - std::unique_ptr mExitButton; - std::unique_ptr mTitle; + UI::Page::Base *mContentPage = nullptr; + Widget::Button *mExitButton = nullptr; + Widget::Label *mTitle = nullptr; }; } // namespace UI::Screen \ No newline at end of file diff --git a/Platformio/OmoteUI/core/widget/WidgetBase.hpp b/Platformio/OmoteUI/core/widget/WidgetBase.hpp index 3a5f004..6b25d19 100644 --- a/Platformio/OmoteUI/core/widget/WidgetBase.hpp +++ b/Platformio/OmoteUI/core/widget/WidgetBase.hpp @@ -5,8 +5,6 @@ namespace UI { -class WidgetContainer; - namespace Screen { class PopUpScreen; } @@ -16,7 +14,6 @@ namespace UI::Widget { class Base : public UIElement { // Classes that Own Widgets - friend class UI::WidgetContainer; friend class UI::Screen::PopUpScreen; public: