Add an Helper in UIElement that converts lvgl object into UIElements or children via a static cast.

Make Tabview a friend of Base Page to allow it to notify pages that they are hidden or showing.

Implement the notification in Tabview to allow pages to know they are showing.
This commit is contained in:
Matthew Colvin 2023-09-22 23:36:25 -05:00
parent 1cc65594a9
commit 7c089e395a
4 changed files with 64 additions and 2 deletions

View file

@ -26,6 +26,8 @@ public:
ID GetID() { return mId; };
template <class UIElemTy> static UIElemTy GetElement(lv_obj_t *aLvglObject);
protected:
/// @brief get Lvgl object refernce to use in LVGL APIs
/// @return lvgl object a
@ -44,4 +46,26 @@ private:
lv_obj_t *mLvglSelf;
const ID mId;
};
/**
* @brief This helper allows conversion between anLvglObject and a
* core element by using the user data that links the LVGL object
* to its C++ counterpart. Do note that it is possible that this
* user data is not always there if the Lvgl Object has not been wrapped
* by UIElement
*
* @tparam UIElemTy - Type of element you want to cast to
* @param aLvglObject - object to extract User data from
* @return UIElemTy - object stored in user data (See constructor of
* UIElement)
*/
template <class UIElemTy>
UIElemTy UIElement::GetElement(lv_obj_t *aLvglObject) {
auto UIElement = lv_obj_get_user_data(aLvglObject);
if (UIElement) {
return static_cast<UIElemTy>(UIElement);
}
return nullptr;
}
} // namespace UI

View file

@ -3,9 +3,11 @@
#include "WidgetBase.hpp"
#include <vector>
namespace UI::Page {
class TabView;
class Base : public UIElement {
friend TabView; // Allow Tab view to call OnShow and OnHide Since it can show
// and Hide pages by swiping
public:
typedef std::unique_ptr<Base> Ptr;

View file

@ -7,7 +7,10 @@ using namespace UI::Page;
TabView::TabView(ID aId)
: Base(lv_tabview_create(Screen::BackgroundScreen::getLvInstance(),
LV_DIR_TOP, 0),
aId) {}
aId) {
lv_obj_add_event_cb(LvglSelf(), HandleTabChangeImpl, LV_EVENT_VALUE_CHANGED,
nullptr);
}
void TabView::AddTab(Page::Base::Ptr aPage, std::string aTitle) {
auto tab = std::make_unique<Base>(
@ -16,4 +19,30 @@ void TabView::AddTab(Page::Base::Ptr aPage, std::string aTitle) {
tab->AddElement(aPage.get());
mTabs.push_back(std::move(tab));
}
uint16_t TabView::GetCurrentTabIdx() {
return lv_tabview_get_tab_act(LvglSelf());
}
void TabView::SetCurrentTabIdx(uint16_t aTabToSetActive,
lv_anim_enable_t aIsDoAnimation) {
lv_tabview_set_act(LvglSelf(), aTabToSetActive, aIsDoAnimation);
}
void TabView::HandleTabChange() {
// Call OnShow() for the page we just swapped to in order to
// Notify the page that it is now showing and the other that the are now
// hidden
for (int i = 0; i < mTabs.size(); i++) {
GetCurrentTabIdx() == i ? mTabs[i]->OnShow() : mTabs[i]->OnHide();
}
}
void TabView::HandleTabChangeImpl(lv_event_t *aTabChangeEvent) {
auto self =
UIElement::GetElement<TabView *>(lv_event_get_target(aTabChangeEvent));
if (self) {
self->HandleTabChange();
}
}

View file

@ -7,11 +7,18 @@ public:
TabView(ID aId);
void AddTab(Page::Base::Ptr aPage, std::string aTitle);
uint16_t GetCurrentTabIdx();
void SetCurrentTabIdx(uint16_t aTabToSetActive,
lv_anim_enable_t aIsDoAnimation = LV_ANIM_ON);
protected:
void OnShow() {}
void OnHide() {}
private:
void HandleTabChange();
static void HandleTabChangeImpl(lv_event_t *aTabChangeEvent);
std::vector<Page::Base::Ptr> mTabs;
};