diff --git a/src/helpers/ui/ColorThemes.h b/src/helpers/ui/ColorThemes.h new file mode 100644 index 00000000..e3294f44 --- /dev/null +++ b/src/helpers/ui/ColorThemes.h @@ -0,0 +1,84 @@ +#pragma once + +// Общие палитры цветных TFT-драйверов: ST7735Display и ST7789LCDDisplay. +// +// Таблица живёт в заголовке, а не в отдельном .cpp, чтобы оба драйвера +// использовали одну и ту же палитру. В сборке всегда включён ровно один +// драйвер (выбор по DISPLAY_CLASS), поэтому копий таблицы в прошивке нет. +// +// Значения — RGB565. CLASSIC — официальная светлая схема MeshCore +// (белый фон, чёрный текст), взятая из upstream. + +#include +#include "DisplayDriver.h" + +// Две темы сразу — почти наверняка ошибка в env +#if (defined(ST7735_THEME_CLASSIC) + defined(ST7735_THEME_AMBER) + defined(ST7735_THEME_TEAL) + defined(ST7735_THEME_SIGNAL) + defined(ST7735_THEME_NEON) + \ + defined(ST7789_THEME_CLASSIC) + defined(ST7789_THEME_AMBER) + defined(ST7789_THEME_TEAL) + defined(ST7789_THEME_SIGNAL) + defined(ST7789_THEME_NEON)) > 1 + #error "ColorThemes: выбрана более чем одна тема *_THEME_*" +#endif + +struct ColorTheme { + const char* name; + ColorVal window_bkg, title_bkg, title_txt, primary_txt, + secondary_txt, warning_txt, popup_bkg, popup_txt, corp_blue; +}; + +// Порядок в таблице = порядок в меню выбора темы +static constexpr ColorTheme UI_THEMES[] = { + { "amber", 0x1082, 0x2146, 0xF79E, 0xFFDF, 0x9493, 0xFD84, 0xFD84, 0x10A3, 0x551F }, // #101010 / #202830 / #FFB020 + { "teal", 0x0883, 0x1187, 0xEFDF, 0xF7DF, 0x8515, 0xFE4A, 0x1696, 0x0881, 0x45DF }, // #081018 / #103038 / #10D0B0 + { "signal", 0x0000, 0xEB07, 0x1082, 0xFFDF, 0x9D15, 0xFE8C, 0xFB46, 0x1082, 0x5D5F }, // #000000 / #E86038 / #FF6830 + { "neon", 0x0000, 0x0000, 0xEF5D, 0xFFFF, 0x8C52, 0xFEA0, 0x18C3, 0xFEA0, 0x555F }, // #000000 / #000000 / #FFD400 + { "classic", 0xFFFF, 0x001F, 0xFFFF, 0x0000, 0x9492, 0xFD20, 0x07FF, 0x0000, 0x001A }, // официальная светлая +}; +#define UI_THEME_COUNT ((uint8_t)(sizeof(UI_THEMES) / sizeof(UI_THEMES[0]))) + +// Тема по умолчанию: AMBER для Heltec T096, для остальных плат — официальная +// CLASSIC. Флаги *_THEME_* в platformio.ini варианта переопределяют выбор. +static constexpr uint8_t ui_default_theme_index() { +#if defined(ST7735_THEME_CLASSIC) || defined(ST7789_THEME_CLASSIC) + return 4; +#elif defined(ST7735_THEME_TEAL) || defined(ST7789_THEME_TEAL) + return 1; +#elif defined(ST7735_THEME_SIGNAL) || defined(ST7789_THEME_SIGNAL) + return 2; +#elif defined(ST7735_THEME_NEON) || defined(ST7789_THEME_NEON) + return 3; +#elif defined(ST7735_THEME_AMBER) || defined(ST7789_THEME_AMBER) || defined(HELTEC_T096) + return 0; +#else + return 4; +#endif +} + +static inline const char* ui_theme_name(uint8_t i) { + return i < UI_THEME_COUNT ? UI_THEMES[i].name : ""; +} + +static inline ColorVal ui_theme_color(uint8_t theme, uint8_t role) { + if (theme >= UI_THEME_COUNT) return 0; + const ColorTheme* t = &UI_THEMES[theme]; + switch (role) { + case DisplayDriver::THEME_COLOR_WINDOW: return t->window_bkg; + case DisplayDriver::THEME_COLOR_TITLE: return t->title_bkg; + case DisplayDriver::THEME_COLOR_POPUP: return t->popup_bkg; + case DisplayDriver::THEME_COLOR_ACCENT: return t->warning_txt; + default: return t->primary_txt; + } +} + +// Применить палитру к глобальным цветам интерфейса +static inline void ui_apply_theme(uint8_t i) { + if (i >= UI_THEME_COUNT) return; + const ColorTheme* t = &UI_THEMES[i]; + UIColor::window_bkg = t->window_bkg; + UIColor::title_bkg = t->title_bkg; + UIColor::title_txt = t->title_txt; + UIColor::primary_txt = t->primary_txt; + UIColor::secondary_txt = t->secondary_txt; + UIColor::warning_txt = t->warning_txt; + UIColor::popup_bkg = t->popup_bkg; + UIColor::popup_txt = t->popup_txt; + UIColor::corp_blue = t->corp_blue; +} diff --git a/src/helpers/ui/ST7735Display.cpp b/src/helpers/ui/ST7735Display.cpp index 9da841b7..ca356d92 100644 --- a/src/helpers/ui/ST7735Display.cpp +++ b/src/helpers/ui/ST7735Display.cpp @@ -1,4 +1,5 @@ #include "ST7735Display.h" +#include "ColorThemes.h" #ifdef OLED_RU #include "glcdfont6x8.h" #endif @@ -422,80 +423,36 @@ bool ST7735Display::i2c_probe(TwoWire& wire, uint8_t addr) { // Color scheme // -// Палитры вынесены в таблицу, поэтому тема переключается в рантайме (UIColor::* — -// обычные статические переменные, не const). Выбранная тема хранится в prefs по имени -// и применяется при старте; в меню ui-new есть страница THEME с живым предпросмотром. +// Палитры общие с ST7789LCDDisplay и лежат в src/helpers/ui/ColorThemes.h, поэтому +// тема переключается в рантайме (UIColor::* — обычные статические переменные, не const). +// Выбранная тема хранится в prefs по имени и применяется при старте; в меню ui-new +// есть страница THEME с живым предпросмотром. // // Тема по умолчанию зависит от платы: // - Heltec T096 — AMBER (графит + янтарь); // - остальные платы на этом драйвере (heltec_t1 / tracker / tracker_v2) — // официальная схема MeshCore (CLASSIC). // Флаг ST7735_THEME_* в platformio.ini варианта переопределяет этот дефолт. -// -// CLASSIC взята из upstream: github.com/meshcore-dev/MeshCore, ветка main, -// src/helpers/ui/ST7735Display.cpp — светлая схема (белый фон, чёрный текст). -// В форке она была перекрашена в тёмную вручную, здесь восстановлен оригинал. -#if (defined(ST7735_THEME_CLASSIC) + defined(ST7735_THEME_AMBER) + defined(ST7735_THEME_TEAL) + defined(ST7735_THEME_SIGNAL) + defined(ST7735_THEME_NEON)) > 1 - #error "ST7735Display: выбрана более чем одна тема ST7735_THEME_*" -#endif - -#define MC_CLASSIC_SECONDARY_TXT ((18 << 11) | (36 << 5) | 18) // mid-gray - -struct ColorTheme { - const char* name; - ColorVal window_bkg, title_bkg, title_txt, primary_txt, - secondary_txt, warning_txt, popup_bkg, popup_txt, corp_blue; -}; - -// Порядок в таблице = порядок в меню выбора темы. -// constexpr — чтобы палитра инициализировалась статически (иначе значения уехали бы -// в .bss и заполнялись динамической инициализацией C++). -static constexpr ColorTheme THEMES[] = { - { "amber", 0x1082, 0x2146, 0xF79E, 0xFFDF, 0x9493, 0xFD84, 0xFD84, 0x10A3, 0x551F }, // #101010 / #202830 / #FFB020 - { "teal", 0x0883, 0x1187, 0xEFDF, 0xF7DF, 0x8515, 0xFE4A, 0x1696, 0x0881, 0x45DF }, // #081018 / #103038 / #10D0B0 - { "signal", 0x0000, 0xEB07, 0x1082, 0xFFDF, 0x9D15, 0xFE8C, 0xFB46, 0x1082, 0x5D5F }, // #000000 / #E86038 / #FF6830 - { "neon", 0x0000, 0x0000, 0xEF5D, 0xFFFF, 0x8C52, 0xFEA0, 0x18C3, 0xFEA0, 0x555F }, // #000000 / #000000 / #FFD400 - { "classic", ST77XX_WHITE, ST77XX_BLUE, ST77XX_WHITE, ST77XX_BLACK, MC_CLASSIC_SECONDARY_TXT, - ST77XX_ORANGE, ST77XX_CYAN, ST77XX_BLACK, 0x001A }, // официальная светлая -}; -#define THEME_COUNT ((uint8_t)(sizeof(THEMES) / sizeof(THEMES[0]))) - -static constexpr uint8_t default_theme_index() { -#if defined(ST7735_THEME_CLASSIC) - return 4; -#elif defined(ST7735_THEME_TEAL) - return 1; -#elif defined(ST7735_THEME_SIGNAL) - return 2; -#elif defined(ST7735_THEME_NEON) - return 3; -#elif defined(ST7735_THEME_AMBER) || defined(HELTEC_T096) - return 0; -#else - return 4; // остальные платы: официальная схема MeshCore -#endif -} - -static constexpr uint8_t DEFAULT_THEME = default_theme_index(); +static constexpr uint8_t DEFAULT_THEME = ui_default_theme_index(); static uint8_t active_theme = DEFAULT_THEME; -ColorVal UIColor::window_bkg = THEMES[DEFAULT_THEME].window_bkg; -ColorVal UIColor::title_bkg = THEMES[DEFAULT_THEME].title_bkg; -ColorVal UIColor::title_txt = THEMES[DEFAULT_THEME].title_txt; -ColorVal UIColor::primary_txt = THEMES[DEFAULT_THEME].primary_txt; -ColorVal UIColor::secondary_txt = THEMES[DEFAULT_THEME].secondary_txt; -ColorVal UIColor::warning_txt = THEMES[DEFAULT_THEME].warning_txt; -ColorVal UIColor::popup_bkg = THEMES[DEFAULT_THEME].popup_bkg; -ColorVal UIColor::popup_txt = THEMES[DEFAULT_THEME].popup_txt; -ColorVal UIColor::corp_blue = THEMES[DEFAULT_THEME].corp_blue; +ColorVal UIColor::window_bkg = UI_THEMES[DEFAULT_THEME].window_bkg; +ColorVal UIColor::title_bkg = UI_THEMES[DEFAULT_THEME].title_bkg; +ColorVal UIColor::title_txt = UI_THEMES[DEFAULT_THEME].title_txt; +ColorVal UIColor::primary_txt = UI_THEMES[DEFAULT_THEME].primary_txt; +ColorVal UIColor::secondary_txt = UI_THEMES[DEFAULT_THEME].secondary_txt; +ColorVal UIColor::warning_txt = UI_THEMES[DEFAULT_THEME].warning_txt; +ColorVal UIColor::popup_bkg = UI_THEMES[DEFAULT_THEME].popup_bkg; +ColorVal UIColor::popup_txt = UI_THEMES[DEFAULT_THEME].popup_txt; +ColorVal UIColor::corp_blue = UI_THEMES[DEFAULT_THEME].corp_blue; uint8_t ST7735Display::getThemeCount() { - return THEME_COUNT; + return UI_THEME_COUNT; } const char* ST7735Display::getThemeName(uint8_t i) { - return i < THEME_COUNT ? THEMES[i].name : ""; + return ui_theme_name(i); } uint8_t ST7735Display::getTheme() { @@ -503,30 +460,13 @@ uint8_t ST7735Display::getTheme() { } void ST7735Display::setTheme(uint8_t i) { - if (i >= THEME_COUNT) return; - const ColorTheme* t = &THEMES[i]; - UIColor::window_bkg = t->window_bkg; - UIColor::title_bkg = t->title_bkg; - UIColor::title_txt = t->title_txt; - UIColor::primary_txt = t->primary_txt; - UIColor::secondary_txt = t->secondary_txt; - UIColor::warning_txt = t->warning_txt; - UIColor::popup_bkg = t->popup_bkg; - UIColor::popup_txt = t->popup_txt; - UIColor::corp_blue = t->corp_blue; + if (i >= UI_THEME_COUNT) return; + ui_apply_theme(i); active_theme = i; } ColorVal ST7735Display::getThemeColor(uint8_t theme, uint8_t role) { - if (theme >= THEME_COUNT) return 0; - const ColorTheme* t = &THEMES[theme]; - switch (role) { - case THEME_COLOR_WINDOW: return t->window_bkg; - case THEME_COLOR_TITLE: return t->title_bkg; - case THEME_COLOR_POPUP: return t->popup_bkg; - case THEME_COLOR_ACCENT: return t->warning_txt; - default: return t->primary_txt; - } + return ui_theme_color(theme, role); } bool ST7735Display::begin() { diff --git a/src/helpers/ui/ST7789LCDDisplay.cpp b/src/helpers/ui/ST7789LCDDisplay.cpp index e259a252..6239cae3 100644 --- a/src/helpers/ui/ST7789LCDDisplay.cpp +++ b/src/helpers/ui/ST7789LCDDisplay.cpp @@ -1,4 +1,5 @@ #include "ST7789LCDDisplay.h" +#include "ColorThemes.h" #ifdef OLED_RU #include "glcdfont6x8.h" #endif @@ -27,15 +28,44 @@ bool ST7789LCDDisplay::i2c_probe(TwoWire& wire, uint8_t addr) { } // Color scheme -ColorVal UIColor::window_bkg = ST77XX_WHITE; -ColorVal UIColor::title_bkg = ST77XX_BLUE; -ColorVal UIColor::title_txt = ST77XX_WHITE; -ColorVal UIColor::primary_txt = ST77XX_BLACK; -ColorVal UIColor::secondary_txt = (18 << 11) | (36 << 5) | 18; // mid-gray -ColorVal UIColor::warning_txt = ST77XX_ORANGE; -ColorVal UIColor::popup_bkg = ST77XX_CYAN; -ColorVal UIColor::popup_txt = ST77XX_BLACK; -ColorVal UIColor::corp_blue = 0x001A; +// +// Палитры общие с ST7735Display (src/helpers/ui/ColorThemes.h), поэтому тема +// переключается в рантайме и одинаково выглядит на обоих TFT-драйверах. +// Дефолт для этих плат (heltec_v4 / tdeck) — официальная светлая CLASSIC. +static constexpr uint8_t DEFAULT_THEME = ui_default_theme_index(); +static uint8_t active_theme = DEFAULT_THEME; + +ColorVal UIColor::window_bkg = UI_THEMES[DEFAULT_THEME].window_bkg; +ColorVal UIColor::title_bkg = UI_THEMES[DEFAULT_THEME].title_bkg; +ColorVal UIColor::title_txt = UI_THEMES[DEFAULT_THEME].title_txt; +ColorVal UIColor::primary_txt = UI_THEMES[DEFAULT_THEME].primary_txt; +ColorVal UIColor::secondary_txt = UI_THEMES[DEFAULT_THEME].secondary_txt; +ColorVal UIColor::warning_txt = UI_THEMES[DEFAULT_THEME].warning_txt; +ColorVal UIColor::popup_bkg = UI_THEMES[DEFAULT_THEME].popup_bkg; +ColorVal UIColor::popup_txt = UI_THEMES[DEFAULT_THEME].popup_txt; +ColorVal UIColor::corp_blue = UI_THEMES[DEFAULT_THEME].corp_blue; + +uint8_t ST7789LCDDisplay::getThemeCount() { + return UI_THEME_COUNT; +} + +const char* ST7789LCDDisplay::getThemeName(uint8_t i) { + return ui_theme_name(i); +} + +uint8_t ST7789LCDDisplay::getTheme() { + return active_theme; +} + +void ST7789LCDDisplay::setTheme(uint8_t i) { + if (i >= UI_THEME_COUNT) return; + ui_apply_theme(i); + active_theme = i; +} + +ColorVal ST7789LCDDisplay::getThemeColor(uint8_t theme, uint8_t role) { + return ui_theme_color(theme, role); +} bool ST7789LCDDisplay::begin() { if (!_isOn) { diff --git a/src/helpers/ui/ST7789LCDDisplay.h b/src/helpers/ui/ST7789LCDDisplay.h index 1adf9237..10b423a2 100644 --- a/src/helpers/ui/ST7789LCDDisplay.h +++ b/src/helpers/ui/ST7789LCDDisplay.h @@ -73,4 +73,11 @@ public: void drawXbm(int x, int y, const uint8_t* bits, int w, int h) override; uint16_t getTextWidth(const char* str) override; void endFrame() override; + + // Темы (палитры общие с ST7735Display — src/helpers/ui/ColorThemes.h) + uint8_t getThemeCount() override; + const char* getThemeName(uint8_t i) override; + uint8_t getTheme() override; + void setTheme(uint8_t i) override; + ColorVal getThemeColor(uint8_t theme, uint8_t role) override; };