propigate key events around UI

use key events to add and remove sliders from settings as example
This commit is contained in:
MatthewColvin 2023-10-01 18:53:25 -05:00
parent a44e92ea5d
commit 3bd2b1a98a
13 changed files with 148 additions and 20 deletions

View file

@ -6,6 +6,12 @@ UIElement::UIElement(lv_obj_t *aLvglSelf, ID aId)
mLvglSelf->user_data = this;
}
UIElement::~UIElement() {
if (lv_obj_is_valid(mLvglSelf)) {
lv_obj_del(mLvglSelf);
}
}
void UIElement::AddElement(UIElement *anUIElement) {
lv_obj_set_parent(anUIElement->mLvglSelf, mLvglSelf);
}

View file

@ -1,7 +1,7 @@
#pragma once
#include "UIElementIds.hpp"
#include "lvgl.h"
#include <lvgl.h>
#include "KeyPressAbstract.hpp"
@ -11,6 +11,7 @@ class UIElement {
public:
UIElement(lv_obj_t *aLvglSelf, const ID aId = ID());
virtual ~UIElement();
virtual void SetBgColor(lv_color_t value,
lv_style_selector_t selector = LV_PART_MAIN);

View file

@ -1,5 +1,5 @@
#include "BackgroundScreen.hpp"
#include "PageBase.hpp"
#include "BackgroundScreen.hpp"
using namespace UI::Page;
@ -11,8 +11,37 @@ Base::Base(lv_obj_t *aLvglSelf, ID aID) : UIElement(aLvglSelf, aID) {
SetWidth(lv_pct(100));
lv_obj_set_align(aLvglSelf, LV_ALIGN_CENTER);
}
void Base::AddWidget(Widget::Base::Ptr aWidget) {
// Return non owning refrence to widget
UI::Widget::Base *Base::AddWidget(Widget::Base::Ptr aWidget) {
AddElement(aWidget.get());
mWidgets.push_back(std::move(aWidget));
}
return mWidgets[mWidgets.size() - 1].get();
}
UI::Widget::Base::Ptr Base::RemoveWidget(Widget::Base *aWidgetRefrence) {
auto widgetToRemoveIter = std::find_if(
mWidgets.begin(), mWidgets.end(), [aWidgetRefrence](auto &aWidget) {
return aWidget.get() == aWidgetRefrence;
});
if (widgetToRemoveIter != mWidgets.end()) {
auto widget = std::move(*widgetToRemoveIter);
mWidgets.erase(widgetToRemoveIter);
return widget;
}
return nullptr;
}
bool Base::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) {
if (OnKeyEvent(aKeyEvent)) {
return true;
}
for (auto &widget : mWidgets) {
auto used = widget->KeyEvent(aKeyEvent);
if (used) {
return true;
}
}
return false;
};
bool Base::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return false; };

View file

