From 7b7045f62bb5e271ba36828e3ded63470c0bb09b Mon Sep 17 00:00:00 2001 From: MatthewColvin Date: Sun, 8 Oct 2023 12:32:59 -0500 Subject: [PATCH] convert Screen manager to use vector to allow popper of screen to use the Page. Add ability to delay destruction of an object in LVGL after the core object has been destructed. This was added for animations to work . make pop up Screen to allow for easy pushing of pages by wrapping it in a screen. Use this all in the settings page to launch a fake display settings --- Platformio/OmoteUI/core/ScreenManager.cpp | 30 +++++++++++++++++-- Platformio/OmoteUI/core/ScreenManager.hpp | 6 ++-- Platformio/OmoteUI/core/UIElement.cpp | 9 ++++-- Platformio/OmoteUI/core/UIElement.hpp | 10 +++++++ .../OmoteUI/core/screen/PopUpScreen.cpp | 10 ++++++- .../OmoteUI/core/screen/PopUpScreen.hpp | 3 ++ Platformio/OmoteUI/core/screen/ScreenBase.cpp | 12 +++++++- Platformio/OmoteUI/core/screen/ScreenBase.hpp | 5 ++++ 8 files changed, 76 insertions(+), 9 deletions(-) diff --git a/Platformio/OmoteUI/core/ScreenManager.cpp b/Platformio/OmoteUI/core/ScreenManager.cpp index b349002..f7fdbc0 100644 --- a/Platformio/OmoteUI/core/ScreenManager.cpp +++ b/Platformio/OmoteUI/core/ScreenManager.cpp @@ -16,8 +16,8 @@ void Manager::pushScreen(Screen::Base::Ptr aScreen, } void Manager::pushScreen(Screen::Base::Ptr aScreen) { - mScreens.push(std::move(aScreen)); - mScreens.top()->Show(); + mScreens.push_back(std::move(aScreen)); + mScreens.back()->Show(); } void Manager::pushPopUp(Page::Base::Ptr aPopUpPage, @@ -26,7 +26,31 @@ void Manager::pushPopUp(Page::Base::Ptr aPopUpPage, aPushAnimation); } +UI::Screen::Base::Ptr Manager::popScreen(Screen::Base *aScreenToRemove) { + auto screenToPop = std::find_if( + mScreens.begin(), mScreens.end(), [aScreenToRemove](auto &screenInStack) { + return screenInStack.get() == aScreenToRemove; + }); + + bool isPopOffTopOfStack = mScreens.end() - 1 == screenToPop; + Screen::Base::Ptr retVal = nullptr; + if (screenToPop != mScreens.end()) { + retVal = std::move(*screenToPop); + mScreens.erase(screenToPop); + if (isPopOffTopOfStack) { + // Make sure to show correct top of stack + // since we popped the top screen off + mScreens.back()->Show(); + } + } + // In order to make sure the Transition can complete + // flag the removed screen to stay alive in case it falls + // out of scope and gets deleted quickly after this. + retVal->SetKeepAliveTime(mScreens.back()->GetTransitionTime() + 500); + return retVal; +} + bool Manager::distributeKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { // Send Key Even to top Screen for handling - return mScreens.top()->KeyEvent(aKeyEvent); + return mScreens.back()->KeyEvent(aKeyEvent); } \ No newline at end of file diff --git a/Platformio/OmoteUI/core/ScreenManager.hpp b/Platformio/OmoteUI/core/ScreenManager.hpp index ac3fbc6..9ed7e32 100644 --- a/Platformio/OmoteUI/core/ScreenManager.hpp +++ b/Platformio/OmoteUI/core/ScreenManager.hpp @@ -3,7 +3,7 @@ #include "PageBase.hpp" #include "ScreenBase.hpp" #include -#include +#include namespace UI::Screen { @@ -19,13 +19,15 @@ public: pushPopUp(UI::Page::Base::Ptr aPopUpPage, lv_scr_load_anim_t aPushAnimation = LV_SCR_LOAD_ANIM_OVER_LEFT); + Screen::Base::Ptr popScreen(Screen::Base *aScreenToRemove); + bool distributeKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent); private: Manager(); static Manager mManager; - std::stack mScreens; + std::vector mScreens; }; } // namespace UI::Screen \ No newline at end of file diff --git a/Platformio/OmoteUI/core/UIElement.cpp b/Platformio/OmoteUI/core/UIElement.cpp index 53978e2..42f565b 100644 --- a/Platformio/OmoteUI/core/UIElement.cpp +++ b/Platformio/OmoteUI/core/UIElement.cpp @@ -14,8 +14,13 @@ UIElement::UIElement(lv_obj_t *aLvglSelf, ID aId) UIElement::~UIElement() { auto lock = LvglResourceManger::GetInstance().scopeLock(); - if (lv_obj_is_valid(mLvglSelf)) { - lv_obj_del(mLvglSelf); + if (lv_obj_is_valid(LvglSelf())) { + if (mLvglKeepAliveTime > 0) { + lv_obj_del_delayed(LvglSelf(), mLvglKeepAliveTime); + } else { + lv_obj_del(LvglSelf()); + } + lv_obj_remove_event_cb(mLvglSelf, UIElement::LvglEventHandler); } } diff --git a/Platformio/OmoteUI/core/UIElement.hpp b/Platformio/OmoteUI/core/UIElement.hpp index 0b099bf..bad7ee7 100644 --- a/Platformio/OmoteUI/core/UIElement.hpp +++ b/Platformio/OmoteUI/core/UIElement.hpp @@ -41,6 +41,15 @@ public: template static UIElemTy GetElement(lv_obj_t *aLvglObject); + /// @brief There are use cases in which objects + /// need to stay alive in LVGL but can die + /// in terms of our usage this is a helper for these + /// use Sparengly!!! + /// @param aTimeToKeepLvglObj + void SetKeepAliveTime(uint32_t aTimeToKeepLvglObj) { + mLvglKeepAliveTime = aTimeToKeepLvglObj; + } + protected: /// @brief get Lvgl object refernce to use in LVGL APIs /// @return lvgl object a @@ -71,6 +80,7 @@ private: lv_obj_t *mLvglSelf; const ID mId; + uint32_t mLvglKeepAliveTime = 0; }; /** diff --git a/Platformio/OmoteUI/core/screen/PopUpScreen.cpp b/Platformio/OmoteUI/core/screen/PopUpScreen.cpp index 9f2918b..22390eb 100644 --- a/Platformio/OmoteUI/core/screen/PopUpScreen.cpp +++ b/Platformio/OmoteUI/core/screen/PopUpScreen.cpp @@ -1,12 +1,20 @@ #include "PopUpScreen.hpp" +#include "ScreenManager.hpp" using namespace UI; using namespace UI::Screen; PopUpScreen::PopUpScreen(Page::Base::Ptr aPage) - : Screen::Base(UI::ID::Screens::PopUp), mContentPage(std::move(aPage)) { + : Screen::Base(UI::ID::Screens::PopUp), mContentPage(std::move(aPage)), + mExitButton(std::make_unique( + [this] { UI::Screen::Manager::getInstance().popScreen(this); })) { + mExitButton->SetWidth(30); + mExitButton->SetHeight(30); + mExitButton->SetBgColor(lv_color_make(255, 0, 0)); + mExitButton->AlignTo(this, LV_ALIGN_TOP_RIGHT, -5, 5); AddElement(mContentPage.get()); + AddElement(mExitButton.get()); } bool PopUpScreen::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { diff --git a/Platformio/OmoteUI/core/screen/PopUpScreen.hpp b/Platformio/OmoteUI/core/screen/PopUpScreen.hpp index f018bf2..cea376a 100644 --- a/Platformio/OmoteUI/core/screen/PopUpScreen.hpp +++ b/Platformio/OmoteUI/core/screen/PopUpScreen.hpp @@ -1,6 +1,8 @@ #pragma once +#include "Button.hpp" #include "PageBase.hpp" #include "ScreenBase.hpp" + namespace UI::Screen { /// @brief A Screen that allows easy display of a page that @@ -13,6 +15,7 @@ public: private: UI::Page::Base::Ptr mContentPage; + std::unique_ptr mExitButton; }; } // namespace UI::Screen \ No newline at end of file diff --git a/Platformio/OmoteUI/core/screen/ScreenBase.cpp b/Platformio/OmoteUI/core/screen/ScreenBase.cpp index b159dcc..9ba00c3 100644 --- a/Platformio/OmoteUI/core/screen/ScreenBase.cpp +++ b/Platformio/OmoteUI/core/screen/ScreenBase.cpp @@ -5,7 +5,8 @@ using namespace UI::Screen; Base::Base(ID aId) : UIElement(lv_obj_create(NULL), aId) {} void Base::Show() { - lv_scr_load_anim(LvglSelf(), mPushAnimation, 1000, 1000, false); + lv_scr_load_anim(LvglSelf(), mPushAnimation, mTransitionAnimationTime, + mTransitionDelayTime, false); UIElement::Show(); } @@ -13,4 +14,13 @@ void Base::SetPushAnimation(lv_scr_load_anim_t aShowAnimation) { mPushAnimation = aShowAnimation; } +uint32_t Base::GetTransitionTime() { + return mTransitionAnimationTime + mTransitionDelayTime; +} + +void Base::SetTransitionTimes(uint32_t aAnimationTime, uint32_t aDelay) { + mTransitionAnimationTime = aAnimationTime; + mTransitionDelayTime = aDelay; +} + bool Base::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return false; }; \ No newline at end of file diff --git a/Platformio/OmoteUI/core/screen/ScreenBase.hpp b/Platformio/OmoteUI/core/screen/ScreenBase.hpp index 7a3db70..0bea2f3 100644 --- a/Platformio/OmoteUI/core/screen/ScreenBase.hpp +++ b/Platformio/OmoteUI/core/screen/ScreenBase.hpp @@ -19,6 +19,9 @@ public: void SetPushAnimation(lv_scr_load_anim_t aPushAnimation); + uint32_t GetTransitionTime(); + void SetTransitionTimes(uint32_t aAnimationTime, uint32_t aDelay = 0); + protected: void Show() override; void OnShow() override{}; @@ -27,6 +30,8 @@ protected: private: lv_scr_load_anim_t mPushAnimation = LV_SCR_LOAD_ANIM_NONE; + uint32_t mTransitionAnimationTime = 1000; // 1000 ms / 1 sec + uint32_t mTransitionDelayTime = 0; }; } // namespace UI::Screen \ No newline at end of file