From f06d47732f5be77592994ee8899f2fa2e85bbb03 Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 13 Oct 2020 16:39:05 +0200 Subject: [PATCH] 2.4 mainview start (#8030) * Start work on mainview --- radio/src/gui/colorlcd/CMakeLists.txt | 6 +- radio/src/gui/colorlcd/draw_functions.cpp | 13 ++ radio/src/gui/colorlcd/draw_functions.h | 2 + radio/src/gui/colorlcd/layout.h | 2 +- radio/src/gui/colorlcd/layouts/layout1x1.cpp | 4 +- radio/src/gui/colorlcd/layouts/layout2+1.cpp | 4 +- radio/src/gui/colorlcd/layouts/layout2x1.cpp | 4 +- radio/src/gui/colorlcd/layouts/layout2x2.cpp | 4 +- radio/src/gui/colorlcd/layouts/layout2x4.cpp | 4 +- radio/src/gui/colorlcd/layouts/layout4+2.cpp | 128 +++++++++++++ .../gui/colorlcd/layouts/mask_layout4+2.png | Bin 0 -> 239 bytes radio/src/gui/colorlcd/layouts/sliders.h | 60 ++++++ radio/src/gui/colorlcd/screen_setup.cpp | 14 ++ radio/src/gui/colorlcd/topbar.cpp | 14 +- radio/src/gui/colorlcd/topbar.h | 9 +- radio/src/gui/colorlcd/view_main.cpp | 27 ++- radio/src/gui/colorlcd/widget.cpp | 4 +- radio/src/gui/colorlcd/widget.h | 23 +-- radio/src/gui/colorlcd/widgets/text.cpp | 47 +++-- radio/src/gui/colorlcd/widgets/value.cpp | 181 ++++++++++-------- radio/src/gui/colorlcd/widgets_container.h | 51 ++--- radio/src/gui/colorlcd/zone.h | 5 - radio/src/storage/storage_common.cpp | 2 +- 23 files changed, 417 insertions(+), 191 deletions(-) create mode 100644 radio/src/gui/colorlcd/layouts/layout4+2.cpp create mode 100644 radio/src/gui/colorlcd/layouts/mask_layout4+2.png create mode 100644 radio/src/gui/colorlcd/layouts/sliders.h diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index bed216b1c..db9ccdaa5 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -22,10 +22,12 @@ set(GUI_SRC fab_button.cpp # topbar.cpp layout.cpp - # widget.cpp + widget.cpp ${THEMES_SRC} ${LAYOUTS_SRC} - # ${WIDGETS_SRC} +# ${WIDGETS_SRC} + widgets/text.cpp + widgets/value.cpp # popups.cpp draw_functions.cpp # menus.cpp diff --git a/radio/src/gui/colorlcd/draw_functions.cpp b/radio/src/gui/colorlcd/draw_functions.cpp index 0069329b1..56952c2e8 100644 --- a/radio/src/gui/colorlcd/draw_functions.cpp +++ b/radio/src/gui/colorlcd/draw_functions.cpp @@ -474,6 +474,19 @@ void drawSensorCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t sens } } +void drawTimer(BitmapBuffer * dc, coord_t x, coord_t y, int32_t tme, LcdFlags flags) +{ + char str[LEN_TIMER_STRING]; + getTimerString(str, tme, (flags & TIMEHOUR) != 0); + dc->drawText(x, y, str, flags); +} + +void drawSourceValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, LcdFlags flags) +{ + getvalue_t value = getValue(source); + drawSourceCustomValue(dc, x, y, source, value, flags); +} + void drawSourceCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, int32_t value, LcdFlags flags) { if (source >= MIXSRC_FIRST_TELEM) { diff --git a/radio/src/gui/colorlcd/draw_functions.h b/radio/src/gui/colorlcd/draw_functions.h index fa9b6fda3..a77ad0bd7 100644 --- a/radio/src/gui/colorlcd/draw_functions.h +++ b/radio/src/gui/colorlcd/draw_functions.h @@ -64,6 +64,8 @@ void drawHorizontalSlider(BitmapBuffer * dc, coord_t x, coord_t y, int len, int void drawSlider(coord_t x, coord_t y, int len, int val, int min, int max, uint8_t steps, uint32_t options); void drawValueOrGVar(BitmapBuffer * dc, coord_t x, coord_t y, gvar_t value, gvar_t vmin, gvar_t vmax, LcdFlags flags = 0); void drawGVarValue(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags = 0); +void drawTimer(BitmapBuffer * dc, coord_t x, coord_t y, int32_t tme, LcdFlags flags = 0); +void drawSourceValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, LcdFlags flags = 0); void drawSourceCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, int32_t value, LcdFlags flags); void drawSensorCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t sensor, int32_t value, LcdFlags flags = 0); void drawGPSPosition(BitmapBuffer * dc, coord_t x, coord_t y, int32_t longitude, int32_t latitude, LcdFlags flags = 0); diff --git a/radio/src/gui/colorlcd/layout.h b/radio/src/gui/colorlcd/layout.h index b39f07c62..bedb8c47b 100644 --- a/radio/src/gui/colorlcd/layout.h +++ b/radio/src/gui/colorlcd/layout.h @@ -35,7 +35,7 @@ class Layout: public WidgetsContainer public: Layout(const LayoutFactory * factory, PersistentData * persistentData): - WidgetsContainer(persistentData), + WidgetsContainer({0, 0, LCD_W, LCD_H}, persistentData), factory(factory) { } diff --git a/radio/src/gui/colorlcd/layouts/layout1x1.cpp b/radio/src/gui/colorlcd/layouts/layout1x1.cpp index 0ea3f10a4..d4b0e12ab 100644 --- a/radio/src/gui/colorlcd/layouts/layout1x1.cpp +++ b/radio/src/gui/colorlcd/layouts/layout1x1.cpp @@ -50,9 +50,9 @@ class Layout1x1: public Layout return 1; } - Zone getZone(unsigned int index) const override + rect_t getZone(unsigned int index) const override { - Zone zone = { 10, 10, LCD_W - 2*10, LCD_H - 2*10 }; + rect_t zone = { 10, 10, LCD_W - 2*10, LCD_H - 2*10 }; if (persistentData->options[0].value.boolValue) { zone.y += MENU_HEADER_HEIGHT; zone.h -= MENU_HEADER_HEIGHT; diff --git a/radio/src/gui/colorlcd/layouts/layout2+1.cpp b/radio/src/gui/colorlcd/layouts/layout2+1.cpp index a205efc66..777184196 100644 --- a/radio/src/gui/colorlcd/layouts/layout2+1.cpp +++ b/radio/src/gui/colorlcd/layouts/layout2+1.cpp @@ -32,7 +32,7 @@ const ZoneOption OPTIONS_LAYOUT_2P1[] = { { nullptr, ZoneOption::Bool } }; -const Zone ZONES_LAYOUT_2P1[3] = { +const rect_t ZONES_LAYOUT_2P1[3] = { { 240, 60, 192, 152 }, { 48, 60, 180, 70 }, { 48, 142, 180, 70 } @@ -60,7 +60,7 @@ class Layout2P1: public Layout return DIM(ZONES_LAYOUT_2P1); } - Zone getZone(unsigned int index) const override + rect_t getZone(unsigned int index) const override { return ZONES_LAYOUT_2P1[index]; } diff --git a/radio/src/gui/colorlcd/layouts/layout2x1.cpp b/radio/src/gui/colorlcd/layouts/layout2x1.cpp index b6345bd47..82ecf279f 100644 --- a/radio/src/gui/colorlcd/layouts/layout2x1.cpp +++ b/radio/src/gui/colorlcd/layouts/layout2x1.cpp @@ -48,9 +48,9 @@ class Layout2x1: public Layout return 2; } - Zone getZone(unsigned int index) const override + rect_t getZone(unsigned int index) const override { - Zone zone; + rect_t zone; zone.w = (LCD_W-3*10) / 2; zone.x = (index & 1) ? 20 + zone.w : 10; if (persistentData->options[0].value.boolValue) { diff --git a/radio/src/gui/colorlcd/layouts/layout2x2.cpp b/radio/src/gui/colorlcd/layouts/layout2x2.cpp index 08ed50159..614e05ecd 100644 --- a/radio/src/gui/colorlcd/layouts/layout2x2.cpp +++ b/radio/src/gui/colorlcd/layouts/layout2x2.cpp @@ -48,9 +48,9 @@ class Layout2x2: public Layout return 4; } - Zone getZone(unsigned int index) const override + rect_t getZone(unsigned int index) const override { - Zone zone; + rect_t zone; zone.w = (LCD_W-3*10) / 2; zone.x = (index & 1) ? 20 + zone.w : 10; if (persistentData->options[0].value.boolValue) { diff --git a/radio/src/gui/colorlcd/layouts/layout2x4.cpp b/radio/src/gui/colorlcd/layouts/layout2x4.cpp index 035e84119..a9bf78e76 100644 --- a/radio/src/gui/colorlcd/layouts/layout2x4.cpp +++ b/radio/src/gui/colorlcd/layouts/layout2x4.cpp @@ -62,9 +62,9 @@ class Layout2x4: public Layout return 8; } - Zone getZone(unsigned int index) const override + rect_t getZone(unsigned int index) const override { - Zone zone; + rect_t zone; zone.x = (index >= 4) ? 260 : 60; zone.y = 56 + (index % 4) * 42; zone.w = 160; diff --git a/radio/src/gui/colorlcd/layouts/layout4+2.cpp b/radio/src/gui/colorlcd/layouts/layout4+2.cpp new file mode 100644 index 000000000..912f13e0f --- /dev/null +++ b/radio/src/gui/colorlcd/layouts/layout4+2.cpp @@ -0,0 +1,128 @@ +/* + * 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 "opentx.h" +#include "sliders.h" + +#define HAS_TOPBAR() (persistentData->options[0].value.boolValue == true) +#define HAS_FM() (persistentData->options[1].value.boolValue == true) +#define HAS_SLIDERS() (persistentData->options[2].value.boolValue == true) +#define HAS_TRIMS() (persistentData->options[3].value.boolValue == true) +#define IS_MIRRORED() (persistentData->options[4].value.boolValue == true) + +const uint8_t LBM_LAYOUT_4P2[] = { +#include "mask_layout4+2.lbm" +}; + +const ZoneOption OPTIONS_LAYOUT_4P2[] = { + { STR_TOP_BAR, ZoneOption::Bool }, + { STR_FLIGHT_MODE, ZoneOption::Bool }, + { STR_SLIDERS, ZoneOption::Bool }, + { STR_TRIMS, ZoneOption::Bool }, + { STR_MIRROR, ZoneOption::Bool }, + { NULL, ZoneOption::Bool } +}; + +constexpr coord_t HTRIM_W = 120; +constexpr coord_t HTRIM_H = 40; +constexpr coord_t HSLIDER_W = 120; +constexpr coord_t HSLIDER_H = 40; + +class Layout4P2: public Layout +{ + public: + Layout4P2(const LayoutFactory * factory, Layout::PersistentData * persistentData): + Layout(factory, persistentData) + { + decorate(); + } + + void create() override + { + Layout::create(); + persistentData->options[0].value.boolValue = true; + persistentData->options[1].value.boolValue = true; + persistentData->options[2].value.boolValue = true; + persistentData->options[3].value.boolValue = true; + persistentData->options[4].value.boolValue = false; + persistentData->options[5].value.boolValue = false; + + decorate(); + } + + unsigned int getZonesCount() const override + { + return 6; + } + + void decorate() + { + if (1 /*HAS_SLIDERS()*/) { + new MainViewHorizontalSlider(this, {0, LCD_H - HTRIM_H - 1, HTRIM_W, HSLIDER_H}, [=] { return calibratedAnalogs[CALIBRATED_POT1]; }, OPTION_SLIDER_TICKS | OPTION_SLIDER_BIG_TICKS | OPTION_SLIDER_SQUARE_BUTTON); + new MainViewHorizontalSlider(this, {LCD_W - HTRIM_W, LCD_H - HTRIM_H, HTRIM_W, HSLIDER_H}, [=] { return calibratedAnalogs[CALIBRATED_POT3]; }, OPTION_SLIDER_TICKS | OPTION_SLIDER_BIG_TICKS | OPTION_SLIDER_SQUARE_BUTTON); + } + } + + rect_t getZone(unsigned int index) const override + { + coord_t areaw = LCD_W - (HAS_SLIDERS() ? 55 : 8) - (HAS_TRIMS() ? 55 : 8); + coord_t areah = LCD_H - 4 - (HAS_TOPBAR() ? 55 : 8) - (HAS_SLIDERS() ? HSLIDER_H + 4 : 4) - (HAS_TRIMS() ? HTRIM_H + 4 : 4); + + rect_t zone; + zone.x = IS_MIRRORED() ? ((index >= 4) ? (LCD_W - areaw) / 2 - 4 : 245) : ((index >= 4) ? 245 : (LCD_W - areaw) / 2 - 4); + zone.h = (index >= 4) ? (areah / 2) : (areah / 4) - 2; + zone.y = (index >= 4) ? (HAS_TOPBAR() ? 52 : 6) + (index == 5 ? zone.h + ((HAS_TRIMS() + HAS_SLIDERS() == 1) ? 8 : 10): 0): (HAS_TOPBAR() ? 52 : 6) + (index % 4) * (zone.h + 6); + zone.w = areaw / 2; + + return zone; + } + + //virtual void refresh(); +}; + +//void Layout4P2::refresh() +//{ + //theme->drawBackground(); + + //if (HAS_TOPBAR()) { + // drawTopBar(); + //} + // + //if (HAS_FM()) { + // // Flight mode + // lcdDrawSizedText(LCD_W / 2 - getTextWidth(g_model.flightModeData[mixerCurrentFlightMode].name, sizeof(g_model.flightModeData[mixerCurrentFlightMode].name), + // ZCHAR | SMLSIZE) / 2, 232, g_model.flightModeData[mixerCurrentFlightMode].name, + // sizeof(g_model.flightModeData[mixerCurrentFlightMode].name), ZCHAR | SMLSIZE); + //} + // + //if (HAS_SLIDERS()) { + // // Pots and rear sliders positions + // drawMainPots(); + //} + // + //if (HAS_TRIMS()) { + // // Trims + // drawTrims(mixerCurrentFlightMode, HAS_SLIDERS()); + //} + + //Layout::refresh(); +//} + +BaseLayoutFactory layout4P2("Layout4P2", "4 + 2", LBM_LAYOUT_4P2, OPTIONS_LAYOUT_4P2); \ No newline at end of file diff --git a/radio/src/gui/colorlcd/layouts/mask_layout4+2.png b/radio/src/gui/colorlcd/layouts/mask_layout4+2.png new file mode 100644 index 0000000000000000000000000000000000000000..c441da1a3888cae2580ba973453fba7dbaa51587 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^#y~93!3HF~&VNk@Qfx`y?k)`fL2$v|<&%LToCO|{ z#Xud`L734=V|E2lkiEpy*OmPV7YmOTbMUf+SFGL;4Nl5;madYy getValue, uint32_t options): + Window(parent, rect), + options(options), + getValue(std::move(getValue)) + { + } + + void checkEvents() override + { + Window::checkEvents(); + int8_t newValue = getValue(); + if (value != newValue) { + value = newValue; + invalidate(); + } + } + + protected: + uint32_t options = 0; + std::function getValue; + int8_t value = 0; +}; + +class MainViewHorizontalSlider : public MainViewSlider +{ + public: + using MainViewSlider::MainViewSlider; + + void paint(BitmapBuffer * dc) override + { + drawHorizontalSlider(dc, 0, 0, width(), getValue(), -RESX, RESX, 40, options); + } +}; diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index 4f2d28c2d..d5e60bf57 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -82,6 +82,20 @@ class LayoutChoice: public FormField { } #endif +#if defined(HARDWARE_TOUCH) + bool onTouchEnd(coord_t, coord_t) override + { + if (enabled) { + if (!hasFocus()) { + setFocus(SET_FOCUS_DEFAULT); + } + onKeyPress(); + openMenu(); + } + return true; + } +#endif + void openMenu() { auto menu = new Menu(parent); diff --git a/radio/src/gui/colorlcd/topbar.cpp b/radio/src/gui/colorlcd/topbar.cpp index 1bc9e1aef..380fdb6c1 100644 --- a/radio/src/gui/colorlcd/topbar.cpp +++ b/radio/src/gui/colorlcd/topbar.cpp @@ -26,14 +26,14 @@ unsigned int Topbar::getZonesCount() const return MAX_TOPBAR_ZONES; } -Zone Topbar::getZone(unsigned int index) const +rect_t Topbar::getZone(unsigned int index) const { - Zone zone; - zone.x = 49 + (TOPBAR_ZONE_WIDTH + 2*TOPBAR_ZONE_MARGIN) * index; - zone.y = TOPBAR_ZONE_MARGIN; - zone.w = TOPBAR_ZONE_WIDTH; - zone.h = MENU_HEADER_HEIGHT - 2*TOPBAR_ZONE_MARGIN; - return zone; + rect_t rect; + rect.x = 49 + (TOPBAR_ZONE_WIDTH + 2*TOPBAR_ZONE_MARGIN) * index; + rect.y = TOPBAR_ZONE_MARGIN; + rect.w = TOPBAR_ZONE_WIDTH; + rect.h = TOPBAR_HEIGHT; + return rect; } const char * const STR_MONTHS[] = TR_MONTHS; diff --git a/radio/src/gui/colorlcd/topbar.h b/radio/src/gui/colorlcd/topbar.h index 7c4e5f3b2..510845297 100644 --- a/radio/src/gui/colorlcd/topbar.h +++ b/radio/src/gui/colorlcd/topbar.h @@ -26,19 +26,20 @@ #define MAX_TOPBAR_ZONES 4 #define MAX_TOPBAR_OPTIONS 1 // just because of VC++ which doesn't like 0-size arrays :( #define TOPBAR_ZONE_WIDTH 70 -#define TOPBAR_ZONE_MARGIN 3 +constexpr coord_t TOPBAR_ZONE_MARGIN = 3; +constexpr coord_t TOPBAR_HEIGHT = MENU_HEADER_HEIGHT - 2 * TOPBAR_ZONE_MARGIN; class Topbar: public WidgetsContainer { public: explicit Topbar(PersistentData * persistentData): - WidgetsContainer(persistentData) + WidgetsContainer({0, 0, LCD_W, TOPBAR_ZONE_WIDTH}, persistentData) { } - virtual unsigned int getZonesCount() const; + unsigned int getZonesCount() const override; - virtual Zone getZone(unsigned int index) const; + rect_t getZone(unsigned int index) const override; }; #endif // _TOPBAR_H_ diff --git a/radio/src/gui/colorlcd/view_main.cpp b/radio/src/gui/colorlcd/view_main.cpp index 6c1022353..1a6777739 100644 --- a/radio/src/gui/colorlcd/view_main.cpp +++ b/radio/src/gui/colorlcd/view_main.cpp @@ -239,6 +239,15 @@ void ViewMain::openMenu() void ViewMain::checkEvents() { Window::checkEvents(); + + // TODO attach elsewhere + for (uint8_t i=0; igetParent()) { + customScreens[i]->attach(this); + } + } + } } void ViewMain::paint(BitmapBuffer * dc) @@ -250,15 +259,15 @@ void ViewMain::paint(BitmapBuffer * dc) if (g_model.view >= getMainViewsCount()) { g_model.view = 0; } - - for (uint8_t i=0; irefresh(); } - else - customScreens[i]->background(); - } - } +// +// for (uint8_t i=0; irefresh(); } +// else +// customScreens[i]->background(); +// } +// } } #if 0 diff --git a/radio/src/gui/colorlcd/widget.cpp b/radio/src/gui/colorlcd/widget.cpp index 0b22203a2..f377be0b6 100644 --- a/radio/src/gui/colorlcd/widget.cpp +++ b/radio/src/gui/colorlcd/widget.cpp @@ -43,11 +43,11 @@ const WidgetFactory * getWidgetFactory(const char * name) return nullptr; } -Widget * loadWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData) +Widget * loadWidget(const char * name, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData) { const WidgetFactory * factory = getWidgetFactory(name); if (factory) { - return factory->create(zone, persistentData, false); + return factory->create(parent, rect, persistentData, false); } return nullptr; } diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index 4a6c7ee9a..2014c3990 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -34,23 +34,21 @@ #endif class WidgetFactory; -class Widget +class Widget : public Window { public: struct PersistentData { ZoneOptionValueTyped options[MAX_WIDGET_OPTIONS] USE_IDX; }; - Widget(const WidgetFactory * factory, const Zone & zone, PersistentData * persistentData): + Widget(const WidgetFactory * factory, Window * parent, const rect_t & rect, PersistentData * persistentData): + Window(parent, rect), factory(factory), - zone(zone), persistentData(persistentData) { } - virtual ~Widget() - { - } + ~Widget() override = default; virtual void update() { @@ -73,15 +71,12 @@ class Widget return &persistentData->options[index].value; } - virtual void refresh() = 0; - virtual void background() { } protected: const WidgetFactory * factory; - Zone zone; PersistentData * persistentData; }; @@ -90,7 +85,7 @@ void registerWidget(const WidgetFactory * factory); class WidgetFactory { public: - WidgetFactory(const char * name, const ZoneOption * options=nullptr): + explicit WidgetFactory(const char * name, const ZoneOption * options = nullptr): name(name), options(options) { @@ -121,7 +116,7 @@ class WidgetFactory } } - virtual Widget * create(const Zone & zone, Widget::PersistentData * persistentData, bool init=true) const = 0; + virtual Widget * create(Window * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const = 0; protected: const char * name; @@ -137,13 +132,13 @@ class BaseWidgetFactory: public WidgetFactory { } - virtual Widget * create(const Zone & zone, Widget::PersistentData * persistentData, bool init=true) const + Widget * create(Window * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const override { if (init) { initPersistentData(persistentData); } - return new T(this, zone, persistentData); + return new T(this, parent, rect, persistentData); } }; @@ -152,7 +147,7 @@ inline const ZoneOption * Widget::getOptions() const return getFactory()->getOptions(); } -Widget * loadWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData); +Widget * loadWidget(const char * name, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData); std::list & getRegisteredWidgets(); diff --git a/radio/src/gui/colorlcd/widgets/text.cpp b/radio/src/gui/colorlcd/widgets/text.cpp index 4195e503d..3248107c8 100644 --- a/radio/src/gui/colorlcd/widgets/text.cpp +++ b/radio/src/gui/colorlcd/widgets/text.cpp @@ -20,17 +20,40 @@ #include "opentx.h" -#define TEXT_WIDGET_DEFAULT_LABEL '\15', '\347', '\0', '\14', '\377', '\376', '\373', '\364' // "My Label" +#define TEXT_WIDGET_DEFAULT_LABEL 'M', 'y', ' ', 'L', 'a', 'b', 'e', 'l' // "My Label" class TextWidget: public Widget { public: - TextWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData): - Widget(factory, zone, persistentData) + TextWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + Widget(factory, parent, rect, persistentData) { } - void refresh() override; + void paint(BitmapBuffer * dc) override + { + // TODO DELETE THOSE TEST INIT VALUE !! + strcpy(persistentData->options[0].value.stringValue, "This is a test string"); + persistentData->options[3].value.boolValue = true; // shadow + // TODO END TEST INIT VALUE + + // clear the background + dc->clear(DEFAULT_BGCOLOR); + + // get font color from options[1] + lcdSetColor(persistentData->options[1].value.unsignedValue); + + // get font size from options[2] + LcdFlags fontsize = persistentData->options[2].value.unsignedValue << 8u; + + // draw shadow + if (persistentData->options[3].value.boolValue) { + dc->drawText(1, 1, persistentData->options[0].value.stringValue, fontsize | BLACK); + } + + // draw text + dc->drawText(0, 0, persistentData->options[0].value.stringValue, fontsize | CUSTOM_COLOR); + } static const ZoneOption options[]; }; @@ -43,20 +66,4 @@ const ZoneOption TextWidget::options[] = { { nullptr, ZoneOption::Bool } }; -void TextWidget::refresh() -{ - lcdSetColor(persistentData->options[1].value.unsignedValue); - LcdFlags fontsize = FONTSIZE(persistentData->options[2].value.unsignedValue << 8); - if(persistentData->options[3].value.boolValue) { - lcdDrawSizedText(zone.x+1, zone.y+1, - persistentData->options[0].value.stringValue, - sizeof(persistentData->options[0].value.stringValue), - ZCHAR|fontsize|BLACK); - } - lcdDrawSizedText(zone.x, zone.y, - persistentData->options[0].value.stringValue, - sizeof(persistentData->options[0].value.stringValue), - ZCHAR|fontsize|CUSTOM_COLOR); -} - BaseWidgetFactory textWidget("Text", TextWidget::options); diff --git a/radio/src/gui/colorlcd/widgets/value.cpp b/radio/src/gui/colorlcd/widgets/value.cpp index a00c1200a..60be57d55 100644 --- a/radio/src/gui/colorlcd/widgets/value.cpp +++ b/radio/src/gui/colorlcd/widgets/value.cpp @@ -20,17 +20,111 @@ #include "opentx.h" +const coord_t NUMBERS_PADDING = 4; + class ValueWidget: public Widget { public: - ValueWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData): - Widget(factory, zone, persistentData) + ValueWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData): + Widget(factory, parent, rect, persistentData) { } - void refresh() override; + void paint(BitmapBuffer * dc) override + { + // TODO DELETE THOSE TEST INIT VALUE !! + persistentData->options[0].value.unsignedValue = 1; + // TODO END TEST INIT VALUE + + // draw the background and border + dc->clear(DEFAULT_BGCOLOR); + dc->drawFilledRect(0,0, width(), height(), SOLID, MAINVIEW_PANES_COLOR | OPACITY(5)); + + // get source from options[0] + mixsrc_t field = persistentData->options[0].value.unsignedValue; + + // get color from options[1] + lcdSetColor(persistentData->options[1].value.unsignedValue); + + coord_t xValue, yValue, xLabel, yLabel; + LcdFlags attrValue, attrLabel = 0; + + if (width() < 120 && height() < 50) { + xValue = 0; + yValue = 14; + xLabel = 0; + yLabel = 0; + attrValue = LEFT | NO_UNIT | FONT(XS); + attrLabel = FONT(XS); + } + else if (height() < 50) { + xValue = width() - NUMBERS_PADDING; + yValue = -2; + xLabel = NUMBERS_PADDING; + yLabel = +2; + attrValue = RIGHT | NO_UNIT | FONT(XL); + } + else { + xValue = NUMBERS_PADDING; + yValue = 18; + xLabel = NUMBERS_PADDING; + yLabel = 2; + if (field >= MIXSRC_FIRST_TELEM) { + if (isGPSSensor(1 + (field - MIXSRC_FIRST_TELEM) / 3)) { + attrValue = LEFT | FONT(L) | EXPANDED; + } + else { + attrValue = LEFT | FONT(XL); + } + } +#if defined(INTERNAL_GPS) + else if (field == MIXSRC_TX_GPS) { + attrValue = LEFT | FONT(L) | EXPANDED; + } +#endif + else { + attrValue = LEFT | FONT(XL); + } + } + + if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) { + TimerState & timerState = timersStates[field - MIXSRC_FIRST_TIMER]; + if (timerState.val < 0) { + lcdSetColor(lcdColorTable[ALARM_COLOR_INDEX]); + } + 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) { + TelemetryItem & telemetryItem = telemetryItems[(field - MIXSRC_FIRST_TELEM) / 3]; // TODO macro to convert a source to a telemetry index + if (!telemetryItem.isAvailable() || telemetryItem.isOld()) { + lcdSetColor(lcdColorTable[TEXT_DISABLE_COLOR_INDEX]); + } + } + + if (persistentData->options[2].value.boolValue) { + drawSource(dc,xLabel + 1, yLabel + 1, field, attrLabel | BLACK); + drawSourceValue(dc, xValue + 1, yValue + 1, field, attrValue | BLACK); + } + + drawSource(dc, xLabel, yLabel, field, attrLabel | CUSTOM_COLOR); + drawSourceValue(dc, xValue, yValue, field, attrValue | CUSTOM_COLOR); + } + + void checkEvents() override + { + auto newValue = getValue(persistentData->options[0].value.unsignedValue); + if (lastValue != newValue) { + lastValue = newValue; + invalidate(); + } + } static const ZoneOption options[]; + int32_t lastValue = 0; }; const ZoneOption ValueWidget::options[] = { @@ -40,85 +134,4 @@ const ZoneOption ValueWidget::options[] = { { nullptr, ZoneOption::Bool } }; -void ValueWidget::refresh() -{ - const int NUMBERS_PADDING = 4; - - mixsrc_t field = persistentData->options[0].value.unsignedValue; - lcdSetColor(persistentData->options[1].value.unsignedValue); - - int x = zone.x; - int y = zone.y; - - // TRACE("w=%d, h=%d", zone.w, zone.h); - - // lcdDrawFilledRect(zone.x, zone.y, zone.w, zone.h, SOLID, MAINVIEW_PANES_COLOR | OPACITY(5)); - - int xValue, yValue, xLabel, yLabel; - LcdFlags attrValue, attrLabel=0; - if (zone.w < 120 && zone.h < 50) { - xValue = x; - yValue = y+14; - xLabel = x; - yLabel = y; - attrValue = LEFT | NO_UNIT | MIDSIZE; - attrLabel = FONT(XS); - } - else if (zone.h < 50) { - xValue = x+zone.w-NUMBERS_PADDING; - yValue = y-2; - xLabel = x+NUMBERS_PADDING; - yLabel = y+2; - attrValue = RIGHT | NO_UNIT | FONT(XL); - } - else { - xValue = x+NUMBERS_PADDING; - yValue = y+18; - xLabel = x+NUMBERS_PADDING; - yLabel = y+2; - if (field >= MIXSRC_FIRST_TELEM) { - if (isGPSSensor(1+(field-MIXSRC_FIRST_TELEM)/3)) { - attrValue = LEFT | MIDSIZE | EXPANDED; - } - else { - attrValue = LEFT | FONT(XL); - } - } -#if defined(INTERNAL_GPS) - else if (field == MIXSRC_TX_GPS) { - attrValue = LEFT | MIDSIZE | EXPANDED; - } -#endif - else { - attrValue = LEFT | FONT(XL); - } - } - - if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) { - TimerState & timerState = timersStates[field-MIXSRC_FIRST_TIMER]; - if (timerState.val < 0) { - lcdSetColor(lcdColorTable[ALARM_COLOR_INDEX]); - } - drawSource(x+NUMBERS_PADDING, y+2, field, CUSTOM_COLOR); - drawSource(x+NUMBERS_PADDING + 1, y + 3, field, BLACK); - drawTimer(xValue, yValue, abs(timerState.val), attrValue|FONT(XL)|CUSTOM_COLOR); - return; - } - - if (field >= MIXSRC_FIRST_TELEM) { - TelemetryItem & telemetryItem = telemetryItems[(field-MIXSRC_FIRST_TELEM)/3]; // TODO macro to convert a source to a telemetry index - if (!telemetryItem.isAvailable() || telemetryItem.isOld()) { - lcdSetColor(lcdColorTable[TEXT_DISABLE_COLOR_INDEX]); - } - } - - if(persistentData->options[2].value.boolValue) { - drawSource(xLabel + 1, yLabel + 1, field, attrLabel|BLACK); - drawSourceValue(xValue + 1, yValue + 1, field, attrValue|BLACK); - } - drawSource(xLabel, yLabel, field, attrLabel|CUSTOM_COLOR); - drawSourceValue(xValue, yValue, field, attrValue|CUSTOM_COLOR); - -} - BaseWidgetFactory ValueWidget("Value", ValueWidget::options); diff --git a/radio/src/gui/colorlcd/widgets_container.h b/radio/src/gui/colorlcd/widgets_container.h index c29c71e6b..642cfe474 100644 --- a/radio/src/gui/colorlcd/widgets_container.h +++ b/radio/src/gui/colorlcd/widgets_container.h @@ -22,6 +22,7 @@ #define _WIDGETS_CONTAINER_H_ #include +#include #include "widget.h" class WidgetsContainerInterface @@ -29,7 +30,7 @@ class WidgetsContainerInterface public: virtual unsigned int getZonesCount() const = 0; - virtual Zone getZone(unsigned int index) const = 0; + virtual rect_t getZone(unsigned int index) const = 0; inline Widget * getWidget(unsigned int index) { @@ -50,7 +51,7 @@ class WidgetsContainerInterface #define WIDGET_NAME_LEN 10 template -class WidgetsContainer: public WidgetsContainerInterface +class WidgetsContainer: public Window, public WidgetsContainerInterface { public: struct ZonePersistentData { @@ -63,21 +64,10 @@ class WidgetsContainer: public WidgetsContainerInterface ZoneOptionValueTyped options[O]; }; - public: - WidgetsContainer(PersistentData * persistentData): + WidgetsContainer(const rect_t & rect, PersistentData * persistentData): + Window(nullptr, rect), persistentData(persistentData) { - widgets = (Widget **)calloc(N, sizeof(Widget *)); - } - - virtual ~WidgetsContainer() - { - if (widgets) { - for (uint8_t i=0; izones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName)); if (factory) { strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(persistentData->zones[index].widgetName)); - widgets[index] = factory->create(getZone(index), &persistentData->zones[index].widgetData); + widgets[index] = factory->create(this, getZone(index), &persistentData->zones[index].widgetData); } else { widgets[index] = nullptr; @@ -103,13 +93,20 @@ class WidgetsContainer: public WidgetsContainerInterface { if (widgets) { unsigned int count = getZonesCount(); - for (unsigned int i=0; izones[i].widgetName[0]) { + if (i == 0) { + char name[WIDGET_NAME_LEN + 1] = "Text"; + widgets[i] = loadWidget(name, this, getZone(i), &persistentData->zones[i].widgetData); + } else if (i == 1) { + char name[WIDGET_NAME_LEN + 1] = "Value"; + widgets[i] = loadWidget(name, this, getZone(i), &persistentData->zones[i].widgetData); + } + else if (persistentData->zones[i].widgetName[0]) { char name[WIDGET_NAME_LEN + 1]; memset(name, 0, sizeof(name)); strncpy(name, persistentData->zones[i].widgetName, WIDGET_NAME_LEN); - // widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData); + // TODO widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData); } else { widgets[i] = nullptr; @@ -125,23 +122,12 @@ class WidgetsContainer: public WidgetsContainerInterface unsigned int getZonesCount() const override = 0; - Zone getZone(unsigned int index) const override = 0; - - virtual void refresh() - { - if (widgets) { - for (int i=0; irefresh(); - } - } - } - } + rect_t getZone(unsigned int index) const override = 0; virtual void background() { if (widgets) { - for (int i=0; ibackground(); } @@ -151,6 +137,7 @@ class WidgetsContainer: public WidgetsContainerInterface protected: PersistentData * persistentData; + Widget * widgets[N] = {}; }; #endif // _WIDGETS_CONTAINER_H_ diff --git a/radio/src/gui/colorlcd/zone.h b/radio/src/gui/colorlcd/zone.h index 097058f00..26836b063 100644 --- a/radio/src/gui/colorlcd/zone.h +++ b/radio/src/gui/colorlcd/zone.h @@ -19,11 +19,6 @@ #define OPTION_VALUE_STRING(...) { .stringValue = { __VA_ARGS__ } } #endif -struct Zone -{ - uint16_t x, y, w, h; -}; - union ZoneOptionValue { uint32_t unsignedValue; diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 09f879d94..81af2c299 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -183,7 +183,7 @@ void postModelLoad(bool alarms) referenceModelAudioFiles(); #endif -#if defined(PCBHORUS) +#if defined(COLORLCD) loadCustomScreens(); #endif