menu tabs header now uses lvgl buttons and supports scrolling. buttons are slightly wider now

This commit is contained in:
gagarinlg
2022-06-11 15:38:08 +02:00
committed by Raphael Coeffic
parent f79c313d85
commit c29ec6edfe
5 changed files with 102 additions and 84 deletions
+62 -42
View File
@@ -33,6 +33,29 @@
#include <algorithm>
TabCarouselButton::TabCarouselButton(Window* parent, const rect_t& rect, std::vector<PageTab *>& tabs, uint8_t index,
std::function<uint8_t(void)> pressHandler,
WindowFlags flags) :
Button(parent, rect, std::move(pressHandler), flags), tabs(tabs), index(index)
{
}
void TabCarouselButton::paint(BitmapBuffer * dc)
{
if(checked()) {
OpenTxTheme::instance()->drawCurrentMenuBackground(dc);
}
dc->drawBitmap(2, 7, theme->getIcon(tabs[index]->getIcon(), checked() ? STATE_PRESSED : STATE_DEFAULT));
}
void TabCarouselButton::check(bool checked)
{
Button::check(checked);
if(checked) {
lv_obj_move_foreground(lvobj);
}
}
TabsGroupHeader::TabsGroupHeader(TabsGroup* parent, uint8_t icon) :
FormGroup(parent, {0, 0, LCD_W, MENU_BODY_TOP}, NO_FOCUS | OPAQUE),
@@ -59,57 +82,54 @@ void TabsGroupHeader::paint(BitmapBuffer* dc)
TabsCarousel::TabsCarousel(Window* parent, TabsGroup* menu) :
Window(parent,
{MENU_HEADER_BUTTONS_LEFT, 0, LCD_W - MENU_HEADER_BUTTONS_LEFT,
{MENU_HEADER_BUTTONS_LEFT, 0, DATETIME_SEPARATOR_X - MENU_HEADER_BUTTONS_LEFT,
MENU_HEADER_HEIGHT + 10},
NO_FOCUS | TRANSPARENT),
NO_FOCUS | TRANSPARENT ),
menu(menu)
{
}
void TabsCarousel::updateInnerWidth()
void TabsCarousel::update()
{
while(buttons.size() < menu->tabs.size())
{
int index = buttons.size();
rect_t btnCoords = {(int)(index * (MENU_HEADER_BUTTON_WIDTH + 2)), 0, (int)(MENU_HEADER_BUTTON_WIDTH + 3), int(MENU_TITLE_TOP + 5)};
buttons.emplace_back(new TabCarouselButton(this, btnCoords, menu->tabs, index,
[&, index](){
menu->setCurrentTab(index);
setCurrentIndex(index);
for(auto &b: buttons)
b->check(false);
buttons[index]->check(true);
return true;
}
, TRANSPARENT | NO_FOCUS));
if(index == 0)
buttons[index]->check(true);
}
while(buttons.size() > menu->tabs.size())
{
delete *buttons.end();
buttons.pop_back();
}
}
void TabsCarousel::setCurrentIndex(uint8_t index)
{
if(buttons.size() <= index)
return;
buttons[currentIndex]->check(false);
currentIndex = index;
buttons[currentIndex]->check(true);
}
void TabsCarousel::paint(BitmapBuffer * dc)
{
OpenTxTheme::instance()->drawPageHeader(dc, menu->tabs, currentIndex);
}
#if defined(HARDWARE_TOUCH)
bool TabsCarousel::onTouchStart(coord_t x, coord_t y)
{
if(sliding)
sliding = false;
return Window::onTouchStart(x,y);
}
bool TabsCarousel::onTouchEnd(coord_t x, coord_t y)
{
if(sliding)
return true;
unsigned index = (x - padding_left) / MENU_HEADER_BUTTON_WIDTH;
if (index >= menu->tabs.size()) {
return false;
}
menu->setCurrentTab(index);
setCurrentIndex(index);
return true;
}
bool TabsCarousel::onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY)
{
sliding = true;
Window::onTouchSlide(x,y,startX,startY,slideX,slideY);
return true;
}
#endif
TabsGroup::TabsGroup(uint8_t icon):
Window(MainWindow::instance(), { 0, 0, LCD_W, LCD_H }, OPAQUE),
header(this, icon),
@@ -147,7 +167,7 @@ void TabsGroup::addTab(PageTab * page)
if (!currentTab) {
setCurrentTab(0);
}
header.carousel.updateInnerWidth();
header.carousel.update();
invalidate();
}
@@ -169,7 +189,7 @@ void TabsGroup::removeTab(unsigned index)
setCurrentTab(max<unsigned>(0, index - 1));
}
tabs.erase(tabs.begin() + index);
header.carousel.updateInnerWidth();
header.carousel.update();
invalidate();
}
@@ -180,7 +200,7 @@ void TabsGroup::removeAllTabs()
}
tabs.clear();
currentTab = nullptr;
header.carousel.updateInnerWidth();
header.carousel.update();
}
void TabsGroup::setVisibleTab(PageTab* tab)
+26 -11
View File
@@ -76,6 +76,29 @@ class PageTab {
std::function<void()> onSetVisible;
};
class TabCarouselButton: public Button
{
public:
TabCarouselButton(Window* parent, const rect_t& rect, std::vector<PageTab *>& tabs, uint8_t index,
std::function<uint8_t(void)> pressHandler,
WindowFlags flags = 0);
#if defined(DEBUG_WINDOWS)
std::string getName() const override
{
return "TabCarouselButton(" + std::to_string(icon) + ")";
}
#endif
void paint(BitmapBuffer * dc);
void check(bool checked = true);
protected:
std::vector<PageTab *> tabs;
uint8_t index;
};
class TabsCarousel: public Window {
public:
TabsCarousel(Window * parent, TabsGroup * menu);
@@ -87,27 +110,19 @@ class TabsCarousel: public Window {
}
#endif
inline void setCurrentIndex(uint8_t index)
{
currentIndex = index;
}
void setCurrentIndex(uint8_t index);
inline uint8_t getCurrentIndex()
{
return currentIndex;
}
void updateInnerWidth();
void update();
void paint(BitmapBuffer * dc) override;
#if defined(HARDWARE_TOUCH)
bool onTouchStart(coord_t x, coord_t y) override;
bool onTouchEnd(coord_t x, coord_t y) override;
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY) override;
#endif
protected:
std::vector<TabCarouselButton*> buttons;
constexpr static uint8_t padding_left = 3;
TabsGroup * menu;
uint8_t currentIndex = 0;
+1 -2
View File
@@ -102,8 +102,7 @@ class OpenTxTheme: public Theme
virtual void drawPageHeaderBackground(BitmapBuffer *dc, uint8_t icon,
const char *title) const = 0;
virtual void drawPageHeader(BitmapBuffer *dc, std::vector<PageTab *> &tabs,
uint8_t currentIndex) const = 0;
virtual void drawCurrentMenuBackground(BitmapBuffer *dc) const = 0;
// virtual void drawMessageBox(const char * title, const char * text, const
// char * action, uint32_t flags) const override;
+2 -11
View File
@@ -365,19 +365,10 @@ class Theme480: public OpenTxTheme
return state == STATE_DEFAULT ? menuIconNormal[index] : menuIconSelected[index];
}
void drawPageHeader(BitmapBuffer *dc, std::vector<PageTab *> &tabs,
uint8_t currentIndex) const override
void drawCurrentMenuBackground(BitmapBuffer *dc) const override
{
for (unsigned index = 0; index < tabs.size(); index++) {
if (index != currentIndex) {
dc->drawBitmap(index * MENU_HEADER_BUTTON_WIDTH + 2, 7,
menuIconNormal[tabs[index]->getIcon()]);
}
}
dc->drawBitmap(currentIndex * MENU_HEADER_BUTTON_WIDTH, 0,
dc->drawBitmap(0, 0,
currentMenuBackground);
dc->drawBitmap(currentIndex * MENU_HEADER_BUTTON_WIDTH + 2, 7,
menuIconSelected[tabs[currentIndex]->getIcon()]);
}
void drawMenuDatetime(BitmapBuffer * dc) const
+11 -18
View File
@@ -366,25 +366,18 @@ class FlyskyTheme: public OpenTxTheme
return state == STATE_DEFAULT ? menuIconNormal[index] : menuIconSelected[index];
}
void drawPageHeader(BitmapBuffer *dc, std::vector<PageTab *> &tabs,
uint8_t currentIndex) const override
void drawCurrentMenuBackground(BitmapBuffer *dc) const override
{
uint8_t padding_left = 4;
dc->drawSolidFilledRect(0, 0, 4, MENU_HEADER_BUTTON_WIDTH,
COLOR_THEME_FOCUS);
for (unsigned i = 0; i < tabs.size(); i++) {
dc->drawBitmap(
padding_left + i * MENU_HEADER_BUTTON_WIDTH, 0,
theme->getIcon(tabs[i]->getIcon(),
currentIndex == i ? STATE_PRESSED : STATE_DEFAULT));
}
// coord_t x = padding_left + MENU_HEADER_BUTTON_WIDTH * tabs.size();
// coord_t w = width() - x;
// if (w > 0) {
// dc->drawSolidFilledRect(x, 0, w, MENU_HEADER_BUTTON_WIDTH,
// COLOR_THEME_FOCUS);
// }
// uint8_t padding_left = 4;
//
// dc->drawSolidFilledRect(0, 0, 4, MENU_HEADER_BUTTON_WIDTH,
// COLOR_THEME_FOCUS);
// for (unsigned i = 0; i < tabs.size(); i++) {
// dc->drawBitmap(
// padding_left + i * MENU_HEADER_BUTTON_WIDTH, 0,
// theme->getIcon(tabs[i]->getIcon(),
// currentIndex == i ? STATE_PRESSED : STATE_DEFAULT));
// }
}
void drawMenuDatetime(BitmapBuffer * dc) const