From de86bdcc97bceb34368c6b41e4f1aa1399065f7c Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 25 Apr 2021 13:48:08 +0200 Subject: [PATCH] Added SelectFabCarousel to implement a button carousel. --- radio/src/gui/colorlcd/CMakeLists.txt | 1 + radio/src/gui/colorlcd/select_fab_button.cpp | 4 +- .../src/gui/colorlcd/select_fab_carousel.cpp | 49 ++++++++++++ radio/src/gui/colorlcd/select_fab_carousel.h | 40 ++++++++++ radio/src/gui/colorlcd/view_main_menu.cpp | 79 +++++++------------ radio/src/gui/colorlcd/view_main_menu.h | 35 +++++++- 6 files changed, 154 insertions(+), 54 deletions(-) create mode 100644 radio/src/gui/colorlcd/select_fab_carousel.cpp create mode 100644 radio/src/gui/colorlcd/select_fab_carousel.h diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index 5fcd7f548..d1271bda3 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -22,6 +22,7 @@ set(GUI_SRC page.cpp fab_button.cpp select_fab_button.cpp + select_fab_carousel.cpp topbar.cpp layout.cpp widget.cpp diff --git a/radio/src/gui/colorlcd/select_fab_button.cpp b/radio/src/gui/colorlcd/select_fab_button.cpp index 6c90e6b71..9e092a27d 100644 --- a/radio/src/gui/colorlcd/select_fab_button.cpp +++ b/radio/src/gui/colorlcd/select_fab_button.cpp @@ -30,10 +30,10 @@ SelectFabButton::SelectFabButton(FormGroup* parent, coord_t x, coord_t y, title(title) { // Add some space on either side on the button - setWidth(width() + SELECT_BUTTON_BORDER); + setWidth(FAB_BUTTON_SIZE + SELECT_BUTTON_BORDER); // 2 Lines extra for the text + half border - setHeight(height() + 2 * PAGE_LINE_HEIGHT + SELECT_BUTTON_BORDER / 2); + setHeight(FAB_BUTTON_SIZE + 2 * PAGE_LINE_HEIGHT + SELECT_BUTTON_BORDER / 2); // if (height() < (width() / 2) * 3) { // setHeight((width() / 2) * 3); diff --git a/radio/src/gui/colorlcd/select_fab_carousel.cpp b/radio/src/gui/colorlcd/select_fab_carousel.cpp new file mode 100644 index 000000000..215efe8d7 --- /dev/null +++ b/radio/src/gui/colorlcd/select_fab_carousel.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "select_fab_carousel.h" + +SelectFabCarousel::SelectFabCarousel(Window* parent): + FormGroup(parent, {}, OPAQUE | FORM_FORWARD_FOCUS | NO_SCROLLBAR) +{ + setPageWidth(FAB_BUTTON_SIZE + SELECT_BUTTON_BORDER); + setHeight(FAB_BUTTON_SIZE + 2 * PAGE_LINE_HEIGHT + SELECT_BUTTON_BORDER / 2); +} + +void SelectFabCarousel::setMaxButtons(uint8_t max) +{ + maxButtons = max; + setWidth(maxButtons * pageWidth); +} + +void SelectFabCarousel::addButton(uint8_t icon, const char* title, + std::function pressHandler) +{ + coord_t y_pos = 0;//SELECT_BUTTON_BORDER; + coord_t x_pos = pageWidth * buttons;// + SELECT_BUTTON_BORDER / 2; + buttons++; + + auto button = new SelectFabButton(this, x_pos, y_pos, icon, title, pressHandler); + setInnerWidth(pageWidth * buttons); + + // y_pos += button->width() + SELECT_BUTTON_BORDER; + // setHeight(y_pos); + // setInnerHeight(y_pos); +} diff --git a/radio/src/gui/colorlcd/select_fab_carousel.h b/radio/src/gui/colorlcd/select_fab_carousel.h new file mode 100644 index 000000000..7516e1780 --- /dev/null +++ b/radio/src/gui/colorlcd/select_fab_carousel.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "select_fab_button.h" + +class SelectFabCarousel : public FormGroup +{ +public: + explicit SelectFabCarousel(Window* parent); + + // Maximum visible buttons (-> width of the carousel) + void setMaxButtons(uint8_t max); + + // Add a new button to the carousel + void addButton(uint8_t icon, const char* title, + std::function pressHandler); + +protected: + uint8_t maxButtons = 0; + uint8_t buttons = 0; +}; diff --git a/radio/src/gui/colorlcd/view_main_menu.cpp b/radio/src/gui/colorlcd/view_main_menu.cpp index 9de8e1390..efa27c831 100644 --- a/radio/src/gui/colorlcd/view_main_menu.cpp +++ b/radio/src/gui/colorlcd/view_main_menu.cpp @@ -28,17 +28,23 @@ #include "menu_screen.h" #include "view_channels.h" #include "view_statistics.h" -#include "select_fab_button.h" +#include "select_fab_carousel.h" + +// TODO: +// -> make SelectFabCarousel() +// -> contains only the scrolling area +// -> ViewMainMenu takes fullscreen +// -> SelectFabCarousel() has ViewMainMenu() as parent ViewMainMenu::ViewMainMenu(Window* parent) : - FormGroup(parent->getFullScreenWindow(), - {}, - OPAQUE | FORM_FORWARD_FOCUS | NO_SCROLLBAR) + Window(parent->getFullScreenWindow(), {}) { Layer::push(this); + setWidth(parent->width()); + setHeight(parent->height()); - coord_t y_pos = SELECT_BUTTON_BORDER; - coord_t x_pos = SELECT_BUTTON_BORDER / 2; + auto carousel = new SelectFabCarousel(this); + carousel->setMaxButtons(4); // Disabled Title // @@ -47,57 +53,37 @@ ViewMainMenu::ViewMainMenu(Window* parent) : // "Tasks", 0, FOCUS_COLOR | FONT(XL) | CENTERED); // pos += title->height() + PAGE_LINE_SPACING; - auto button = new SelectFabButton(this, x_pos, y_pos, ICON_RADIO_TOOLS, "Model\nSettings", - [=]() -> uint8_t { + carousel->addButton(ICON_RADIO_TOOLS, "Model\nSettings", [=]() -> uint8_t { deleteLater(); new ModelMenu(); return 0; }); - x_pos += button->width() + SELECT_BUTTON_BORDER / 2; - setPageWidth(x_pos); - setWidth(pageWidth * 4); - - x_pos += SELECT_BUTTON_BORDER / 2; - - button = new SelectFabButton(this, x_pos, y_pos, ICON_MODEL, "Select\nModel", - [=]() -> uint8_t { + carousel->addButton(ICON_MODEL, "Select\nModel", [=]() -> uint8_t { deleteLater(); new ModelSelectMenu(); return 0; }); - x_pos += pageWidth; - - button = new SelectFabButton(this, x_pos, y_pos, ICON_RADIO, "Radio\nSettings", - [=]() -> uint8_t { + carousel->addButton(ICON_RADIO, "Radio\nSettings", [=]() -> uint8_t { deleteLater(); new RadioMenu(); return 0; }); - x_pos += pageWidth; - - button = new SelectFabButton(this, x_pos, y_pos, ICON_THEME, "Screens\nSetup", - [=]() -> uint8_t { + carousel->addButton(ICON_THEME, "Screens\nSetup", [=]() -> uint8_t { deleteLater(); new ScreenMenu(); return 0; }); - x_pos += pageWidth; - - button = new SelectFabButton(this, x_pos, y_pos, ICON_MONITOR, "Channel\nMonitor", - [=]() -> uint8_t { + carousel->addButton(ICON_MONITOR, "Channel\nMonitor", [=]() -> uint8_t { deleteLater(); new ChannelsViewMenu(); return 0; }); - x_pos += pageWidth; - - button = new SelectFabButton(this, x_pos, y_pos, ICON_MODEL_TELEMETRY, "Reset\nTelemetry", - [=]() -> uint8_t { + carousel->addButton(ICON_MODEL_TELEMETRY, "Reset\nTelemetry", [=]() -> uint8_t { deleteLater(); Menu* resetMenu = new Menu(parent); resetMenu->addLine(STR_RESET_FLIGHT, []() { flightReset(); }); @@ -108,42 +94,33 @@ ViewMainMenu::ViewMainMenu(Window* parent) : return 0; }); - x_pos += pageWidth; - - button = new SelectFabButton(this, x_pos, y_pos, ICON_STATS, "Statistics", - [=]() -> uint8_t { + carousel->addButton(ICON_STATS, "Statistics", [=]() -> uint8_t { deleteLater(); new StatisticsViewPageGroup(); return 0; }); - x_pos += pageWidth; - - button = new SelectFabButton(this, x_pos, y_pos, ICON_OPENTX, "About\nOpenTx", - [=]() -> uint8_t { + carousel->addButton(ICON_OPENTX, "About\nOpenTx", [=]() -> uint8_t { deleteLater(); //TODO: new AboutUs(); return 0; }); - x_pos += pageWidth; - setInnerWidth(x_pos + SELECT_BUTTON_BORDER / 2); + carousel->setWindowCentered(); + carouselRect = carousel->getRect(); - y_pos += button->height() + SELECT_BUTTON_BORDER; - setHeight(y_pos); - setInnerHeight(y_pos); - - setWindowCentered(); - - setFocus(); + carousel->setCloseHandler([=]() { deleteLater(); }); + carousel->setFocus(); } void ViewMainMenu::paint(BitmapBuffer* dc) { - dc->drawFilledRect(0, 0, getInnerWidth(), height(), SOLID, OVERLAY_COLOR, OPACITY(5)); + dc->drawFilledRect(carouselRect.x, carouselRect.y, carouselRect.w, + carouselRect.h, SOLID, OVERLAY_COLOR, OPACITY(5)); } + void ViewMainMenu::deleteLater(bool detach, bool trash) { Layer::pop(this); - FormGroup::deleteLater(detach, trash); + Window::deleteLater(detach, trash); } diff --git a/radio/src/gui/colorlcd/view_main_menu.h b/radio/src/gui/colorlcd/view_main_menu.h index ab75fc497..b9045dc9c 100644 --- a/radio/src/gui/colorlcd/view_main_menu.h +++ b/radio/src/gui/colorlcd/view_main_menu.h @@ -22,10 +22,43 @@ #include "form.h" -class ViewMainMenu: FormGroup +class ViewMainMenu: public Window { public: ViewMainMenu(Window * parent); void paint(BitmapBuffer * dc) override; void deleteLater(bool detach=true, bool trash=true) override; + +#if defined(HARDWARE_TOUCH) + bool onTouchStart(coord_t /*x*/, coord_t /*y*/) override { return true; } + bool onTouchEnd(coord_t x, coord_t y) override + { + if (!Window::onTouchEnd(x, y)) { + onKeyPress(); + deleteLater(); + } + return true; + } + bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, + coord_t slideX, coord_t slideY) override + { + Window::onTouchSlide(x, y, startX, startY, slideX, slideY); + return true; + } +#endif +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override + { + switch (event) { + case EVT_KEY_BREAK(KEY_EXIT): + killEvents(event); + parent->deleteLater(); + return; + } + Window::onEvent(event); + } +#endif + + protected: + rect_t carouselRect; };