From 7d68cce6ad635e3d36e6624c58fc1acb89aff06a Mon Sep 17 00:00:00 2001 From: Matthew Colvin Date: Thu, 12 Oct 2023 15:20:38 -0500 Subject: [PATCH] Add start stop event handling in UIElement Add demo page to get play logic out of settings page. Add a demo page and a Settings page to the home screen. --- .../OmoteUI/UIs/BasicRefactored/page/Demo.cpp | 54 ++++++++++++++++ .../OmoteUI/UIs/BasicRefactored/page/Demo.hpp | 22 +++++++ .../UIs/BasicRefactored/page/SettingsPage.cpp | 61 ++----------------- .../UIs/BasicRefactored/page/SettingsPage.hpp | 8 +-- .../UIs/BasicRefactored/screen/HomeScreen.cpp | 3 +- Platformio/OmoteUI/core/UIElement.cpp | 13 ++++ Platformio/OmoteUI/core/UIElement.hpp | 7 ++- Platformio/OmoteUI/core/UIElementIds.hpp | 2 + Platformio/OmoteUI/core/widget/List.cpp | 32 ++++++++++ Platformio/OmoteUI/core/widget/List.hpp | 30 +++++++++ 10 files changed, 171 insertions(+), 61 deletions(-) create mode 100644 Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.cpp create mode 100644 Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.hpp create mode 100644 Platformio/OmoteUI/core/widget/List.cpp create mode 100644 Platformio/OmoteUI/core/widget/List.hpp diff --git a/Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.cpp b/Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.cpp new file mode 100644 index 0000000..c9213b9 --- /dev/null +++ b/Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.cpp @@ -0,0 +1,54 @@ +#include "Demo.hpp" +#include "Slider.hpp" + +using namespace UI::Page; + +Demo::Demo(std::shared_ptr aHardware): Base(ID::Pages::Demo), mHardware(aHardware){ + + +} + +void Demo::AddSlider() { + auto fakeSlider = std::make_unique([](auto data){}); + fakeSlider->SetHeight(lv_pct(10)); + fakeSlider->SetWidth(GetContentWidth()); + if (sliders.empty()) { + fakeSlider->AlignTo(this,LV_ALIGN_TOP_MID); + } else { + auto nextY = sliders.back()->GetY() + sliders.back()->GetHeight(); + fakeSlider->SetY(nextY + 10); + } + + sliders.push_back(AddElement(std::move(fakeSlider))); +} + +bool Demo::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { + using id = KeyPressAbstract::KeyId; + using eventType = KeyPressAbstract::KeyEvent::Type; + bool used = true; + switch (aKeyEvent.mId) { + case id::Aux1: + if (aKeyEvent.mType == eventType::Press) { + AddSlider(); + } + break; + case id::Aux2: + if (aKeyEvent.mType == eventType::Release) { + if (sliders.size() > 0) { + RemoveElement(sliders[0]); + sliders.erase( + sliders.begin()); // sliders is non owning so after removing delete + // it from non owning array + } + } + break; + case id::Aux3: + break; + case id::Aux4: + break; + default: + used = Page::Base::OnKeyEvent(aKeyEvent); + break; + } + return used; +} \ No newline at end of file diff --git a/Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.hpp b/Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.hpp new file mode 100644 index 0000000..63a839e --- /dev/null +++ b/Platformio/OmoteUI/UIs/BasicRefactored/page/Demo.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "PageBase.hpp" +#include "HardwareAbstract.hpp" + +namespace UI::Page{ + +class Demo : public Base{ +public: + Demo(std::shared_ptr aHardware); + + void AddSlider(); + + void OnShow()override{}; + void OnHide()override{}; + bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent); + +private: + std::shared_ptr mHardware; + std::vector sliders; +}; + +} \ No newline at end of file diff --git a/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.cpp b/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.cpp index 086d6a2..79f4721 100644 --- a/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.cpp +++ b/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.cpp @@ -2,6 +2,7 @@ #include "BackgroundScreen.hpp" #include "Button.hpp" #include "Slider.hpp" +#include "List.hpp" #include "Colors.hpp" #include "DisplaySettings.hpp" #include "PopUpScreen.hpp" @@ -11,66 +12,16 @@ using namespace UI::Page; using namespace UI::Color; SettingsPage::SettingsPage(std::shared_ptr aHardware) - : Base(ID::Pages::Settings), mHardware(aHardware) { - SetBgColor(RED); - auto button = - std::make_unique([this] { PushDisplaySettings(); }); - button->SetBorder(button->GetBorder().Color(BLUE).Width(2)); - button->SetY(0); - button->SetHeight(lv_pct(10)); - button->SetWidth(lv_pct(10)); + : Base(ID::Pages::Settings), + mSettingsList(AddElement(std::make_unique())), + mHardware(aHardware) { - mButton = AddElement(std::move(button)); + mSettingsList->AddItem("Display",LV_SYMBOL_EYE_OPEN,[this] { PushDisplaySettings(); }); + mSettingsList->AddItem("Wifi",LV_SYMBOL_WIFI,[]{}); } -void SettingsPage::OnShow() {} - void SettingsPage::PushDisplaySettings() { UI::Screen::Manager::getInstance().pushPopUp( std::make_unique(mHardware->display())); } -void SettingsPage::AddSlider() { - auto fakeSlider = std::make_unique([](auto data){}); - fakeSlider->SetHeight(lv_pct(10)); - fakeSlider->SetWidth(GetContentWidth()); - if (sliders.empty()) { - fakeSlider->SetY(mButton->GetBottom()); - } else { - auto nextY = sliders.back()->GetY() + sliders.back()->GetHeight(); - fakeSlider->SetY(nextY + 10); - } - - sliders.push_back(AddElement(std::move(fakeSlider))); -} - -bool SettingsPage::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { - using id = KeyPressAbstract::KeyId; - using eventType = KeyPressAbstract::KeyEvent::Type; - bool used = true; - switch (aKeyEvent.mId) { - case id::Aux1: - if (aKeyEvent.mType == eventType::Press) { - AddSlider(); - } - break; - case id::Aux2: - if (aKeyEvent.mType == eventType::Release) { - if (sliders.size() > 0) { - RemoveElement(sliders[0]); - sliders.erase( - sliders.begin()); // sliders is non owning so after removing delete - // it from non owning array - } - } - break; - case id::Aux3: - break; - case id::Aux4: - break; - default: - used = Page::Base::OnKeyEvent(aKeyEvent); - break; - } - return used; -} \ No newline at end of file diff --git a/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.hpp b/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.hpp index dc7e757..b5636f4 100644 --- a/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.hpp +++ b/Platformio/OmoteUI/UIs/BasicRefactored/page/SettingsPage.hpp @@ -3,23 +3,23 @@ namespace UI::Widget{ class Button; + class List; } namespace UI::Page { class SettingsPage : public Base { public: SettingsPage(std::shared_ptr aHardware = nullptr); - bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override; + bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override{return false;}; - void AddSlider(); void PushDisplaySettings(); protected: - void OnShow() override; + void OnShow() override{}; void OnHide() override{}; - std::vector sliders; Widget::Button *mButton; + Widget::List *mSettingsList; std::shared_ptr mHardware; }; } // namespace UI::Page diff --git a/Platformio/OmoteUI/UIs/BasicRefactored/screen/HomeScreen.cpp b/Platformio/OmoteUI/UIs/BasicRefactored/screen/HomeScreen.cpp index 1098669..8817cba 100644 --- a/Platformio/OmoteUI/UIs/BasicRefactored/screen/HomeScreen.cpp +++ b/Platformio/OmoteUI/UIs/BasicRefactored/screen/HomeScreen.cpp @@ -1,6 +1,7 @@ #include "HomeScreen.hpp" #include "Colors.hpp" #include "SettingsPage.hpp" +#include "Demo.hpp" using namespace UI::Screen; @@ -15,7 +16,7 @@ HomeScreen::HomeScreen(std::shared_ptr aHardware) // Adds pages to the Tab view mTabView->AddTab(std::make_unique(aHardware)); - mTabView->AddTab(std::make_unique(aHardware)); + mTabView->AddTab(std::make_unique(aHardware)); } void HomeScreen::SetBgColor(lv_color_t value, lv_style_selector_t selector) { diff --git a/Platformio/OmoteUI/core/UIElement.cpp b/Platformio/OmoteUI/core/UIElement.cpp index 69eb38e..ac8a5a5 100644 --- a/Platformio/OmoteUI/core/UIElement.cpp +++ b/Platformio/OmoteUI/core/UIElement.cpp @@ -249,6 +249,19 @@ void UIElement::SetBgOpacity(lv_opa_t aOpacity, lv_style_selector_t aStyle) { }); } +void UIElement::StartLvglEventHandler(){ + if(mIsHandlingLvglEvents){ return; } + lv_obj_add_event_cb(mLvglSelf, UIElement::LvglEventHandler, LV_EVENT_ALL, + this); + mIsHandlingLvglEvents = true; +} +void UIElement::StopLvglEventHandler(){ + if(!mIsHandlingLvglEvents){return;} + lv_obj_remove_event_cb_with_user_data(mLvglSelf,UIElement::LvglEventHandler, + this); + mIsHandlingLvglEvents = false; +} + void UIElement::Show() { if (IsVisible()) { return; diff --git a/Platformio/OmoteUI/core/UIElement.hpp b/Platformio/OmoteUI/core/UIElement.hpp index c62e870..a464298 100644 --- a/Platformio/OmoteUI/core/UIElement.hpp +++ b/Platformio/OmoteUI/core/UIElement.hpp @@ -81,12 +81,16 @@ public: /// @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!!! + /// use Sparingly!!! /// @param aTimeToKeepLvglObj void SetKeepAliveTime(uint32_t aTimeToKeepLvglObj) { mLvglKeepAliveTime = aTimeToKeepLvglObj; } + + void StartLvglEventHandler(); + void StopLvglEventHandler(); + protected: /// @brief get Lvgl object refernce to use in LVGL APIs /// @return lvgl object a @@ -118,6 +122,7 @@ private: lv_obj_t *mLvglSelf; const ID mId; uint32_t mLvglKeepAliveTime = 0; + bool mIsHandlingLvglEvents = true; /// @brief Elements that are currently in this element std::vector mContainedElements; diff --git a/Platformio/OmoteUI/core/UIElementIds.hpp b/Platformio/OmoteUI/core/UIElementIds.hpp index 6fd8c0f..15d4dcf 100644 --- a/Platformio/OmoteUI/core/UIElementIds.hpp +++ b/Platformio/OmoteUI/core/UIElementIds.hpp @@ -17,6 +17,7 @@ public: Slider = static_cast(Screens::INVALID_SCREEN_ID) + 1, Button, Label, + List, BrightnessSlider, INVALID_WIDGET_ID }; @@ -24,6 +25,7 @@ public: enum class Pages { Settings = static_cast(Widgets::INVALID_WIDGET_ID) + 1, DisplaySettings, + Demo, INVALID_PAGE_ID }; diff --git a/Platformio/OmoteUI/core/widget/List.cpp b/Platformio/OmoteUI/core/widget/List.cpp new file mode 100644 index 0000000..c0d977f --- /dev/null +++ b/Platformio/OmoteUI/core/widget/List.cpp @@ -0,0 +1,32 @@ +#include "List.hpp" +#include "BackgroundScreen.hpp" +using namespace UI; +using namespace UI::Widget; + +ListItem::ListItem(lv_obj_t *aListItem, std::function onItemSelected): + UIElement(aListItem,ID()), + mSelectedHandler(std::move(onItemSelected)){} + +void ListItem::OnLvglEvent(lv_event_t* anEvent){ + if(anEvent->code == LV_EVENT_CLICKED){ + if(mSelectedHandler){ + mSelectedHandler(); + } + } +} + +List::List():Base(lv_list_create(Screen::BackgroundScreen::getLvInstance()),ID::Widgets::List){ + StopLvglEventHandler(); +} + +void List::AddItem(std::string aTitle, const char* aSymbol, std::function onItemSelected){ + auto lvListItem = lv_list_add_btn(LvglSelf(),aSymbol,aTitle.c_str()); + mListItems.push_back(std::make_unique(lvListItem, std::move(onItemSelected))); + mListItems.back()->SetHeight(lv_pct(20)); +} + +void List::OnLvglEvent(lv_event_t* anEvent){ + if(anEvent->code == LV_EVENT_CLICKED){ + auto tgt = anEvent->target; + } +} \ No newline at end of file diff --git a/Platformio/OmoteUI/core/widget/List.hpp b/Platformio/OmoteUI/core/widget/List.hpp new file mode 100644 index 0000000..6a80fb3 --- /dev/null +++ b/Platformio/OmoteUI/core/widget/List.hpp @@ -0,0 +1,30 @@ +#pragma once +#include "WidgetBase.hpp" + +namespace UI::Widget{ + +class ListItem : public UIElement{ +public: + ListItem(lv_obj_t* aListItem, std::function onItemSelected); +protected: + void OnLvglEvent(lv_event_t* anEvent) override; + bool OnKeyEvent(KeyPressAbstract::KeyEvent anEvent)override{return false;}; + void OnShow()override{}; + void OnHide()override{}; +private: + std::function mSelectedHandler; +}; + +class List : public Base{ +public: + List(); + void AddItem(std::string aTitle, const char* aSymbol, std::function onItemSelected); + +protected: + void OnLvglEvent(lv_event_t* anEvent)override; + +private: + std::vector mListItems; +}; + +} \ No newline at end of file