diff --git a/Platformio/OmoteUI/UIs/BasicRefactored/BasicUI.cpp b/Platformio/OmoteUI/UIs/BasicRefactored/BasicUI.cpp index 47fd1e2..28c91aa 100644 --- a/Platformio/OmoteUI/UIs/BasicRefactored/BasicUI.cpp +++ b/Platformio/OmoteUI/UIs/BasicRefactored/BasicUI.cpp @@ -14,5 +14,5 @@ BasicUI::BasicUI(std::shared_ptr aHardware) }); Screen::Manager::getInstance().pushScreen( - std::make_unique()); + std::make_unique(aHardware)); } \ No newline at end of file diff --git a/Platformio/OmoteUI/UIs/LvglResourceManger.hpp b/Platformio/OmoteUI/UIs/LvglResourceManger.hpp index 71c516a..cf733d1 100644 --- a/Platformio/OmoteUI/UIs/LvglResourceManger.hpp +++ b/Platformio/OmoteUI/UIs/LvglResourceManger.hpp @@ -16,7 +16,7 @@ public: return mInstance; } - [[nodiscard]] std::scoped_lock scopeLock() { + [[nodiscard]] std::scoped_lock scopeLock() { return std::scoped_lock(mLvglMutex); } @@ -45,5 +45,5 @@ protected: } std::queue> mLvglTasks; - std::mutex mLvglMutex; + std::recursive_mutex mLvglMutex; }; diff --git a/Platformio/OmoteUI/core/UIElement.cpp b/Platformio/OmoteUI/core/UIElement.cpp index 9e9505c..53978e2 100644 --- a/Platformio/OmoteUI/core/UIElement.cpp +++ b/Platformio/OmoteUI/core/UIElement.cpp @@ -6,6 +6,10 @@ UIElement::UIElement(lv_obj_t *aLvglSelf, ID aId) : mLvglSelf(aLvglSelf), mId(aId) { auto lock = LvglResourceManger::GetInstance().scopeLock(); mLvglSelf->user_data = this; + // Register Handler so that all object are able to override OnLvglEvent to + // handle events easilyOnLvEvent + lv_obj_add_event_cb(mLvglSelf, UIElement::LvglEventHandler, LV_EVENT_ALL, + this); } UIElement::~UIElement() { @@ -68,6 +72,8 @@ lv_coord_t UIElement::GetX() { return lv_obj_get_x(mLvglSelf); } +lv_coord_t UIElement::GetBottom() { return GetY() + GetHeight(); }; + void UIElement::AlignTo(UIElement *anElementToAlignTo, lv_align_t anAlignment, lv_coord_t aXoffset, lv_coord_t aYOffset) { LvglResourceManger::GetInstance().AttemptNow([=] { @@ -114,4 +120,11 @@ bool UIElement::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return OnKeyEvent(aKeyEvent); } +//////////////////// Statics ////////////////////////// + +void UIElement::LvglEventHandler(lv_event_t *anEvent) { + auto lock = LvglResourceManger::GetInstance().scopeLock(); + reinterpret_cast(anEvent->user_data)->OnLvglEvent(anEvent); +} + } // namespace UI diff --git a/Platformio/OmoteUI/core/UIElement.hpp b/Platformio/OmoteUI/core/UIElement.hpp index 239870f..0b099bf 100644 --- a/Platformio/OmoteUI/core/UIElement.hpp +++ b/Platformio/OmoteUI/core/UIElement.hpp @@ -30,9 +30,10 @@ public: lv_coord_t GetY(); lv_coord_t GetX(); + lv_coord_t GetBottom(); - void AlignTo(UIElement *anElementToAlignWith,lv_align_t anAlignment, - lv_coord_t aXoffset = 0, lv_coord_t aYOffset = 0); + void AlignTo(UIElement *anElementToAlignWith, lv_align_t anAlignment, + lv_coord_t aXoffset = 0, lv_coord_t aYOffset = 0); virtual void AddElement(UIElement *anElement); @@ -54,6 +55,9 @@ protected: /// @brief Override in child class to run something after element is hidden virtual void OnHide() = 0; + // Override in object to handle LVGL events for that object + virtual void OnLvglEvent(lv_event_t *anEvent){}; + /// @brief Set KeyEvent to the UI element to see if it wants to handle it virtual bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent); @@ -63,6 +67,8 @@ protected: virtual bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) = 0; private: + static void LvglEventHandler(lv_event_t *anEvent); + lv_obj_t *mLvglSelf; const ID mId; }; diff --git a/Platformio/OmoteUI/core/page/SettingsPage.cpp b/Platformio/OmoteUI/core/page/SettingsPage.cpp index 01e088f..d4062bd 100644 --- a/Platformio/OmoteUI/core/page/SettingsPage.cpp +++ b/Platformio/OmoteUI/core/page/SettingsPage.cpp @@ -1,11 +1,18 @@ #include "SettingsPage.hpp" #include "BackgroundScreen.hpp" +#include "Button.hpp" using namespace UI::Page; SettingsPage::SettingsPage(std::shared_ptr aHardware) : Base(ID::Pages::Settings), mHardware(aHardware) { SetBgColor(lv_color_make(255, 0, 0)); + auto button = std::make_unique([this] { AddSlider(); }); + button->SetY(0); + button->SetHeight(lv_pct(10)); + button->SetWidth(lv_pct(10)); + + mButton = AddWidget(std::move(button)); } void SettingsPage::OnShow() {} @@ -16,7 +23,7 @@ void SettingsPage::AddSlider() { fakeSlider->SetHeight(lv_pct(10)); fakeSlider->SetWidth(GetWidth()); if (sliders.empty()) { - fakeSlider->SetY(0); + fakeSlider->SetY(mButton->GetBottom()); } else { auto nextY = sliders.back()->GetY() + sliders.back()->GetHeight(); fakeSlider->SetY(nextY + 10); @@ -50,7 +57,7 @@ bool SettingsPage::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { case id::Aux4: break; default: - used = false; + used = Page::Base::OnKeyEvent(aKeyEvent); break; } return used; diff --git a/Platformio/OmoteUI/core/page/SettingsPage.hpp b/Platformio/OmoteUI/core/page/SettingsPage.hpp index 759bacd..23cea9b 100644 --- a/Platformio/OmoteUI/core/page/SettingsPage.hpp +++ b/Platformio/OmoteUI/core/page/SettingsPage.hpp @@ -14,6 +14,7 @@ protected: void OnShow() override; std::vector sliders; + Widget::Base *mButton; std::shared_ptr mHardware; }; } // namespace UI::Page diff --git a/Platformio/OmoteUI/core/widget/Button.cpp b/Platformio/OmoteUI/core/widget/Button.cpp new file mode 100644 index 0000000..d901d8b --- /dev/null +++ b/Platformio/OmoteUI/core/widget/Button.cpp @@ -0,0 +1,14 @@ +#include "Button.hpp" +#include "BackgroundScreen.hpp" + +using namespace UI::Widget; + +Button::Button(std::function aOnPressHandler) + : Base(lv_btn_create(UI::Screen::BackgroundScreen::getLvInstance())), + mOnPress(aOnPressHandler) {} + +void Button::OnLvglEvent(lv_event_t *anEvent) { + if (anEvent->code == LV_EVENT_PRESSED) { + mOnPress(); + } +}; \ No newline at end of file diff --git a/Platformio/OmoteUI/core/widget/Button.hpp b/Platformio/OmoteUI/core/widget/Button.hpp new file mode 100644 index 0000000..304f892 --- /dev/null +++ b/Platformio/OmoteUI/core/widget/Button.hpp @@ -0,0 +1,15 @@ +#pragma once +#include "WidgetBase.hpp" + +namespace UI::Widget { +class Button : public Base { +public: + Button(std::function aOnPressHandler); + + void OnLvglEvent(lv_event_t *anEvent) override; + +private: + std::function mOnPress; +}; + +} // namespace UI::Widget \ No newline at end of file