From f305fd397d8a11536f86e7bb1f9f53ed46d0fc9c Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 24 Apr 2021 21:47:54 +0200 Subject: [PATCH] Selectable widgets (+edit, fullscreen mode, etc) --- radio/src/gui/colorlcd/CMakeLists.txt | 1 + radio/src/gui/colorlcd/layout.cpp | 1 + radio/src/gui/colorlcd/lcd.h | 1 + radio/src/gui/colorlcd/view_main.cpp | 95 +++------ radio/src/gui/colorlcd/view_main.h | 7 +- radio/src/gui/colorlcd/view_main_menu.cpp | 192 ++++++++++++++++++ radio/src/gui/colorlcd/view_main_menu.h | 31 +++ radio/src/gui/colorlcd/widget.cpp | 127 ++++++++++++ radio/src/gui/colorlcd/widget.h | 43 ++-- radio/src/gui/colorlcd/widgets/gauge.cpp | 11 +- radio/src/gui/colorlcd/widgets/modelbmp.cpp | 2 +- radio/src/gui/colorlcd/widgets/outputs.cpp | 2 +- radio/src/gui/colorlcd/widgets/text.cpp | 2 +- radio/src/gui/colorlcd/widgets/timer.cpp | 2 +- radio/src/gui/colorlcd/widgets/value.cpp | 5 +- .../colorlcd/widgets/widgets_container_impl.h | 2 +- radio/src/gui/colorlcd/widgets_container.h | 1 + radio/src/lua/widgets.cpp | 12 +- 18 files changed, 421 insertions(+), 116 deletions(-) create mode 100644 radio/src/gui/colorlcd/view_main_menu.cpp create mode 100644 radio/src/gui/colorlcd/view_main_menu.h diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index 19957a284..b2944c4e2 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -54,6 +54,7 @@ set(GUI_SRC radio_diaganas.cpp radio_calibration.cpp view_main.cpp + view_main_menu.cpp view_main_decoration.cpp view_channels.cpp view_logical_switches.cpp diff --git a/radio/src/gui/colorlcd/layout.cpp b/radio/src/gui/colorlcd/layout.cpp index 6e64c7222..10cdf1a96 100644 --- a/radio/src/gui/colorlcd/layout.cpp +++ b/radio/src/gui/colorlcd/layout.cpp @@ -129,6 +129,7 @@ void loadCustomScreens() viewMain->setCurrentMainView(0); viewMain->updateTopbarVisibility(); + viewMain->setFocus(); } // diff --git a/radio/src/gui/colorlcd/lcd.h b/radio/src/gui/colorlcd/lcd.h index 8595cdbba..18f6e23a3 100644 --- a/radio/src/gui/colorlcd/lcd.h +++ b/radio/src/gui/colorlcd/lcd.h @@ -51,6 +51,7 @@ void lcdDrawBlackOverlay(); #if defined(BOOT) #define BLINK_ON_PHASE (0) #else + #define FAST_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<5)) #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6)) #define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7)) #endif diff --git a/radio/src/gui/colorlcd/view_main.cpp b/radio/src/gui/colorlcd/view_main.cpp index bbd6d2420..90c1a9bf1 100644 --- a/radio/src/gui/colorlcd/view_main.cpp +++ b/radio/src/gui/colorlcd/view_main.cpp @@ -22,11 +22,12 @@ #include "menu_model.h" #include "menu_radio.h" #include "menu_screen.h" -#include "model_select.h" -#include "view_channels.h" -#include "view_statistics.h" +//#include "model_select.h" +//#include "view_channels.h" +//#include "view_statistics.h" #include "topbar_impl.h" -#include "menu.h" +//#include "menu.h" +#include "view_main_menu.h" #include "opentx.h" @@ -36,34 +37,13 @@ ViewMain::ViewMain(): Window(MainWindow::instance(), MainWindow::instance()->getRect()), topbar(dynamic_cast(TopbarFactory::create(this))) { -#if defined(HARDWARE_TOUCH) && !defined(HARDWARE_KEYS) - new FabButton(this, 50, 100, ICON_MODEL, - [=]() -> uint8_t { - new ModelMenu(); - return 0; - }); - - new FabButton(this, LCD_W / 2, 100, ICON_RADIO, - [=]() -> uint8_t { - new RadioMenu(); - return 0; - }); - - new FabButton(this, LCD_W - 50, 100, ICON_THEME, - [=]() -> uint8_t { - new ScreenMenu(); - return 0; - }); - - new IconButton(this, {0, 0, MENU_HEADER_BUTTON_WIDTH, MENU_HEADER_BUTTON_WIDTH}, ICON_BACK, - [=]() -> uint8_t { - openMenu(); - return 0; - }, NO_FOCUS); -#endif - setPageWidth(getParent()->width()); focusWindow = this; + + setFocusHandler([&](bool focus) { + TRACE("[ViewMain] Focus %s", + focus ? "gained" : "lost"); + }); } ViewMain::~ViewMain() @@ -198,6 +178,7 @@ void ViewMain::setScrollPositionX(coord_t value) // update page index g_model.view = getPageIndex(); + setFocus(); // update Topbar updateTopbarVisibility(); @@ -264,12 +245,12 @@ bool ViewMain::onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY void ViewMain::onEvent(event_t event) { switch (event) { - case EVT_KEY_LONG(KEY_MODEL): + case EVT_KEY_BREAK(KEY_MODEL): killEvents(event); new ModelMenu(); break; - case EVT_KEY_LONG(KEY_RADIO): + case EVT_KEY_BREAK(KEY_RADIO): killEvents(event); new RadioMenu(); break; @@ -279,7 +260,7 @@ void ViewMain::onEvent(event_t event) new ScreenMenu(); break; - case EVT_KEY_LONG(KEY_ENTER): + case EVT_KEY_BREAK(KEY_ENTER): killEvents(event); openMenu(); break; @@ -299,48 +280,24 @@ void ViewMain::onEvent(event_t event) killEvents(event); previousMainView(); break; + + case EVT_ROTARY_LEFT: + // decrement + case EVT_ROTARY_RIGHT: + // increment + if (customScreens[g_model.view]) { + customScreens[g_model.view]->setFocus(); + } + break; + + break; } } #endif void ViewMain::openMenu() { - Menu * menu = new Menu(this); - menu->addLine(STR_MODEL_SELECT, []() { - new ModelSelectMenu(); - }); - if (modelHasNotes()) { - menu->addLine(STR_VIEW_NOTES, [=]() { - // TODO - }); - } - menu->addLine(STR_MONITOR_SCREENS, []() { - new ChannelsViewMenu(); - }); - menu->addLine(STR_RESET_SUBMENU, [this]() { - Menu * resetMenu = new Menu(this); - resetMenu->addLine(STR_RESET_FLIGHT, []() { - flightReset(); - }); - resetMenu->addLine(STR_RESET_TIMER1, []() { - timerReset(0); - }); - resetMenu->addLine(STR_RESET_TIMER2, []() { - timerReset(1); - }); - resetMenu->addLine(STR_RESET_TIMER3, []() { - timerReset(2); - }); - resetMenu->addLine(STR_RESET_TELEMETRY, []() { - telemetryReset(); - }); - }); - menu->addLine(STR_STATISTICS, []() { - new StatisticsViewPageGroup(); - }); - menu->addLine(STR_ABOUT_US, []() { - // TODO - }); + new ViewMainMenu(this); } void ViewMain::paint(BitmapBuffer * dc) diff --git a/radio/src/gui/colorlcd/view_main.h b/radio/src/gui/colorlcd/view_main.h index 3b57f611d..5869caa0b 100644 --- a/radio/src/gui/colorlcd/view_main.h +++ b/radio/src/gui/colorlcd/view_main.h @@ -71,6 +71,10 @@ class ViewMain: public Window Topbar* getTopbar(); +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override; +#endif + protected: static ViewMain * _instance; @@ -94,9 +98,6 @@ class ViewMain: public Window bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY) override; #endif -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; -#endif void paint(BitmapBuffer * dc) override; void openMenu(); diff --git a/radio/src/gui/colorlcd/view_main_menu.cpp b/radio/src/gui/colorlcd/view_main_menu.cpp new file mode 100644 index 000000000..032700777 --- /dev/null +++ b/radio/src/gui/colorlcd/view_main_menu.cpp @@ -0,0 +1,192 @@ +/* + * 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 "view_main_menu.h" +#include "menu.h" +#include "audio.h" +#include "translations.h" +#include "model_select.h" +#include "menu_model.h" +#include "menu_radio.h" +#include "menu_screen.h" +//#include "radio_setup.h" +#include "view_channels.h" +#include "view_statistics.h" +#include "fab_button.h" + +constexpr coord_t FAB_BUTTON_WIDTH = 68; +constexpr coord_t FAB_BUTTON_BORDER = 12; +constexpr coord_t MENU_BORDER = 16; + +class SelectFabButton : public FabButton +{ + public: + SelectFabButton(FormGroup* parent, coord_t x, coord_t y, uint8_t icon, + const char* title, std::function pressHandler, + WindowFlags windowFlags = 0) : + FabButton(parent, x + FAB_BUTTON_WIDTH / 2, y + FAB_BUTTON_WIDTH / 2, + icon, pressHandler, windowFlags), + title(title) + { + setHeight(height() + 2 * PAGE_LINE_HEIGHT); + } + + void paint(BitmapBuffer* dc) override + { + FabButton::paint(dc); + auto pos = title.find('\n'); + dc->drawSizedText(width() / 2, FAB_BUTTON_WIDTH, title.c_str(), pos, + FOCUS_COLOR | CENTERED); + dc->drawSizedText(width() / 2, FAB_BUTTON_WIDTH, title.substr(pos).c_str(), 255, + FOCUS_COLOR | CENTERED); + if (hasFocus()) { + dc->drawSolidRect(0, 0, width(), height(), 2, CHECKBOX_COLOR); + } + } + + void onEvent(event_t event) override; + + protected: + std::string title; +}; + +void SelectFabButton::onEvent(event_t event) +{ +#if defined(HARDWARE_KEYS) + switch (event) { + case EVT_KEY_BREAK(KEY_EXIT): + killEvents(event); + parent->deleteLater(); + return; + } +#endif + FabButton::onEvent(event); +} + +ViewMainMenu::ViewMainMenu(Window* parent) : + FormGroup(parent->getFullScreenWindow(), + { 0, 0, 350, 180 }, OPAQUE | FORM_FORWARD_FOCUS) +{ + Layer::push(this); + + coord_t y_pos = MENU_BORDER; + coord_t x_pos = MENU_BORDER; + + // Disabled Title + // + // auto title = new StaticText(this, + // {0, pos, width(), getFontHeight(FONT(XL))}, + // "Tasks", 0, FOCUS_COLOR | FONT(XL) | CENTERED); + // pos += title->height() + PAGE_LINE_SPACING; + + new SelectFabButton(this, x_pos, y_pos, ICON_RADIO_TOOLS, "Model\nSettings", + [=]() -> uint8_t { + deleteLater(); + new ModelMenu(); + return 0; + }); + + x_pos += FAB_BUTTON_WIDTH + FAB_BUTTON_BORDER; + + new SelectFabButton(this, x_pos, y_pos, ICON_MODEL, "Select\nModel", + [=]() -> uint8_t { + deleteLater(); + new ModelSelectMenu(); + return 0; + }); + + x_pos += FAB_BUTTON_WIDTH + FAB_BUTTON_BORDER; + + new SelectFabButton(this, x_pos, y_pos, ICON_RADIO, "Radio\nSettings", + [=]() -> uint8_t { + deleteLater(); + new RadioMenu(); + return 0; + }); + + x_pos += FAB_BUTTON_WIDTH + FAB_BUTTON_BORDER; + + auto button = new SelectFabButton(this, x_pos, y_pos, ICON_THEME, "Screens\nSetup", + [=]() -> uint8_t { + deleteLater(); + new ScreenMenu(); + return 0; + }); + + x_pos += FAB_BUTTON_WIDTH + MENU_BORDER; + y_pos += button->height() + MENU_BORDER; + + setWidth(x_pos); + setInnerHeight(x_pos); + + setHeight(y_pos); + setInnerHeight(y_pos); + + setWindowCentered(); + + // new IconButton( + // this, {0, 0, MENU_HEADER_BUTTON_WIDTH, MENU_HEADER_BUTTON_WIDTH}, + // ICON_BACK, + // [=]() -> uint8_t { + // // openMenu(); + // return 0; + // }); + + //TODO: adjust to whatever is in this window + //setRect() + + + // Menu* menu = new Menu(this); + // menu->addLine(STR_MODEL_SELECT, []() { new ModelSelectMenu(); }); + // // if (modelHasNotes()) { + // // menu->addLine(STR_VIEW_NOTES, [=]() { + // // // TODO + // // }); + // // } + // menu->addLine(STR_MONITOR_SCREENS, []() { new ChannelsViewMenu(); }); + // menu->addLine(STR_RESET_SUBMENU, [this]() { + // Menu* resetMenu = new Menu(this); + // resetMenu->addLine(STR_RESET_FLIGHT, []() { flightReset(); }); + // resetMenu->addLine(STR_RESET_TIMER1, []() { timerReset(0); }); + // resetMenu->addLine(STR_RESET_TIMER2, []() { timerReset(1); }); + // resetMenu->addLine(STR_RESET_TIMER3, []() { timerReset(2); }); + // resetMenu->addLine(STR_RESET_TELEMETRY, []() { telemetryReset(); }); + // }); + // menu->addLine(STR_STATISTICS, []() { new StatisticsViewPageGroup(); }); + // menu->addLine(STR_ABOUT_US, []() { + // // TODO + // }); + + // // Place at current position + // menu->setLeft(menu->left() + getScrollPositionX()); + // menu->setTop(menu->top() + getScrollPositionY()); + + setFocus(); +} + +void ViewMainMenu::paint(BitmapBuffer* dc) +{ + dc->drawFilledRect(0, 0, width(), height(), SOLID, OVERLAY_COLOR, OPACITY(5)); +} +void ViewMainMenu::deleteLater(bool detach, bool trash) +{ + Layer::pop(this); + FormGroup::deleteLater(detach, trash); +} diff --git a/radio/src/gui/colorlcd/view_main_menu.h b/radio/src/gui/colorlcd/view_main_menu.h new file mode 100644 index 000000000..ab75fc497 --- /dev/null +++ b/radio/src/gui/colorlcd/view_main_menu.h @@ -0,0 +1,31 @@ +/* + * 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 "form.h" + +class ViewMainMenu: FormGroup +{ +public: + ViewMainMenu(Window * parent); + void paint(BitmapBuffer * dc) override; + void deleteLater(bool detach=true, bool trash=true) override; +}; diff --git a/radio/src/gui/colorlcd/widget.cpp b/radio/src/gui/colorlcd/widget.cpp index a9c9a1647..608e35f6b 100644 --- a/radio/src/gui/colorlcd/widget.cpp +++ b/radio/src/gui/colorlcd/widget.cpp @@ -20,6 +20,133 @@ #include "opentx.h" #include "widget.h" +#include "menu.h" +#include "widget_settings.h" +#include "view_main.h" +#include "lcd.h" + +constexpr uint32_t WIDGET_FOCUS_TIMEOUT = 10*1000; // 10 seconds + +static void openWidgetMenu(Widget * parent) +{ + Menu *menu = new Menu(parent); + menu->addLine("Full screen", [=]() { + parent->setFullscreen(true); + }); + menu->addLine(TR_WIDGET_SETTINGS, [=]() { + new WidgetSettings(parent, parent); + }); +} + +Widget::Widget(const WidgetFactory *factory, FormGroup *parent, + const rect_t &rect, WidgetPersistentData *persistentData) : + Button(parent, rect), factory(factory), persistentData(persistentData) +{ + setFocusHandler([&](bool focus) { + if (focus) { // gained focus + focusGainedTimestamp = RTOS_GET_MS(); + } + }); +} + +void Widget::checkEvents() +{ + Button::checkEvents(); + + // Give the focus back to ViewMain after WIDGET_FOCUS_TIMEOUT milliseconds + if (hasFocus() && (RTOS_GET_MS() - focusGainedTimestamp >= WIDGET_FOCUS_TIMEOUT)) { + ViewMain::instance()->setFocus(); + } +} + +void Widget::paint(BitmapBuffer * dc) +{ + if (fullscreen) { + // Draw background screen bellow + OpenTxTheme::instance()->drawBackground(dc); + } + + // refresh the widget + refresh(dc); + + if (hasFocus() && !fullscreen) { + + // Blink from haft-time before expiring (5s) + if ((RTOS_GET_MS() - focusGainedTimestamp >= WIDGET_FOCUS_TIMEOUT / 2) + && !FAST_BLINK_ON_PHASE) { + return; + } + dc->drawRect(0, 0, width(), height(), 2, STASHED, CHECKBOX_COLOR); + } +} + +void Widget::onEvent(event_t event) +{ +#if defined(HARDWARE_KEYS) + TRACE("### event = 0x%x ###", event); + if (!fullscreen) { + switch(event) { + // [Enter LONG] -> pop-up widget menu + case EVT_KEY_LONG(KEY_ENTER): + killEvents(event); + openWidgetMenu(this); + return; + // [RTN / EXIT] -> exit focus mode (if not fullscreen) + case EVT_KEY_BREAK(KEY_EXIT): + killEvents(event); + ViewMain::instance()->setFocus(); + return; + // Forward [ENTER] to ViewMain (main menu) + case EVT_KEY_BREAK(KEY_ENTER): + killEvents(event); + ViewMain::instance()->onEvent(event); + return; + } + // Forward the rest to the parent class + Button::onEvent(event); + } + // In fullscreen mode, we react only to that one key: + // [RTN / EXIT LONG] -> exit fullscreen mode + else if (EVT_KEY_LONG(KEY_EXIT) == event) { + killEvents(event); + setFullscreen(false); + } +#endif +} + +void Widget::update() +{ + auto container = dynamic_cast(parent); + if (container) { + container->updateZones(); + } +} + +void Widget::setFullscreen(bool fullscreen) +{ + if (fullscreen == this->fullscreen) return; + + // Leave Fullscreen Mode + if (!fullscreen) { + + // Reset all zones in container + update(); + setWindowFlags(getWindowFlags() & ~OPAQUE); + + // and give up focus + ViewMain::instance()->setFocus(); + this->fullscreen = false; + } + // Enter Fullscreen Mode + else { + + // Set window opaque (inhibits redraw from windows bellow) + setWindowFlags(getWindowFlags() | OPAQUE); + setRect(parent->getRect()); + this->fullscreen = true; + bringToTop(); + } +} std::list & getRegisteredWidgets() { diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index 5bfcb7b2c..4f77ceef9 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -22,7 +22,7 @@ #include #include -#include "form.h" +#include "button.h" #include "widgets_container.h" #include "debug.h" @@ -33,18 +33,14 @@ class WidgetFactory; -class Widget : public Window +class Widget : public Button { public: typedef WidgetPersistentData PersistentData; - Widget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, WidgetPersistentData * persistentData): - Window(parent, rect), - factory(factory), - persistentData(persistentData) - { - } + Widget(const WidgetFactory *factory, FormGroup *parent, const rect_t &rect, + WidgetPersistentData *persistentData); ~Widget() override = default; @@ -78,16 +74,6 @@ class Widget : public Window return persistentData; } - // Called when the widget options have changed - virtual void update() - { - } - - // Called at regular time interval, even if the widget cannot be seen - virtual void background() - { - } - #if defined(DEBUG_WINDOWS) std::string getName() const override { @@ -95,9 +81,30 @@ class Widget : public Window } #endif + // Window interface + void checkEvents() override; + void onEvent(event_t event) override; + void paint(BitmapBuffer * dc) override; + + // Widget interface + + // Set/unset fullscreen mode + void setFullscreen(bool fullscreen); + + // Called when the widget options have changed + virtual void update(); + + // Called when the widget should redraw + virtual void refresh(BitmapBuffer* dc) = 0; + + // Called at regular time interval, even if the widget cannot be seen + virtual void background() {} + protected: const WidgetFactory * factory; PersistentData * persistentData; + uint32_t focusGainedTimestamp = 0; + bool fullscreen = false; }; void registerWidget(const WidgetFactory * factory); diff --git a/radio/src/gui/colorlcd/widgets/gauge.cpp b/radio/src/gui/colorlcd/widgets/gauge.cpp index 3f01aa6f3..826fceaa6 100644 --- a/radio/src/gui/colorlcd/widgets/gauge.cpp +++ b/radio/src/gui/colorlcd/widgets/gauge.cpp @@ -29,7 +29,7 @@ class GaugeWidget: public Widget { } - void paint(BitmapBuffer * dc) override + void refresh(BitmapBuffer * dc) override { mixsrc_t index = persistentData->options[0].value.unsignedValue; int32_t min = persistentData->options[1].value.signedValue; @@ -56,10 +56,6 @@ class GaugeWidget: public Widget dc->drawSolidFilledRect(0, 16, width(), 16, FOCUS_COLOR); dc->drawNumber(0+width()/2, 17, percent, FONT(XS) | CUSTOM_COLOR | CENTERED, 0, nullptr, "%"); dc->invertRect(w, 16, width() - w, 16, CUSTOM_COLOR); - - if (hasFocus()) { - dc->clear(HIGHLIGHT_COLOR); - } } void checkEvents() override @@ -71,11 +67,6 @@ class GaugeWidget: public Widget lastValue = newValue; invalidate(); } - - if (!hasFocus() && g_tmr10ms < 100) { - TRACE("ICI"); - setFocus(SET_FOCUS_FIRST); - } } static const ZoneOption options[]; diff --git a/radio/src/gui/colorlcd/widgets/modelbmp.cpp b/radio/src/gui/colorlcd/widgets/modelbmp.cpp index e4ded8ab0..58543db05 100644 --- a/radio/src/gui/colorlcd/widgets/modelbmp.cpp +++ b/radio/src/gui/colorlcd/widgets/modelbmp.cpp @@ -31,7 +31,7 @@ class ModelBitmapWidget: public Widget { } - void paint(BitmapBuffer * dc) override + void refresh(BitmapBuffer * dc) override { // big space to draw if (rect.h >= 96 && rect.w >= 120) { diff --git a/radio/src/gui/colorlcd/widgets/outputs.cpp b/radio/src/gui/colorlcd/widgets/outputs.cpp index 8f3f11e42..71c634562 100644 --- a/radio/src/gui/colorlcd/widgets/outputs.cpp +++ b/radio/src/gui/colorlcd/widgets/outputs.cpp @@ -37,7 +37,7 @@ class OutputsWidget: public Widget { } - void paint(BitmapBuffer * dc) override + void refresh(BitmapBuffer * dc) override { if (width() > 300 && height() > 20) twoColumns(dc); diff --git a/radio/src/gui/colorlcd/widgets/text.cpp b/radio/src/gui/colorlcd/widgets/text.cpp index 701dfef84..cbc1f3db3 100644 --- a/radio/src/gui/colorlcd/widgets/text.cpp +++ b/radio/src/gui/colorlcd/widgets/text.cpp @@ -31,7 +31,7 @@ class TextWidget: public Widget { } - void paint(BitmapBuffer * dc) override + void refresh(BitmapBuffer * dc) override { // get font color from options[1] lcdSetColor(persistentData->options[1].value.unsignedValue); diff --git a/radio/src/gui/colorlcd/widgets/timer.cpp b/radio/src/gui/colorlcd/widgets/timer.cpp index 45336252d..389303acb 100644 --- a/radio/src/gui/colorlcd/widgets/timer.cpp +++ b/radio/src/gui/colorlcd/widgets/timer.cpp @@ -29,7 +29,7 @@ class TimerWidget: public Widget { } - void paint(BitmapBuffer * dc) override + void refresh(BitmapBuffer * dc) override { uint32_t index = persistentData->options[0].value.unsignedValue; TimerData & timerData = g_model.timers[index]; diff --git a/radio/src/gui/colorlcd/widgets/value.cpp b/radio/src/gui/colorlcd/widgets/value.cpp index 2556a310f..4c7b8e32b 100644 --- a/radio/src/gui/colorlcd/widgets/value.cpp +++ b/radio/src/gui/colorlcd/widgets/value.cpp @@ -31,7 +31,7 @@ class ValueWidget: public Widget { } - void paint(BitmapBuffer * dc) override + void refresh(BitmapBuffer * dc) override { // get source from options[0] mixsrc_t field = persistentData->options[0].value.unsignedValue; @@ -88,7 +88,6 @@ class ValueWidget: public Widget drawSource(dc, NUMBERS_PADDING, 2, field, CUSTOM_COLOR); drawSource(dc, NUMBERS_PADDING + 1, 3, field, BLACK); drawTimer(dc, xValue, yValue, abs(timerState.val), attrValue | FONT(XL) | CUSTOM_COLOR); - return; } if (field >= MIXSRC_FIRST_TELEM) { @@ -105,6 +104,8 @@ class ValueWidget: public Widget drawSource(dc, xLabel, yLabel, field, attrLabel | CUSTOM_COLOR); drawSourceValue(dc, xValue, yValue, field, attrValue | CUSTOM_COLOR); + + Widget::paint(dc); } void checkEvents() override diff --git a/radio/src/gui/colorlcd/widgets/widgets_container_impl.h b/radio/src/gui/colorlcd/widgets/widgets_container_impl.h index 1966a0e0a..0fb615c3a 100644 --- a/radio/src/gui/colorlcd/widgets/widgets_container_impl.h +++ b/radio/src/gui/colorlcd/widgets/widgets_container_impl.h @@ -126,7 +126,7 @@ class WidgetsContainerImpl: public WidgetsContainer } } - void updateZones() + void updateZones() override { for (int i = 0; i < N; i++) { if (widgets[i]) { diff --git a/radio/src/gui/colorlcd/widgets_container.h b/radio/src/gui/colorlcd/widgets_container.h index d02237b87..754bbec11 100644 --- a/radio/src/gui/colorlcd/widgets_container.h +++ b/radio/src/gui/colorlcd/widgets_container.h @@ -75,6 +75,7 @@ class WidgetsContainer: public FormGroup virtual Widget * getWidget(unsigned int index) = 0; virtual void removeWidget(unsigned int index) = 0; virtual void adjustLayout() = 0; + virtual void updateZones() = 0; }; diff --git a/radio/src/lua/widgets.cpp b/radio/src/lua/widgets.cpp index 9f2d130db..1ffe6d182 100644 --- a/radio/src/lua/widgets.cpp +++ b/radio/src/lua/widgets.cpp @@ -186,16 +186,13 @@ class LuaWidget: public Widget } #endif - // Window interface - void paint(BitmapBuffer * dc) override; - // Widget interface const char * getErrorMessage() const override; void update() override; void background() override; // Calls LUA widget 'refresh' method - void refresh(BitmapBuffer* dc); + void refresh(BitmapBuffer* dc) override; protected: int luaWidgetDataRef; @@ -279,13 +276,10 @@ void LuaWidget::checkEvents() } } -void LuaWidget::paint(BitmapBuffer * dc) -{ - refresh(dc); -} - void LuaWidget::update() { + Widget::update(); + if (lsWidgets == 0 || errorMessage) return; luaSetInstructionsLimit(lsWidgets, WIDGET_SCRIPTS_MAX_INSTRUCTIONS);