@ -4,8 +4,10 @@
#include <vector>
namespace UI::Page {
class Tab;
class TabView;
class Base : public UIElement {
friend Tab; // Allow Tab to Forward all Key Events to its page
friend TabView; // Allow Tab view to call OnShow and OnHide Since it can show
// and Hide pages by swiping
public:
@ -13,16 +15,18 @@ public:
Base(ID aID);
Base(lv_obj_t *aLvglSelf, ID aID);
virtual ~Base() = default;
void AddWidget(Widget::Base::Ptr aWidget);
Widget::Base *AddWidget(Widget::Base::Ptr aWidget);
Widget::Base::Ptr RemoveWidget(Widget::Base *aWidgetRefrence);
size_t GetNumWidgets() { return mWidgets.size(); }
protected:
void OnShow() override{};
void OnHide() override{};
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override {
return false;
};
bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
private:
std::vector<Widget::Base::Ptr> mWidgets;

View file

@ -1,5 +1,5 @@
#include "BackgroundScreen.hpp"
#include "SettingsPage.hpp"
#include "BackgroundScreen.hpp"
using namespace UI::Page;
@ -7,7 +7,9 @@ SettingsPage::SettingsPage() : Base(ID::Pages::Settings) {
SetBgColor(lv_color_make(255, 0, 0));
}
void SettingsPage::OnShow() {
void SettingsPage::OnShow() {}
void SettingsPage::AddSlider() {
auto fakeSlider = std::make_unique<UI::Widget::Base>(
lv_slider_create(UI::Screen::BackgroundScreen::getLvInstance()));
fakeSlider->SetHeight(lv_pct(10));
@ -16,5 +18,36 @@ void SettingsPage::OnShow() {
auto sliderHeight = fakeSlider->GetHeight();
fakeSlider->SetY(sliderHeight * GetNumWidgets());
AddWidget(std::move(fakeSlider));
sliders.push_back(AddWidget(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) {
auto widget = RemoveWidget(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 = false;
break;
}
return used;
}

View file

@ -5,7 +5,13 @@ class SettingsPage : public Base {
public:
SettingsPage();
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
void AddSlider();
protected:
void OnShow() override;
std::vector<Widget::Base *> sliders;
};
} // namespace UI::Page

View file

@ -1,5 +1,5 @@
#include "BackgroundScreen.hpp"
#include "TabView.hpp"
#include "BackgroundScreen.hpp"
#include <string>
using namespace UI::Page;
@ -13,6 +13,16 @@ void Tab::GiveContent(Page::Base::Ptr aContent) {
Base::Ptr Tab::TakeContent() { return std::move(mContent); }
bool Tab::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) {
return mContent->OnKeyEvent(aKeyEvent);
}
bool Tab::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) {
return mContent->KeyEvent(aKeyEvent);
}
/////////////////////TabView/////////////////////////////////////
TabView::TabView(ID aId)
: Base(lv_tabview_create(Screen::BackgroundScreen::getLvInstance(),
LV_DIR_TOP, 0),
@ -59,4 +69,11 @@ void TabView::HandleTabChangeImpl(lv_event_t *aTabChangeEvent) {
if (self) {
self->HandleTabChange();
}
}
}
bool TabView::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) {
if (OnKeyEvent(aKeyEvent)) {
return true;
}
return mTabs[GetCurrentTabIdx()]->KeyEvent(aKeyEvent);
};

View file

@ -2,8 +2,11 @@
#include <functional>
namespace UI::Page {
class TabView;
class Tab : public Base {
friend TabView;
public:
typedef std::unique_ptr<Tab> Ptr;
@ -12,6 +15,9 @@ public:
void GiveContent(Page::Base::Ptr aContent);
[[nodiscard]] Base::Ptr TakeContent();
bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
private:
Base::Ptr mContent;
};
@ -25,6 +31,8 @@ public:
void SetCurrentTabIdx(uint16_t aTabToSetActive,
lv_anim_enable_t aIsDoAnimation = LV_ANIM_ON);
bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
protected:
void OnShow() {}
void OnHide() {}

View file

@ -18,4 +18,15 @@ HomeScreen::HomeScreen()
void HomeScreen::SetBgColor(lv_color_t value, lv_style_selector_t selector) {
mTabView.SetBgColor(value, selector);
UI::UIElement::SetBgColor(value, selector);
}
}
bool HomeScreen::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) {
return false;
};
bool HomeScreen::KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) {
if (OnKeyEvent(aKeyEvent)) {
return true;
}
return mTabView.KeyEvent(aKeyEvent);
};

View file

@ -12,6 +12,11 @@ public:
void SetBgColor(lv_color_t value,
lv_style_selector_t selector = LV_PART_MAIN) override;
bool KeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
protected:
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
private:
Page::TabView mTabView;
};

View file

@ -4,7 +4,6 @@ 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);
UIElement::Show();
@ -12,4 +11,6 @@ void Base::Show() {
void Base::SetPushAnimation(lv_scr_load_anim_t aShowAnimation) {
mPushAnimation = aShowAnimation;
}
}
bool Base::OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) { return false; };

View file

@ -23,9 +23,7 @@ protected:
void Show() override;
void OnShow() override{};
void OnHide() override{};
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override {
return false;
};
bool OnKeyEvent(KeyPressAbstract::KeyEvent aKeyEvent) override;
private:
lv_scr_load_anim_t mPushAnimation = LV_SCR_LOAD_ANIM_NONE;

View file

@ -2,13 +2,22 @@
#include "UIElement.hpp"
#include <memory>
namespace UI::Page {
class Base;
}
namespace UI::Widget {
class Base : public UIElement {
friend class UI::Page::Base;
public:
typedef std::unique_ptr<Base> Ptr;
Base(lv_obj_t *aLvglSelf);
virtual ~Base() override = default;
protected:
void OnShow() override{};