From 235d8e043fa3deb22eef2ad652a176630a48ec24 Mon Sep 17 00:00:00 2001 From: MatthewColvin Date: Fri, 6 Oct 2023 22:11:15 -0500 Subject: [PATCH] Convert Lvgl resource manager to recursive mutex to allow re locking in thread. This helps with creation and getting values and should be safe since it still keeps lvgl on one thread at a time. Add OnLvglEvent to UIElement that allows foreasy place for UI Elements to respond to LVGL events . Add button class that can react to being presssed via a callback function. Add GetBottom() api to allow easy grabbing of bottom Y coordinate. use some new stuff in the settings page to sort test it all out. --- .../OmoteUI/UIs/BasicRefactored/BasicUI.cpp | 2 +- Platformio/OmoteUI/UIs/LvglResourceManger.hpp | 4 ++-- Platformio/OmoteUI/core/UIElement.cpp | 13 +++++++++++++ Platformio/OmoteUI/core/UIElement.hpp | 10 ++++++++-- Platformio/OmoteUI/core/page/SettingsPage.cpp | 11 +++++++++-- Platformio/OmoteUI/core/page/SettingsPage.hpp | 1 + Platformio/OmoteUI/core/widget/Button.cpp | 14 ++++++++++++++ Platformio/OmoteUI/core/widget/Button.hpp | 15 +++++++++++++++ 8 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 Platformio/OmoteUI/core/widget/Button.cpp create mode 100644 Platformio/OmoteUI/core/widget/Button.hpp 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