From 0aff002c8a81910993e1fc4f184910742a3b12a0 Mon Sep 17 00:00:00 2001 From: philmoz Date: Thu, 21 Sep 2023 19:39:05 +1000 Subject: [PATCH] chore(color): Cleanup and optimise EdgeTxTheme class (#4013) --- .../src/firmwares/customisation_data.cpp | 17 - companion/src/firmwares/customisation_data.h | 18 -- .../firmwares/edgetx/yaml_generalsettings.cpp | 6 - companion/src/firmwares/generalsettings.h | 2 - .../src/firmwares/opentx/opentxeeprom.cpp | 16 - .../src/modeledit/colorcustomscreens.cpp | 7 - radio/src/datastructs.h | 6 +- radio/src/datastructs_private.h | 13 - radio/src/gui/colorlcd/curve.cpp | 1 + radio/src/gui/colorlcd/draw_functions.cpp | 1 + radio/src/gui/colorlcd/fab_button.cpp | 2 +- radio/src/gui/colorlcd/fullscreen_dialog.cpp | 1 + radio/src/gui/colorlcd/gui.h | 1 - radio/src/gui/colorlcd/layout.cpp | 1 + radio/src/gui/colorlcd/layout.h | 3 - .../colorlcd/layouts/layout_factory_impl.h | 5 - .../src/gui/colorlcd/layouts/topbar_impl.cpp | 1 + radio/src/gui/colorlcd/page.cpp | 1 + radio/src/gui/colorlcd/tabsgroup.cpp | 1 + radio/src/gui/colorlcd/theme.cpp | 295 ++++++++++-------- radio/src/gui/colorlcd/theme.h | 118 ++----- radio/src/gui/colorlcd/theme_manager.cpp | 22 +- radio/src/gui/colorlcd/themes/480_default.cpp | 239 -------------- radio/src/gui/colorlcd/view_main.cpp | 1 + radio/src/gui/colorlcd/widget.cpp | 1 + radio/src/gui/colorlcd/widgets/radio_info.cpp | 15 +- radio/src/lua/api_colorlcd.cpp | 3 +- radio/src/main.cpp | 1 + radio/src/myeeprom.h | 1 - radio/src/opentx.cpp | 10 +- radio/src/storage/sdcard_common.cpp | 6 +- .../storage/yaml/yaml_datastructs_nv14.cpp | 54 ++-- .../src/storage/yaml/yaml_datastructs_x10.cpp | 54 ++-- .../storage/yaml/yaml_datastructs_x12s.cpp | 54 ++-- .../libopenui/src/libopenui_defines.h | 3 +- 35 files changed, 306 insertions(+), 674 deletions(-) delete mode 100644 radio/src/gui/colorlcd/themes/480_default.cpp diff --git a/companion/src/firmwares/customisation_data.cpp b/companion/src/firmwares/customisation_data.cpp index ad91cfc8358..ebca3c3b61b 100644 --- a/companion/src/firmwares/customisation_data.cpp +++ b/companion/src/firmwares/customisation_data.cpp @@ -132,23 +132,6 @@ bool RadioLayout::CustomScreenData::isEmpty() const return strlen(layoutId) == 0; } -void RadioTheme::init(const char* themeName, ThemeData& themeData) -{ - memset(&themeData, 0, sizeof(ThemeData)); - - memcpy(&themeData.themeName, themeName, THEME_NAME_LEN); - - PersistentData& persistentData = themeData.themePersistentData; - - persistentData.options[0].type = - zoneValueEnumFromType(ZoneOption::Type::Color); - setZoneOptionValue(persistentData.options[0].value, (unsigned int)WHITE); - - persistentData.options[1].type = - zoneValueEnumFromType(ZoneOption::Type::Color); - setZoneOptionValue(persistentData.options[1].value, (unsigned int)RED); -} - void RadioLayout::init(const char* layoutId, CustomScreens& customScreens) { memset(&customScreens, 0, sizeof(CustomScreens)); diff --git a/companion/src/firmwares/customisation_data.h b/companion/src/firmwares/customisation_data.h index 7496bcca1ad..043707fac47 100644 --- a/companion/src/firmwares/customisation_data.h +++ b/companion/src/firmwares/customisation_data.h @@ -31,7 +31,6 @@ */ constexpr int MAX_CUSTOM_SCREENS {10}; -constexpr int THEME_NAME_LEN {8}; constexpr int MAX_THEME_OPTIONS {5}; constexpr int LEN_ZONE_OPTION_STRING {8}; constexpr int MAX_LAYOUT_ZONES {10}; @@ -146,23 +145,6 @@ typedef WidgetsContainerPersistentData typedef WidgetsContainerPersistentData TopBarPersistentData; -class RadioTheme -{ - Q_DECLARE_TR_FUNCTIONS(RadioTheme) - - public: - struct PersistentData { - ZoneOptionValueTyped options[MAX_THEME_OPTIONS]; - }; - - struct ThemeData { - char themeName[THEME_NAME_LEN + 1]; - PersistentData themePersistentData; - }; - - static void init(const char * themeName, ThemeData & themeData); -}; - class RadioLayout { Q_DECLARE_TR_FUNCTIONS(RadioLayout) diff --git a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp index 6e0cd4eee3c..373e4d42307 100644 --- a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp +++ b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp @@ -299,9 +299,6 @@ Node convert::encode(const GeneralSettings& rhs) node["potsConfig"] = potsConfig; } - // Color lcd theme settings are not used in EdgeTx - // RadioTheme::ThemeData themeData; - node["ownerRegistrationID"] = rhs.registrationId; // Gyro (for now only xlites) @@ -573,9 +570,6 @@ bool convert::decode(const Node& node, GeneralSettings& rhs) } } - // Color lcd theme settings are not used in EdgeTx - // RadioTheme::ThemeData themeData; - node["ownerRegistrationID"] >> rhs.registrationId; // Gyro (for now only xlites) diff --git a/companion/src/firmwares/generalsettings.h b/companion/src/firmwares/generalsettings.h index f5b40e23ca2..f651716f40c 100644 --- a/companion/src/firmwares/generalsettings.h +++ b/companion/src/firmwares/generalsettings.h @@ -277,8 +277,6 @@ class GeneralSettings { char sliderName[CPN_MAX_SLIDERS][HARDWARE_NAME_LEN + 1]; unsigned int sliderConfig[CPN_MAX_SLIDERS]; - RadioTheme::ThemeData themeData; - char registrationId[REGISTRATION_ID_LEN + 1]; int gyroMax; int gyroOffset; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index d6247523368..1199208ecb0 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -3304,15 +3304,6 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name")); } - if (IS_FAMILY_HORUS_OR_T16(board)) { - if (version >= 220) { // data from earlier versions cannot be converted so fields initialised in afterImport - internalField.Append(new CharField<8>(this, generalData.themeData.themeName, true, "Theme name")); - for (int i = 0; i < MAX_THEME_OPTIONS; i++) { - internalField.Append(new ZoneOptionValueTypedField(this, generalData.themeData.themePersistentData.options[i], board, version)); - } - } - } - if (version >= 220) { internalField.Append(new CharField<8>(this, generalData.registrationId, "ACCESS Registration ID")); } @@ -3357,13 +3348,6 @@ void OpenTxGeneralData::beforeExport() void OpenTxGeneralData::afterImport() { - if (IS_FAMILY_HORUS_OR_T16(board)) { - if (version < 220) { // re-initialise as no conversion possible - const char * themeName = IS_FLYSKY_NV14(board) ? "FlySky" : "EdgeTX"; - RadioTheme::init(themeName, generalData.themeData); - } - } - if (Boards::getCapability((Board::Type)generalData.variant, Board::SportMaxBaudRate) >= 400000) generalData.internalModuleBaudrate = diff --git a/companion/src/modeledit/colorcustomscreens.cpp b/companion/src/modeledit/colorcustomscreens.cpp index 90a8d5fd941..6b7736fb28a 100644 --- a/companion/src/modeledit/colorcustomscreens.cpp +++ b/companion/src/modeledit/colorcustomscreens.cpp @@ -39,8 +39,6 @@ UserInterfacePanel::UserInterfacePanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): ModelPanel(parent, model, generalSettings, firmware) { - RadioTheme::ThemeData & td = generalSettings.themeData; - QString sdPath = QString(g.profile[g.id()].sdPath()).trimmed(); grid = new QGridLayout(this); @@ -191,11 +189,6 @@ UserInterfacePanel::UserInterfacePanel(QWidget * parent, ModelData & model, Gene col = 0; - if (SHOW_RAW_INFO) { - addGridLabel(grid, tr("Theme"), row, col++); - grid->addLayout(addOptionsLayout(td.themePersistentData, MAX_THEME_OPTIONS), row, col); - } - // the grid must be fully built for the rowspan to work as required foreach (QWidget * wgt, optswidgets) { grid->addWidget(wgt, widgetdetailsrow, widgetdetailscol, 3, Qt::AlignTop); diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 4907f81ab1d..f35d37e2ae9 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -147,14 +147,14 @@ static inline void check_struct() CHKSIZE(ModelData, 6706); #elif defined(PCBHORUS) #if defined(PCBX10) - CHKSIZE(RadioData, 916); + CHKSIZE(RadioData, 848); CHKSIZE(ModelData, 15607); #else - CHKSIZE(RadioData, 916); + CHKSIZE(RadioData, 848); CHKSIZE(ModelData, 15607); #endif #elif defined(PCBNV14) - CHKSIZE(RadioData, 916); + CHKSIZE(RadioData, 848); CHKSIZE(ModelData, 15463); #endif diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 0dd13401e08..347730b1357 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -830,16 +830,6 @@ PACK(struct TrainerData { BLUETOOTH_FIELDS #endif -#if defined(COLORLCD) && !defined(BACKUP) - #include "theme.h" - #define THEME_NAME_LEN 8 - #define THEME_DATA \ - NOBACKUP(char themeName[THEME_NAME_LEN]); \ - NOBACKUP(EdgeTxTheme::PersistentData themeData); -#else - #define THEME_DATA -#endif - #if defined(BUZZER) #define BUZZER_FIELD int8_t buzzerMode:2 // -2=quiet, -1=only alarms, 0=no keys, 1=all (only used on AVR radios without audio hardware) #else @@ -934,8 +924,6 @@ PACK(struct RadioData { EXTRA_GENERAL_FIELDS - THEME_DATA - char ownerRegistrationID[PXX2_LEN_REGISTRATION_ID]; CUST_ATTR(rotEncDirection, r_rotEncDirection, nullptr); @@ -992,5 +980,4 @@ PACK(struct RadioData { #undef SCRIPTS_DATA #undef CUSTOM_SCREENS_DATA #undef EXTRA_GENERAL_FIELDS -#undef THEME_DATA #undef NOBACKUP diff --git a/radio/src/gui/colorlcd/curve.cpp b/radio/src/gui/colorlcd/curve.cpp index e096d8a7fcb..14ee870db27 100644 --- a/radio/src/gui/colorlcd/curve.cpp +++ b/radio/src/gui/colorlcd/curve.cpp @@ -25,6 +25,7 @@ #include "bitmaps.h" #include "strhelpers.h" #include "font.h" +#include "theme.h" const uint8_t _LBM_CURVE_POINT[] = { #include "mask_cvpoint.lbm" diff --git a/radio/src/gui/colorlcd/draw_functions.cpp b/radio/src/gui/colorlcd/draw_functions.cpp index 06f9e736473..1823203b104 100644 --- a/radio/src/gui/colorlcd/draw_functions.cpp +++ b/radio/src/gui/colorlcd/draw_functions.cpp @@ -23,6 +23,7 @@ #include "lcd.h" #include "theme_manager.h" #include "libopenui.h" +#include "theme.h" #include "watchdog_driver.h" diff --git a/radio/src/gui/colorlcd/fab_button.cpp b/radio/src/gui/colorlcd/fab_button.cpp index 8fb211b1660..424d4b443c5 100644 --- a/radio/src/gui/colorlcd/fab_button.cpp +++ b/radio/src/gui/colorlcd/fab_button.cpp @@ -57,7 +57,7 @@ void FabButton::paint(BitmapBuffer * dc) dc->drawBitmap((width() - bitmap->width()) / 2, (FAB_BUTTON_SIZE - bitmap->height()) / 2, bitmap); - const BitmapBuffer* mask = theme->getIconMask(icon); + const BitmapBuffer* mask = EdgeTxTheme::instance()->getIconMask(icon); if (mask) { dc->drawMask((width() - mask->width()) / 2, (FAB_BUTTON_SIZE - mask->height()) / 2, mask, COLOR2FLAGS(WHITE)); diff --git a/radio/src/gui/colorlcd/fullscreen_dialog.cpp b/radio/src/gui/colorlcd/fullscreen_dialog.cpp index b5306f54f75..f973bb74dcd 100644 --- a/radio/src/gui/colorlcd/fullscreen_dialog.cpp +++ b/radio/src/gui/colorlcd/fullscreen_dialog.cpp @@ -24,6 +24,7 @@ #include "mainwindow.h" #include "opentx.h" #include "libopenui.h" +#include "theme.h" #include "watchdog_driver.h" diff --git a/radio/src/gui/colorlcd/gui.h b/radio/src/gui/colorlcd/gui.h index 00b49c06893..b8f9fcfa502 100644 --- a/radio/src/gui/colorlcd/gui.h +++ b/radio/src/gui/colorlcd/gui.h @@ -28,7 +28,6 @@ #include "popups.h" #include "draw_functions.h" #include "bitmaps.h" -#include "theme.h" #define LOAD_MODEL_BITMAP() diff --git a/radio/src/gui/colorlcd/layout.cpp b/radio/src/gui/colorlcd/layout.cpp index cddf6fabe51..8b5651da222 100644 --- a/radio/src/gui/colorlcd/layout.cpp +++ b/radio/src/gui/colorlcd/layout.cpp @@ -22,6 +22,7 @@ #include "opentx.h" #include "view_main.h" #include "topbar_impl.h" +#include "theme.h" WidgetsContainer * customScreens[MAX_CUSTOM_SCREENS] = {}; diff --git a/radio/src/gui/colorlcd/layout.h b/radio/src/gui/colorlcd/layout.h index 6fc86412780..301b11a0c76 100644 --- a/radio/src/gui/colorlcd/layout.h +++ b/radio/src/gui/colorlcd/layout.h @@ -52,9 +52,6 @@ class LayoutFactory virtual const uint8_t* getBitmap() const = 0; - virtual void drawThumb(BitmapBuffer* dc, uint16_t x, uint16_t y, - LcdFlags flags) const = 0; - virtual const ZoneOption* getOptions() const = 0; virtual WidgetsContainer* create(Window* parent, diff --git a/radio/src/gui/colorlcd/layouts/layout_factory_impl.h b/radio/src/gui/colorlcd/layouts/layout_factory_impl.h index 56d0d62518c..b2e043c5972 100644 --- a/radio/src/gui/colorlcd/layouts/layout_factory_impl.h +++ b/radio/src/gui/colorlcd/layouts/layout_factory_impl.h @@ -206,11 +206,6 @@ class BaseLayoutFactory: public LayoutFactory const uint8_t* getBitmap() const override { return bitmap; } - void drawThumb(BitmapBuffer * dc, uint16_t x, uint16_t y, uint32_t flags) const override - { - dc->drawBitmapPattern(x, y, bitmap, flags); - } - const ZoneOption * getOptions() const override { return options; diff --git a/radio/src/gui/colorlcd/layouts/topbar_impl.cpp b/radio/src/gui/colorlcd/layouts/topbar_impl.cpp index d6d8d7b233c..474855672b9 100644 --- a/radio/src/gui/colorlcd/layouts/topbar_impl.cpp +++ b/radio/src/gui/colorlcd/layouts/topbar_impl.cpp @@ -21,6 +21,7 @@ #include "topbar_impl.h" #include "opentx.h" +#include "theme.h" constexpr uint32_t TOPBAR_REFRESH = 1000 / 10; // 10 Hz diff --git a/radio/src/gui/colorlcd/page.cpp b/radio/src/gui/colorlcd/page.cpp index a75966db427..aa749585a98 100644 --- a/radio/src/gui/colorlcd/page.cpp +++ b/radio/src/gui/colorlcd/page.cpp @@ -23,6 +23,7 @@ #include "mainwindow.h" #include "keyboard_base.h" #include "opentx.h" +#include "theme.h" PageHeader::PageHeader(Page * parent, uint8_t icon): FormWindow(parent, { 0, 0, LCD_W, MENU_HEADER_HEIGHT }, OPAQUE), diff --git a/radio/src/gui/colorlcd/tabsgroup.cpp b/radio/src/gui/colorlcd/tabsgroup.cpp index b9be76edae3..4e87c61a5a4 100644 --- a/radio/src/gui/colorlcd/tabsgroup.cpp +++ b/radio/src/gui/colorlcd/tabsgroup.cpp @@ -24,6 +24,7 @@ #include "mainwindow.h" #include "view_main.h" #include "static.h" +#include "theme.h" #if defined(HARDWARE_TOUCH) #include "keyboard_base.h" diff --git a/radio/src/gui/colorlcd/theme.cpp b/radio/src/gui/colorlcd/theme.cpp index 319a905a2e4..74d5c88bcb0 100644 --- a/radio/src/gui/colorlcd/theme.cpp +++ b/radio/src/gui/colorlcd/theme.cpp @@ -21,14 +21,8 @@ #include "opentx.h" #include "libopenui.h" - -extern EdgeTxTheme * defaultTheme; -const BitmapBuffer * EdgeTxTheme::error = nullptr; -const BitmapBuffer * EdgeTxTheme::busy = nullptr; -const BitmapBuffer * EdgeTxTheme::shutdown = nullptr; - -constexpr coord_t LBM_USB_PLUGGED_W = 211; -constexpr coord_t LBM_USB_PLUGGED_H = 110; +#include "theme.h" +#include "theme_manager.h" const uint8_t _LBM_USB_PLUGGED[] = { #include "mask_usb_symbol.lbm" @@ -47,166 +41,217 @@ const uint8_t shutdown_bitmap[] = { #include "mask_shutdown.lbm" }; -std::list & getRegisteredThemes() -{ - static std::list themes; - return themes; -} +const uint8_t mask_topleft[] = { +#include "mask_topleft.lbm" +}; -void registerTheme(EdgeTxTheme * theme) -{ - TRACE("register theme %s", theme->getName()); - getRegisteredThemes().push_back(theme); -} +const uint8_t mask_currentmenu_bg[] = { +#include "mask_currentmenu_bg.lbm" +}; + +const uint8_t mask_currentmenu_dot[] = { +#include "mask_currentmenu_dot.lbm" +}; + +const uint8_t mask_currentmenu_shadow[] = { +#include "mask_currentmenu_shadow.lbm" +}; + +uint16_t EdgeTxTheme::defaultColors[LCD_COLOR_COUNT] = { + RGB(18, 94, 153), // DEFAULT + RGB(0, 0, 0), // PRIMARY1 + RGB(255, 255, 255), // PRIMARY2 + RGB(12, 63, 102), // PRIMARY3 + RGB(18, 94, 153), // SECONDARY1 + RGB(182, 224, 242), // SECONDARY2 + RGB(228, 238, 242), // SECONDARY3 + RGB(20, 161, 229), // FOCUS + RGB(0, 153, 9), // EDIT + RGB(255, 222, 0), // ACTIVE + RGB(224, 0, 0), // WARNING + RGB(140, 140, 140), // DISABLED + RGB(170, 85, 0) // CUSTOM +}; -void EdgeTxTheme::init() const +EdgeTxTheme::EdgeTxTheme(): name("EdgeTX") { - memset(&g_eeGeneral.themeData, 0, sizeof(EdgeTxTheme::PersistentData)); - if (options) { - int i = 0; - for (const ZoneOption * option = options; option->name; option++, i++) { - // TODO compiler bug? The CPU freezes ... g_eeGeneral.themeData.options[i] = &option->deflt; - memcpy(&g_eeGeneral.themeData.options[i].value, &option->deflt, sizeof(ZoneOptionValue)); - g_eeGeneral.themeData.options[i].type = zoneValueEnumFromType(option->type); - } - } + loadColors(); } -void EdgeTxTheme::load() const +void EdgeTxTheme::load() { + loadColors(); + ThemePersistance::instance()->loadDefaultTheme(); + if (!error) error = BitmapBuffer::load8bitMaskLZ4(error_bitmap); if (!busy) busy = BitmapBuffer::load8bitMaskLZ4(busy_bitmap); if (!shutdown) shutdown = BitmapBuffer::load8bitMaskLZ4(shutdown_bitmap); + + update(); +} + +void EdgeTxTheme::update() +{ + createIcons(); + loadIcons(); + if (!backgroundBitmap) { + backgroundBitmap = BitmapBuffer::loadBitmap(getFilePath("background.png")); + } + initLvglTheme(); +} + +void EdgeTxTheme::loadColors() const +{ + TRACE("Load EdgeTX theme colors"); + memcpy(lcdColorTable, defaultColors, sizeof(defaultColors)); +} + +void EdgeTxTheme::createIcons() +{ + if (!iconsLoaded) { + iconsLoaded = true; + + iconMask = new BitmapBuffer*[MENUS_ICONS_COUNT]; + for (int id = ICON_EDGETX; id != MENUS_ICONS_COUNT; id++) { + iconMask[id] = BitmapBuffer::load8bitMaskLZ4(getBuiltinIcon((MenuIcons)id)); + } + + // Get mask with max size. Extract size from shadow LBM file. + uint16_t* shadow = (uint16_t*)mask_currentmenu_shadow; + currentMenuBackground = new BitmapBuffer(BMP_RGB565, shadow[0], shadow[1]); + + topleftBitmap = BitmapBuffer::load8bitMaskLZ4(mask_topleft); + + loadBuiltinBitmaps(); + } +} + +void EdgeTxTheme::loadIcons() const +{ + if (currentMenuBackground) { + currentMenuBackground->drawSolidFilledRect( + 0, 0, currentMenuBackground->width(), currentMenuBackground->height(), + COLOR_THEME_SECONDARY1); + + currentMenuBackground->drawSolidFilledRect( + 0, MENU_HEADER_HEIGHT, currentMenuBackground->width(), + MENU_TITLE_TOP - MENU_HEADER_HEIGHT, COLOR_THEME_SECONDARY3); + + std::unique_ptr background(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_bg)); + currentMenuBackground->drawMask(0, 0, background.get(), COLOR_THEME_FOCUS); + + std::unique_ptr shadow(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_shadow)); + currentMenuBackground->drawMask(0, 0, shadow.get(), COLOR_THEME_PRIMARY1); + + std::unique_ptr dot(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_dot)); + currentMenuBackground->drawMask(10, 39, dot.get(), COLOR_THEME_PRIMARY2); + } } -ZoneOptionValue * EdgeTxTheme::getOptionValue(unsigned int index) const +void EdgeTxTheme::setBackgroundImageFileName(const char *fileName) { - return &g_eeGeneral.themeData.options[index].value; + // ensure you delete old bitmap + if (backgroundBitmap != nullptr) + delete backgroundBitmap; + + strncpy(backgroundImageFileName, fileName, FF_MAX_LFN); + backgroundImageFileName[FF_MAX_LFN] = '\0'; // ensure string termination + + // Try to load bitmap. If this fails backgroundBitmap will be NULL and default will be loaded in update() method + backgroundBitmap = BitmapBuffer::loadBitmap(backgroundImageFileName); } const char * EdgeTxTheme::getFilePath(const char * filename) const { static char path[FF_MAX_LFN+1] = THEMES_PATH "/"; - strcpy(path + sizeof(THEMES_PATH), getName()); + strcpy(path + sizeof(THEMES_PATH), name); int len = sizeof(THEMES_PATH) + strlen(path + sizeof(THEMES_PATH)); path[len] = '/'; strcpy(path+len+1, filename); return path; } -void EdgeTxTheme::drawThumb(BitmapBuffer * dc, coord_t x, coord_t y, uint32_t flags) -{ - #define THUMB_WIDTH 51 - #define THUMB_HEIGHT 31 - if (!thumb) { - thumb = BitmapBuffer::loadBitmap(getFilePath("thumb.bmp")); - } - lcd->drawBitmap(x, y, thumb); - if (flags == COLOR_THEME_PRIMARY3) { - dc->drawFilledRect(x, y, THUMB_WIDTH, THUMB_HEIGHT, SOLID, COLOR_THEME_PRIMARY1); - } -} - -void EdgeTxTheme::drawBackground(BitmapBuffer * dc) const +const BitmapBuffer * EdgeTxTheme::getIconMask(uint8_t index) const { - dc->drawSolidFilledRect(0, 0, LCD_W, LCD_H, COLOR_THEME_SECONDARY3); -} - -//void EdgeTxTheme::drawMessageBox(const char *title, const char *text, -// const char *action, uint32_t type) const -//{ -// //if (flags & MESSAGEBOX_TYPE_ALERT) { -// drawBackground(); -// lcdDrawFilledRect(0, POPUP_Y, LCD_W, POPUP_H, SOLID, COLOR_THEME_PRIMARY2 | -// OPACITY(8)); -// //} -// -// if (type == WARNING_TYPE_ALERT || type == WARNING_TYPE_ASTERISK) -// lcd->drawBitmap(POPUP_X-80, POPUP_Y+12, asterisk); -// else if (type == WARNING_TYPE_INFO) -// lcd->drawBitmap(POPUP_X-80, POPUP_Y+12, busy); -// else -// lcd->drawBitmap(POPUP_X-80, POPUP_Y+12, question); -// -// if (type == WARNING_TYPE_ALERT) { -//#if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || -//defined(TRANSLATIONS_CZ) -// lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y, STR_WARNING, -// COLOR_THEME_WARNING|FONT(XL)); lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+28, -// title, COLOR_THEME_WARNING|FONT(XL)); -//#else -// lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y, title, COLOR_THEME_WARNING|FONT(XL)); -// lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+28, STR_WARNING, -// COLOR_THEME_WARNING|FONT(XL)); -//#endif -// } -// else if (title) { -// lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y, title, COLOR_THEME_WARNING|FONT(XL)); -// } -// -// if (text) { -// lcdDrawText(WARNING_LINE_X, WARNING_INFOLINE_Y, text); -// } -// -// if (action) { -// lcdDrawText(WARNING_LINE_X, WARNING_INFOLINE_Y+24, action); -// } -//} - -void EdgeTxTheme::drawCheckBox(BitmapBuffer *dc, bool checked, coord_t x, - coord_t y, bool focus) const -{ - dc->drawSolidFilledRect(x, y, 16, 16, COLOR_THEME_PRIMARY2); - if (focus) { - dc->drawSolidRect(x, y, 16, 16, 2, COLOR_THEME_FOCUS); - } - else { - dc->drawSolidRect(x, y, 16, 16, 1, COLOR_THEME_SECONDARY2); - } - if (checked) { - dc->drawSolidFilledRect(x + 3, y + 3, 10, 10, COLOR_THEME_FOCUS); - } + return iconMask[index]; } void EdgeTxTheme::drawUsbPluggedScreen(BitmapBuffer * dc) const { // draw USB icon dc->clear(COLOR_THEME_SECONDARY3); - dc->drawBitmapPattern((LCD_W - LBM_USB_PLUGGED_W) / 2, - (LCD_H - LBM_USB_PLUGGED_H) / 2, + uint16_t* usb_icon_hdr = (uint16_t*)_LBM_USB_PLUGGED; + dc->drawBitmapPattern((LCD_W - usb_icon_hdr[0]) / 2, + (LCD_H - usb_icon_hdr[1]) / 2, LBM_USB_PLUGGED, COLOR_THEME_SECONDARY1); } +void EdgeTxTheme::drawBackground(BitmapBuffer * dc) const +{ + dc->clear(COLOR_THEME_SECONDARY3); + if (backgroundBitmap) + dc->drawBitmap(0, 0, backgroundBitmap); +} + +void EdgeTxTheme::drawHeaderIcon(BitmapBuffer * dc, uint8_t icon) const +{ + dc->drawSolidFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, COLOR_THEME_SECONDARY1); + + if (topleftBitmap) + dc->drawMask(0, 0, topleftBitmap, COLOR_THEME_FOCUS); + + if (icon == ICON_EDGETX) + dc->drawMask(4, 10, iconMask[icon], COLOR_THEME_PRIMARY2); + else + dc->drawMask(5, 7, iconMask[icon], COLOR_THEME_PRIMARY2); +} -EdgeTxTheme * getTheme(const char * name) +void EdgeTxTheme::drawPageHeaderBackground(BitmapBuffer *dc, uint8_t icon, const char *title) const { - std::list::const_iterator it = getRegisteredThemes().cbegin(); - for (; it != getRegisteredThemes().cend(); ++it) { - if (!strcmp(name, (*it)->getName())) { - return (*it); - } + drawHeaderIcon(dc, icon); + + dc->drawSolidFilledRect(0, MENU_HEADER_HEIGHT, LCD_W, + MENU_TITLE_TOP - MENU_HEADER_HEIGHT, + COLOR_THEME_SECONDARY3); // the white separation line + + dc->drawSolidFilledRect(0, MENU_TITLE_TOP, LCD_W, MENU_TITLE_HEIGHT, + COLOR_THEME_SECONDARY1); // the title line background + if (title) { + dc->drawText(MENUS_MARGIN_LEFT, MENU_TITLE_TOP + 1, title, COLOR_THEME_PRIMARY2); } - return nullptr; + + drawMenuDatetime(dc, DATETIME_MIDDLE, DATETIME_LINE1, COLOR_THEME_PRIMARY2); } -void loadTheme(EdgeTxTheme * newTheme) +void EdgeTxTheme::drawMenuDatetime(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags color) const { - TRACE("load theme %s", newTheme->getName()); - theme = newTheme; - newTheme->load(); + const TimerOptions timerOptions = {.options = SHOW_TIME}; + struct gtm t; + gettime(&t); + char str[10]; +#if defined(TRANSLATIONS_CN) || defined(TRANSLATIONS_TW) + sprintf(str, "%02d-%02d", t.tm_mon + 1, t.tm_mday); +#else + sprintf(str, "%d %s", t.tm_mday, STR_MONTHS[t.tm_mon]); +#endif + dc->drawText(x, y, str, FONT(XS)|color|CENTERED); + getTimerString(str, getValue(MIXSRC_TX_TIME), timerOptions); + dc->drawText(x, y + 15, str, FONT(XS)|color|CENTERED); } -void loadTheme() +void EdgeTxTheme::drawMenuIcon(BitmapBuffer *dc, uint8_t icon, bool checked) const { - char name[THEME_NAME_LEN + 1]; - memset(name, 0, sizeof(name)); - strncpy(name, g_eeGeneral.themeName, THEME_NAME_LEN); - EdgeTxTheme * newTheme = getTheme(name); - if (newTheme) - loadTheme(newTheme); - else - loadTheme(defaultTheme); + if (checked) + dc->drawBitmap(0, 0, currentMenuBackground); + dc->drawMask(2, 7, iconMask[icon], COLOR_THEME_PRIMARY2); +} + +EdgeTxTheme defaultTheme; + +EdgeTxTheme * EdgeTxTheme::instance() +{ + return &defaultTheme; } diff --git a/radio/src/gui/colorlcd/theme.h b/radio/src/gui/colorlcd/theme.h index df99cad2fdb..4f4b7d58970 100644 --- a/radio/src/gui/colorlcd/theme.h +++ b/radio/src/gui/colorlcd/theme.h @@ -19,17 +19,7 @@ * GNU General Public License for more details. */ -#ifndef _COLORLCD_THEME_H_ -#define _COLORLCD_THEME_H_ - -#include -#include -#include "zone.h" - -enum IconState { - STATE_DEFAULT, - STATE_PRESSED, -}; +#pragma once // TODO: hotfix, through FatFS out of libopenui instead #if !defined(YAML_GENERATOR) @@ -39,104 +29,54 @@ enum IconState { #endif class BitmapBuffer; -class PageTab; - -#define MAX_THEME_OPTIONS 5 - -class EdgeTxTheme; -void registerTheme(EdgeTxTheme * theme); - -// YAML_GENERATOR defs -#if !defined(USE_IDX) -#define USE_IDX -#endif - -class EdgeTxTheme; -extern EdgeTxTheme * theme; class EdgeTxTheme { public: - struct PersistentData { - ZoneOptionValueTyped options[MAX_THEME_OPTIONS] USE_IDX; - }; - - explicit EdgeTxTheme(const char * name, const ZoneOption * options = nullptr): - name(name), - options(options), - thumb(nullptr) - { - registerTheme(this); - } - - static EdgeTxTheme * instance() - { - return theme; - } - - inline const char * getName() const - { - return name; - } - - const char * getFilePath(const char * filename) const; + EdgeTxTheme(); - void drawThumb(BitmapBuffer * dc, coord_t x, coord_t y, uint32_t flags); + static EdgeTxTheme * instance(); - inline const ZoneOption * getOptions() const - { - return options; - } - - void init() const; - - virtual void update(bool reload = true) const - { - } - - ZoneOptionValue * getOptionValue(unsigned int index) const; + const char * getFilePath(const char * filename) const; - virtual void setBackgroundImageFileName(const char *fileName) - { - strncpy(backgroundImageFileName, fileName, FF_MAX_LFN); - backgroundImageFileName[FF_MAX_LFN] = '\0'; // ensure string termination - } + void createIcons(); + void loadColors() const; + void loadIcons() const; + virtual void load(); + void update(); - virtual void load() const; + void setBackgroundImageFileName(const char *fileName); - virtual void drawBackground(BitmapBuffer * dc) const; + void drawBackground(BitmapBuffer * dc) const; - virtual void drawPageHeaderBackground(BitmapBuffer *dc, uint8_t icon, - const char *title) const = 0; + void drawPageHeaderBackground(BitmapBuffer *dc, uint8_t icon, const char *title) const; - virtual void drawMenuIcon(BitmapBuffer *dc, uint8_t icon, bool checked) const = 0; + void drawMenuIcon(BitmapBuffer *dc, uint8_t icon, bool checked) const; - virtual void drawCheckBox(BitmapBuffer * dc, bool checked, coord_t x, coord_t y, bool focus) const; + void drawMenuDatetime(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags color) const; - virtual void drawHeaderIcon(BitmapBuffer * dc, uint8_t icon) const = 0; + void drawHeaderIcon(BitmapBuffer * dc, uint8_t icon) const; - virtual void drawUsbPluggedScreen(BitmapBuffer * dc) const; + void drawUsbPluggedScreen(BitmapBuffer * dc) const; - virtual const BitmapBuffer * getIconMask(uint8_t index) const = 0; + const BitmapBuffer * getIconMask(uint8_t index) const; - virtual uint16_t* getDefaultColors() const = 0; + uint16_t* getDefaultColors() const { return defaultColors; } protected: + bool iconsLoaded = false; const char * name; - const ZoneOption * options; - BitmapBuffer * thumb; char backgroundImageFileName[FF_MAX_LFN + 1]; - public: - static const BitmapBuffer * error; - static const BitmapBuffer * busy; - static const BitmapBuffer * shutdown; -}; - -EdgeTxTheme * getTheme(const char * name); -void loadTheme(EdgeTxTheme * theme); -void loadTheme(); + const BitmapBuffer * backgroundBitmap = nullptr; + const BitmapBuffer * topleftBitmap = nullptr; + BitmapBuffer * currentMenuBackground = nullptr; + BitmapBuffer ** iconMask = nullptr; -std::list & getRegisteredThemes(); + static uint16_t defaultColors[LCD_COLOR_COUNT]; -#endif // _COLORLCD_THEME_H_ + public: + const BitmapBuffer * error = nullptr; + const BitmapBuffer * busy = nullptr; + const BitmapBuffer * shutdown = nullptr; +}; diff --git a/radio/src/gui/colorlcd/theme_manager.cpp b/radio/src/gui/colorlcd/theme_manager.cpp index 7e442fe67e0..3d733a9a71d 100644 --- a/radio/src/gui/colorlcd/theme_manager.cpp +++ b/radio/src/gui/colorlcd/theme_manager.cpp @@ -20,6 +20,7 @@ */ #include "theme_manager.h" #include "view_main.h" +#include "theme.h" #include "../../storage/yaml/yaml_tree_walker.h" #include "../../storage/yaml/yaml_bits.h" @@ -245,26 +246,20 @@ void ThemeFile::applyBackground() if (isFileAvailable(rootDir.c_str())) { instance->setBackgroundImageFileName((char *)rootDir.c_str()); - } else { - // TODO: This needs to be made user configurable, not - // require the file be deleted to remove global background - std::string fileName = THEMES_PATH PATH_SEPARATOR "EdgeTX/background.png"; - if (isFileAvailable(fileName.c_str())) { - instance->setBackgroundImageFileName(fileName.c_str()); - } else { - instance->setBackgroundImageFileName(""); + return; } - } - } else { - instance->setBackgroundImageFileName(""); } + + // Use EdgeTxTheme default background + // TODO: This needs to be made user configurable + instance->setBackgroundImageFileName(""); } void ThemeFile::applyTheme() { applyColors(); applyBackground(); - EdgeTxTheme::instance()->update(false); + EdgeTxTheme::instance()->update(); // Update views with new theme // Currently, on startup, active theme is loaded after ViewMain is created so ViewMain instance is defined @@ -467,8 +462,7 @@ class DefaultEdgeTxTheme : public ThemeFile setInfo("Default EdgeTX Color Scheme"); // initializze the default color table - extern EdgeTxTheme * defaultTheme; - uint16_t* defaultColors = defaultTheme->getDefaultColors(); + uint16_t* defaultColors = EdgeTxTheme::instance()->getDefaultColors(); for (uint8_t i = COLOR_THEME_PRIMARY1_INDEX; i <= COLOR_THEME_DISABLED_INDEX; i += 1) colorList.emplace_back(ColorEntry { (LcdColorIndex)i, defaultColors[i] }); } diff --git a/radio/src/gui/colorlcd/themes/480_default.cpp b/radio/src/gui/colorlcd/themes/480_default.cpp deleted file mode 100644 index 19ad556c1b2..00000000000 --- a/radio/src/gui/colorlcd/themes/480_default.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * 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 "tabsgroup.h" -#include "bitmaps.h" -#include "theme_manager.h" - -#include -using std::unique_ptr; - -const ZoneOption OPTIONS_THEME_DEFAULT[] = { - { STR_BACKGROUND_COLOR, ZoneOption::Color, OPTION_VALUE_UNSIGNED(COLOR_THEME_PRIMARY2 >> 16) }, - { STR_MAIN_COLOR, ZoneOption::Color, OPTION_VALUE_UNSIGNED(COLOR_THEME_WARNING >> 16) }, - { nullptr, ZoneOption::Bool } -}; - -const uint8_t mask_topleft[] = { -#include "mask_topleft.lbm" -}; -const uint8_t mask_currentmenu_bg[] = { -#include "mask_currentmenu_bg.lbm" -}; -const uint8_t mask_currentmenu_dot[] = { -#include "mask_currentmenu_dot.lbm" -}; -const uint8_t mask_currentmenu_shadow[] = { -#include "mask_currentmenu_shadow.lbm" -}; - -class Theme480: public EdgeTxTheme -{ - public: - Theme480(): - EdgeTxTheme("EdgeTX", OPTIONS_THEME_DEFAULT) - { - loadColors(); - } - - void loadColors() const - { - TRACE("Load EdgeTX theme colors"); - memcpy(lcdColorTable, defaultColors, sizeof(defaultColors)); - } - - void createIcons() const - { - if (iconsLoaded) - return; - - iconsLoaded = true; - - for (int id = ICON_EDGETX; id != MENUS_ICONS_COUNT; id++) { - iconMask[id] = BitmapBuffer::load8bitMaskLZ4(getBuiltinIcon((MenuIcons)id)); - } - - // Get mask with max size - unique_ptr shadow(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_shadow)); - currentMenuBackground = new BitmapBuffer(BMP_RGB565, shadow->width(), shadow->height()); - - topleftBitmap = BitmapBuffer::load8bitMaskLZ4(mask_topleft); - - loadBuiltinBitmaps(); - } - - void loadIcons() const - { - if (currentMenuBackground) { - currentMenuBackground->drawSolidFilledRect( - 0, 0, currentMenuBackground->width(), currentMenuBackground->height(), - COLOR_THEME_SECONDARY1); - - currentMenuBackground->drawSolidFilledRect( - 0, MENU_HEADER_HEIGHT, currentMenuBackground->width(), - MENU_TITLE_TOP - MENU_HEADER_HEIGHT, COLOR_THEME_SECONDARY3); - - unique_ptr background(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_bg)); - currentMenuBackground->drawMask(0, 0, background.get(), COLOR_THEME_FOCUS); - - unique_ptr shadow(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_shadow)); - currentMenuBackground->drawMask(0, 0, shadow.get(), COLOR_THEME_PRIMARY1); - - unique_ptr dot(BitmapBuffer::load8bitMaskLZ4(mask_currentmenu_dot)); - currentMenuBackground->drawMask(10, 39, dot.get(), COLOR_THEME_PRIMARY2); - } - } - - void setBackgroundImageFileName(const char *fileName) override - { - // ensure you delete old bitmap - if (backgroundBitmap != nullptr) - delete backgroundBitmap; - EdgeTxTheme::setBackgroundImageFileName(fileName); // set the filename - backgroundBitmap = BitmapBuffer::loadBitmap(backgroundImageFileName); - } - - void load() const override - { - loadColors(); - ThemePersistance::instance()->loadDefaultTheme(); - EdgeTxTheme::load(); - if (!backgroundBitmap) { - backgroundBitmap = BitmapBuffer::loadBitmap(getFilePath("background.png")); - } - update(); - } - - void update(bool reload = true) const override - { - createIcons(); - loadIcons(); - initLvglTheme(); - } - - void drawBackground(BitmapBuffer * dc) const override - { - dc->clear(COLOR_THEME_SECONDARY3); - if (backgroundBitmap) - dc->drawBitmap(0, 0, backgroundBitmap); - } - - void drawHeaderIcon(BitmapBuffer * dc, uint8_t icon) const override - { - dc->drawSolidFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, COLOR_THEME_SECONDARY1); - - if (topleftBitmap) - dc->drawMask(0, 0, topleftBitmap, COLOR_THEME_FOCUS); - - if (icon == ICON_EDGETX) - dc->drawMask(4, 10, iconMask[icon], COLOR_THEME_PRIMARY2); - else - dc->drawMask(5, 7, iconMask[icon], COLOR_THEME_PRIMARY2); - } - - void drawPageHeaderBackground(BitmapBuffer *dc, uint8_t icon, - const char *title) const override - { - drawHeaderIcon(dc, icon); - - dc->drawSolidFilledRect(0, MENU_HEADER_HEIGHT, LCD_W, - MENU_TITLE_TOP - MENU_HEADER_HEIGHT, - COLOR_THEME_SECONDARY3); // the white separation line - - dc->drawSolidFilledRect(0, MENU_TITLE_TOP, LCD_W, MENU_TITLE_HEIGHT, - COLOR_THEME_SECONDARY1); // the title line background - if (title) { - dc->drawText(MENUS_MARGIN_LEFT, MENU_TITLE_TOP + 1, title, COLOR_THEME_PRIMARY2); - } - - drawMenuDatetime(dc); - } - - const BitmapBuffer * getIconMask(uint8_t index) const override - { - return iconMask[index]; - } - - void drawMenuIcon(BitmapBuffer *dc, uint8_t icon, bool checked) const override - { - if (checked) - dc->drawBitmap(0, 0, currentMenuBackground); - dc->drawMask(2, 7, iconMask[icon], COLOR_THEME_PRIMARY2); - } - - void drawMenuDatetime(BitmapBuffer * dc) const - { - //dc->drawSolidVerticalLine(DATETIME_SEPARATOR_X, 7, 31, COLOR_THEME_PRIMARY2); - const TimerOptions timerOptions = {.options = SHOW_TIME}; - struct gtm t; - gettime(&t); - char str[10]; -#if defined(TRANSLATIONS_CN) || defined(TRANSLATIONS_TW) - sprintf(str, "%02d-%02d", t.tm_mon + 1, t.tm_mday); -#else - sprintf(str, "%d %s", t.tm_mday, STR_MONTHS[t.tm_mon]); -#endif - dc->drawText(DATETIME_MIDDLE, DATETIME_LINE1, str, FONT(XS)|COLOR_THEME_PRIMARY2|CENTERED); - getTimerString(str, getValue(MIXSRC_TX_TIME), timerOptions); - dc->drawText(DATETIME_MIDDLE, DATETIME_LINE2, str, FONT(XS)|COLOR_THEME_PRIMARY2|CENTERED); - } - - uint16_t* getDefaultColors() const override { return defaultColors; } - - protected: - static bool iconsLoaded; - static const BitmapBuffer * backgroundBitmap; - static BitmapBuffer * topleftBitmap; - static BitmapBuffer * iconMask[MENUS_ICONS_COUNT]; - static BitmapBuffer * currentMenuBackground; - static uint16_t defaultColors[LCD_COLOR_COUNT]; -}; - -bool Theme480::iconsLoaded = false; - -const BitmapBuffer * Theme480::backgroundBitmap = nullptr; -BitmapBuffer * Theme480::topleftBitmap = nullptr; -BitmapBuffer * Theme480::iconMask[MENUS_ICONS_COUNT] = { nullptr }; -BitmapBuffer * Theme480::currentMenuBackground = nullptr; - -uint16_t Theme480::defaultColors[LCD_COLOR_COUNT] = { - RGB(18, 94, 153), // DEFAULT - RGB(0, 0, 0), // PRIMARY1 - RGB(255, 255, 255), // PRIMARY2 - RGB(12, 63, 102), // PRIMARY3 - RGB(18, 94, 153), // SECONDARY1 - RGB(182, 224, 242), // SECONDARY2 - RGB(228, 238, 242), // SECONDARY3 - RGB(20, 161, 229), // FOCUS - RGB(0, 153, 9), // EDIT - RGB(255, 222, 0), // ACTIVE - RGB(224, 0, 0), // WARNING - RGB(140, 140, 140), // DISABLED - RGB(170, 85, 0) // CUSTOM -}; - -Theme480 theme480; - -#if LCD_W == 480 || LCD_H == 480 -EdgeTxTheme * defaultTheme = &theme480; -EdgeTxTheme * theme = &theme480; -#endif diff --git a/radio/src/gui/colorlcd/view_main.cpp b/radio/src/gui/colorlcd/view_main.cpp index 9012faa7ab1..8c4bc52d827 100644 --- a/radio/src/gui/colorlcd/view_main.cpp +++ b/radio/src/gui/colorlcd/view_main.cpp @@ -26,6 +26,7 @@ #include "menu_screen.h" #include "topbar_impl.h" #include "view_main_menu.h" +#include "theme.h" #include "opentx.h" diff --git a/radio/src/gui/colorlcd/widget.cpp b/radio/src/gui/colorlcd/widget.cpp index 69f2e7b201e..19e0436fa2d 100644 --- a/radio/src/gui/colorlcd/widget.cpp +++ b/radio/src/gui/colorlcd/widget.cpp @@ -25,6 +25,7 @@ #include "widget_settings.h" #include "view_main.h" #include "lcd.h" +#include "theme.h" #if defined(HARDWARE_TOUCH) #include "touch.h" diff --git a/radio/src/gui/colorlcd/widgets/radio_info.cpp b/radio/src/gui/colorlcd/widgets/radio_info.cpp index 4cb2c7de02d..c2e4f9a2c2e 100644 --- a/radio/src/gui/colorlcd/widgets/radio_info.cpp +++ b/radio/src/gui/colorlcd/widgets/radio_info.cpp @@ -21,6 +21,7 @@ #include "opentx.h" #include "widgets_container_impl.h" +#include "theme.h" #define W_AUDIO_X 0 #define W_USB_X 32 @@ -192,19 +193,7 @@ class DateTimeWidget: public Widget { // get color from options LcdFlags color = COLOR2FLAGS(persistentData->options[0].value.unsignedValue); - - const TimerOptions timerOptions = {.options = SHOW_TIME}; - struct gtm t; - gettime(&t); - char str[10]; -#if defined(TRANSLATIONS_CN) || defined(TRANSLATIONS_TW) - sprintf(str, "%02d-%02d", t.tm_mon + 1, t.tm_mday); -#else - sprintf(str, "%d %s", t.tm_mday, STR_MONTHS[t.tm_mon]); -#endif - dc->drawText(width()/2+DT_OFFSET, 3, str, FONT(XS) | CENTERED | color); - getTimerString(str, getValue(MIXSRC_TX_TIME), timerOptions); - dc->drawText(width()/2+DT_OFFSET, 18, str, FONT(XS) | CENTERED | color); + EdgeTxTheme::instance()->drawMenuDatetime(dc, width()/2+DT_OFFSET, 3, color); } void checkEvents() override diff --git a/radio/src/lua/api_colorlcd.cpp b/radio/src/lua/api_colorlcd.cpp index 09cfc62bf46..9993e76c410 100644 --- a/radio/src/lua/api_colorlcd.cpp +++ b/radio/src/lua/api_colorlcd.cpp @@ -27,6 +27,7 @@ #include "opentx.h" #include "libopenui.h" #include "widget.h" +#include "theme.h" #include "lua_api.h" #include "api_colorlcd.h" @@ -971,7 +972,7 @@ static int luaLcdSetColor(lua_State *L) if (index < LCD_COLOR_COUNT && lcdColorTable[index] != color) { lcdColorTable[index] = color; if (index != CUSTOM_COLOR_INDEX) - EdgeTxTheme::instance()->update(false); + EdgeTxTheme::instance()->update(); } return 0; } diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 0957794f4fc..2a2d4c2394e 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -26,6 +26,7 @@ #include "libopenui.h" #include "gui/colorlcd/LvglWrapper.h" #include "gui/colorlcd/view_main.h" + #include "theme.h" #endif #if defined(CLI) diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 90982531459..f68d61e0e56 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -118,7 +118,6 @@ #if defined(COLORLCD) && !defined(BOOT) #include "layout.h" - #include "theme.h" #include "topbar.h" #endif diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 725b328fee6..145e6e1cdf6 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -43,6 +43,7 @@ #include "radio_calibration.h" #include "view_main.h" #include "view_text.h" + #include "theme.h" #include "gui/colorlcd/LvglWrapper.h" #endif @@ -322,11 +323,6 @@ void generalDefault() strcpy(g_eeGeneral.currModelFilename, DEFAULT_MODEL_FILENAME); #endif -#if defined(COLORLCD) - strcpy(g_eeGeneral.themeName, static_cast(theme)->getName()); - static_cast(theme)->init(); -#endif - #if defined(PXX2) setDefaultOwnerId(); #endif @@ -1171,7 +1167,7 @@ void opentxResume() #if defined(COLORLCD) //TODO: needs to go into storageReadAll() TRACE("reloading theme"); - loadTheme(); + EdgeTxTheme::instance()->load(); // Force redraw ViewMain::instance()->invalidate(); @@ -1534,7 +1530,7 @@ void opentxInit() BACKLIGHT_ENABLE(); #if defined(COLORLCD) - loadTheme(); + EdgeTxTheme::instance()->load(); if (g_eeGeneral.backlightMode == e_backlight_mode_off) { // no backlight mode off on color lcd radios g_eeGeneral.backlightMode = e_backlight_mode_keys; diff --git a/radio/src/storage/sdcard_common.cpp b/radio/src/storage/sdcard_common.cpp index 6d3708fb82b..74badbb1b43 100644 --- a/radio/src/storage/sdcard_common.cpp +++ b/radio/src/storage/sdcard_common.cpp @@ -25,6 +25,10 @@ #include "modelslist.h" #include "model_init.h" +#if defined(COLORLCD) + #include "theme.h" +#endif + void getModelPath(char * path, const char * filename, const char* pathName) { unsigned int len = strlen(pathName); @@ -39,7 +43,7 @@ void storageEraseAll(bool warn) #if defined(COLORLCD) // the theme has not been loaded before - static_cast(theme)->load(); + EdgeTxTheme::instance()->load(); #endif // Init backlight mode before entering alert screens diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index 623476a51ad..bfd7c0a05eb 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -87,15 +87,6 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_DISABLE_AUDIO_AMP, "DISABLE_AUDIO_AMP" }, { 0, NULL } }; -const struct YamlIdStr enum_ZoneOptionValueEnum[] = { - { ZOV_Unsigned, "Unsigned" }, - { ZOV_Signed, "Signed" }, - { ZOV_Bool, "Bool" }, - { ZOV_String, "String" }, - { ZOV_Source, "Source" }, - { ZOV_Color, "Color" }, - { 0, NULL } -}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -203,6 +194,15 @@ const struct YamlIdStr enum_TelemetrySensorType[] = { { TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" }, { 0, NULL } }; +const struct YamlIdStr enum_ZoneOptionValueEnum[] = { + { ZOV_Unsigned, "Unsigned" }, + { ZOV_Signed, "Signed" }, + { ZOV_Bool, "Bool" }, + { ZOV_String, "String" }, + { ZOV_Source, "Source" }, + { ZOV_Color, "Color" }, + { 0, NULL } +}; const struct YamlIdStr enum_USBJoystickIfMode[] = { { USBJOYS_JOYSTICK, "JOYSTICK" }, { USBJOYS_GAMEPAD, "GAMEPAD" }, @@ -276,25 +276,6 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_PADDING( 8 ), YAML_END }; -static const struct YamlNode union_ZoneOptionValue_elmts[] = { - YAML_UNSIGNED( "unsignedValue", 32 ), - YAML_SIGNED( "signedValue", 32 ), - YAML_UNSIGNED( "boolValue", 32 ), - YAML_STRING("stringValue", 8), - YAML_CUSTOM("source",r_zov_source,w_zov_source), - YAML_CUSTOM("color",r_zov_color,w_zov_color), - YAML_END -}; -static const struct YamlNode struct_ZoneOptionValueTyped[] = { - YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), - YAML_UNION("value", 64, union_ZoneOptionValue_elmts, select_zov), - YAML_END -}; -static const struct YamlNode struct_EdgeTxTheme__PersistentData[] = { - YAML_ARRAY("options", 96, 5, struct_ZoneOptionValueTyped, NULL), - YAML_END -}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -376,8 +357,6 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_UNSIGNED( "blOffBright", 7 ), YAML_STRING("bluetoothName", 10), - YAML_STRING("themeName", 8), - YAML_STRUCT("themeData", 480, struct_EdgeTxTheme__PersistentData, NULL), YAML_STRING("ownerRegistrationID", 8), YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr), YAML_UNSIGNED( "rotEncMode", 2 ), @@ -767,6 +746,21 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg), YAML_END }; +static const struct YamlNode union_ZoneOptionValue_elmts[] = { + YAML_UNSIGNED( "unsignedValue", 32 ), + YAML_SIGNED( "signedValue", 32 ), + YAML_UNSIGNED( "boolValue", 32 ), + YAML_STRING("stringValue", 8), + YAML_CUSTOM("source",r_zov_source,w_zov_source), + YAML_CUSTOM("color",r_zov_color,w_zov_color), + YAML_END +}; +static const struct YamlNode struct_ZoneOptionValueTyped[] = { + YAML_IDX, + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_UNION("value", 64, union_ZoneOptionValue_elmts, select_zov), + YAML_END +}; static const struct YamlNode struct_WidgetPersistentData[] = { YAML_ARRAY("options", 96, 5, struct_ZoneOptionValueTyped, NULL), YAML_END diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index 35c2de0c4cd..df08bc1915b 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -87,15 +87,6 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_SET_SCREEN, "SET_SCREEN" }, { 0, NULL } }; -const struct YamlIdStr enum_ZoneOptionValueEnum[] = { - { ZOV_Unsigned, "Unsigned" }, - { ZOV_Signed, "Signed" }, - { ZOV_Bool, "Bool" }, - { ZOV_String, "String" }, - { ZOV_Source, "Source" }, - { ZOV_Color, "Color" }, - { 0, NULL } -}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -210,6 +201,15 @@ const struct YamlIdStr enum_TelemetrySensorType[] = { { TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" }, { 0, NULL } }; +const struct YamlIdStr enum_ZoneOptionValueEnum[] = { + { ZOV_Unsigned, "Unsigned" }, + { ZOV_Signed, "Signed" }, + { ZOV_Bool, "Bool" }, + { ZOV_String, "String" }, + { ZOV_Source, "Source" }, + { ZOV_Color, "Color" }, + { 0, NULL } +}; const struct YamlIdStr enum_USBJoystickIfMode[] = { { USBJOYS_JOYSTICK, "JOYSTICK" }, { USBJOYS_GAMEPAD, "GAMEPAD" }, @@ -283,25 +283,6 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_PADDING( 8 ), YAML_END }; -static const struct YamlNode union_ZoneOptionValue_elmts[] = { - YAML_UNSIGNED( "unsignedValue", 32 ), - YAML_SIGNED( "signedValue", 32 ), - YAML_UNSIGNED( "boolValue", 32 ), - YAML_STRING("stringValue", 8), - YAML_CUSTOM("source",r_zov_source,w_zov_source), - YAML_CUSTOM("color",r_zov_color,w_zov_color), - YAML_END -}; -static const struct YamlNode struct_ZoneOptionValueTyped[] = { - YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), - YAML_UNION("value", 64, union_ZoneOptionValue_elmts, select_zov), - YAML_END -}; -static const struct YamlNode struct_EdgeTxTheme__PersistentData[] = { - YAML_ARRAY("options", 96, 5, struct_ZoneOptionValueTyped, NULL), - YAML_END -}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -381,8 +362,6 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_UNSIGNED( "blOffBright", 7 ), YAML_STRING("bluetoothName", 10), - YAML_STRING("themeName", 8), - YAML_STRUCT("themeData", 480, struct_EdgeTxTheme__PersistentData, NULL), YAML_STRING("ownerRegistrationID", 8), YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr), YAML_UNSIGNED( "rotEncMode", 2 ), @@ -774,6 +753,21 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg), YAML_END }; +static const struct YamlNode union_ZoneOptionValue_elmts[] = { + YAML_UNSIGNED( "unsignedValue", 32 ), + YAML_SIGNED( "signedValue", 32 ), + YAML_UNSIGNED( "boolValue", 32 ), + YAML_STRING("stringValue", 8), + YAML_CUSTOM("source",r_zov_source,w_zov_source), + YAML_CUSTOM("color",r_zov_color,w_zov_color), + YAML_END +}; +static const struct YamlNode struct_ZoneOptionValueTyped[] = { + YAML_IDX, + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_UNION("value", 64, union_ZoneOptionValue_elmts, select_zov), + YAML_END +}; static const struct YamlNode struct_WidgetPersistentData[] = { YAML_ARRAY("options", 96, 5, struct_ZoneOptionValueTyped, NULL), YAML_END diff --git a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp index 35c2de0c4cd..df08bc1915b 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp @@ -87,15 +87,6 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_SET_SCREEN, "SET_SCREEN" }, { 0, NULL } }; -const struct YamlIdStr enum_ZoneOptionValueEnum[] = { - { ZOV_Unsigned, "Unsigned" }, - { ZOV_Signed, "Signed" }, - { ZOV_Bool, "Bool" }, - { ZOV_String, "String" }, - { ZOV_Source, "Source" }, - { ZOV_Color, "Color" }, - { 0, NULL } -}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -210,6 +201,15 @@ const struct YamlIdStr enum_TelemetrySensorType[] = { { TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" }, { 0, NULL } }; +const struct YamlIdStr enum_ZoneOptionValueEnum[] = { + { ZOV_Unsigned, "Unsigned" }, + { ZOV_Signed, "Signed" }, + { ZOV_Bool, "Bool" }, + { ZOV_String, "String" }, + { ZOV_Source, "Source" }, + { ZOV_Color, "Color" }, + { 0, NULL } +}; const struct YamlIdStr enum_USBJoystickIfMode[] = { { USBJOYS_JOYSTICK, "JOYSTICK" }, { USBJOYS_GAMEPAD, "GAMEPAD" }, @@ -283,25 +283,6 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_PADDING( 8 ), YAML_END }; -static const struct YamlNode union_ZoneOptionValue_elmts[] = { - YAML_UNSIGNED( "unsignedValue", 32 ), - YAML_SIGNED( "signedValue", 32 ), - YAML_UNSIGNED( "boolValue", 32 ), - YAML_STRING("stringValue", 8), - YAML_CUSTOM("source",r_zov_source,w_zov_source), - YAML_CUSTOM("color",r_zov_color,w_zov_color), - YAML_END -}; -static const struct YamlNode struct_ZoneOptionValueTyped[] = { - YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), - YAML_UNION("value", 64, union_ZoneOptionValue_elmts, select_zov), - YAML_END -}; -static const struct YamlNode struct_EdgeTxTheme__PersistentData[] = { - YAML_ARRAY("options", 96, 5, struct_ZoneOptionValueTyped, NULL), - YAML_END -}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -381,8 +362,6 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelQuickSelect", 1 ), YAML_UNSIGNED( "blOffBright", 7 ), YAML_STRING("bluetoothName", 10), - YAML_STRING("themeName", 8), - YAML_STRUCT("themeData", 480, struct_EdgeTxTheme__PersistentData, NULL), YAML_STRING("ownerRegistrationID", 8), YAML_CUSTOM("rotEncDirection",r_rotEncDirection,nullptr), YAML_UNSIGNED( "rotEncMode", 2 ), @@ -774,6 +753,21 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("cfg", 32, union_anonymous_17_elmts, select_sensor_cfg), YAML_END }; +static const struct YamlNode union_ZoneOptionValue_elmts[] = { + YAML_UNSIGNED( "unsignedValue", 32 ), + YAML_SIGNED( "signedValue", 32 ), + YAML_UNSIGNED( "boolValue", 32 ), + YAML_STRING("stringValue", 8), + YAML_CUSTOM("source",r_zov_source,w_zov_source), + YAML_CUSTOM("color",r_zov_color,w_zov_color), + YAML_END +}; +static const struct YamlNode struct_ZoneOptionValueTyped[] = { + YAML_IDX, + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_UNION("value", 64, union_ZoneOptionValue_elmts, select_zov), + YAML_END +}; static const struct YamlNode struct_WidgetPersistentData[] = { YAML_ARRAY("options", 96, 5, struct_ZoneOptionValueTyped, NULL), YAML_END diff --git a/radio/src/thirdparty/libopenui/src/libopenui_defines.h b/radio/src/thirdparty/libopenui/src/libopenui_defines.h index f85d843720b..20198b8552f 100644 --- a/radio/src/thirdparty/libopenui/src/libopenui_defines.h +++ b/radio/src/thirdparty/libopenui/src/libopenui_defines.h @@ -71,8 +71,7 @@ constexpr uint32_t CURVE_COORD_WIDTH = 36; constexpr uint32_t CURVE_COORD_HEIGHT = 17; constexpr uint32_t DATETIME_SEPARATOR_X = LCD_W - 53; -constexpr uint32_t DATETIME_LINE1 = 7; -constexpr uint32_t DATETIME_LINE2 = 22; +constexpr uint32_t DATETIME_LINE1 = 6; constexpr uint32_t DATETIME_MIDDLE = (LCD_W + DATETIME_SEPARATOR_X + 1) / 2; constexpr uint32_t PAGE_TITLE_TOP = 2;