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