diff --git a/radio/src/gui/colorlcd/tabsgroup.cpp b/radio/src/gui/colorlcd/tabsgroup.cpp index 655282313..bbbbe11cf 100644 --- a/radio/src/gui/colorlcd/tabsgroup.cpp +++ b/radio/src/gui/colorlcd/tabsgroup.cpp @@ -33,6 +33,29 @@ #include +TabCarouselButton::TabCarouselButton(Window* parent, const rect_t& rect, std::vector& tabs, uint8_t index, + std::function 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(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) diff --git a/radio/src/gui/colorlcd/tabsgroup.h b/radio/src/gui/colorlcd/tabsgroup.h index c23ec252b..3b01272fb 100644 --- a/radio/src/gui/colorlcd/tabsgroup.h +++ b/radio/src/gui/colorlcd/tabsgroup.h @@ -76,6 +76,29 @@ class PageTab { std::function onSetVisible; }; +class TabCarouselButton: public Button +{ +public: + TabCarouselButton(Window* parent, const rect_t& rect, std::vector& tabs, uint8_t index, + std::function 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 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 buttons; constexpr static uint8_t padding_left = 3; TabsGroup * menu; uint8_t currentIndex = 0; diff --git a/radio/src/gui/colorlcd/theme.h b/radio/src/gui/colorlcd/theme.h index cf154f243..01f318695 100644 --- a/radio/src/gui/colorlcd/theme.h +++ b/radio/src/gui/colorlcd/theme.h @@ -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 &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; diff --git a/radio/src/gui/colorlcd/themes/480_default.cpp b/radio/src/gui/colorlcd/themes/480_default.cpp index fab2e51fa..07f458127 100644 --- a/radio/src/gui/colorlcd/themes/480_default.cpp +++ b/radio/src/gui/colorlcd/themes/480_default.cpp @@ -365,19 +365,10 @@ class Theme480: public OpenTxTheme return state == STATE_DEFAULT ? menuIconNormal[index] : menuIconSelected[index]; } - void drawPageHeader(BitmapBuffer *dc, std::vector &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 diff --git a/radio/src/gui/colorlcd/themes/flysky.cpp b/radio/src/gui/colorlcd/themes/flysky.cpp index ef580e39f..5e2d87345 100644 --- a/radio/src/gui/colorlcd/themes/flysky.cpp +++ b/radio/src/gui/colorlcd/themes/flysky.cpp @@ -366,25 +366,18 @@ class FlyskyTheme: public OpenTxTheme return state == STATE_DEFAULT ? menuIconNormal[index] : menuIconSelected[index]; } - void drawPageHeader(BitmapBuffer *dc, std::vector &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