From bf5ba3c304db79ac50a9f402b009e2111ad72603 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Tue, 4 Aug 2026 18:08:26 -0300 Subject: [PATCH] Add theme-aware colour helpers to the display core #### Proposed Changes #### A module that needs a dimmed or highlighted shade of the active theme has no way to ask for one. The only helper available, getColorVariation, steps brightness up or down and cannot mix toward another colour, so modules fall back to a fixed constant such as TFT_DARKGREY or TFT_WHITE. That is the root cause of most of the screens in Bruce that stop following the user's theme as soon as they need more than the primary colour. This adds two helpers next to it in core/display: blendColors(a, b, t) linear RGB565 mix; t = 0 keeps a, t = 255 keeps b buildHeatPalette(lut, n) fills a lookup table with a theme ramp running from the background up to a brightened primary, for waterfalls and other intensity plots Both are pure additions. No existing function is modified, and nothing calls them in this PR - the modules that consume them follow separately. #### Types of Changes #### New Feature (internal helper API). No behaviour change and no breaking change. #### Verification #### Nothing on screen changes from this PR alone, so verification is limited to confirming the build is clean and that only insertions were made: pio run -e m5stack-cardputer git show --stat # 2 files changed, 31 insertions(+), 0 deletions(-) #### Testing #### Bruce has no unit test harness covering the display layer, so this was verified by compiling for m5stack-cardputer on this branch. The helpers get exercised on hardware through the follow-up PRs that use them. #### Linked Issues #### None. This is the base commit of a series that standardises the spectrum-style screens; the module PRs listed below depend on it. #### User-Facing Change #### ```release-note NONE ``` #### Further Comments #### Prerequisite for ui/spectrum-view, ui/rf-waterfall-theme and ui/rf-spectrum-theme. --- src/core/display.cpp | 25 +++++++++++++++++++++++++ src/core/display.h | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/src/core/display.cpp b/src/core/display.cpp index 3b4f210ba..435ef1c18 100644 --- a/src/core/display.cpp +++ b/src/core/display.cpp @@ -1737,6 +1737,31 @@ uint16_t getColorVariation(uint16_t color, int delta, int direction) { return compl_color; } +uint16_t blendColors(uint16_t a, uint16_t b, uint8_t t) { + int ar = (a >> 11) & 0x1f, ag = (a >> 5) & 0x3f, ab = a & 0x1f; + int br = (b >> 11) & 0x1f, bg = (b >> 5) & 0x3f, bb = b & 0x1f; + int r = ar + (br - ar) * t / 255; + int g = ag + (bg - ag) * t / 255; + int bl = ab + (bb - ab) * t / 255; + return (uint16_t)((r << 11) | (g << 5) | bl); +} + +void buildHeatPalette(uint16_t *lut, uint8_t n) { + if (!lut || n < 2) return; + uint16_t bg = bruceConfig.bgColor; + uint16_t pri = bruceConfig.priColor; + uint16_t hot = blendColors(pri, TFT_WHITE, 150); + + lut[0] = bg; + for (uint8_t i = 1; i < n; i++) { + int t = i * 255 / (n - 1); + // ramp to the primary for the lower two thirds, then burn toward the + // highlight so strong signals stay readable against a busy plot + lut[i] = (t < 170) ? blendColors(bg, pri, 55 + t * 200 / 255) + : blendColors(pri, hot, (t - 170) * 255 / 85); + } +} + // Draw BITMAP files // These read 16- and 32-bit types from the SD card file. // BMP data is stored little-endian, Arduino is little-endian too. diff --git a/src/core/display.h b/src/core/display.h index 97c276e35..5d8c25669 100644 --- a/src/core/display.h +++ b/src/core/display.h @@ -107,6 +107,12 @@ bool showJpeg(const uint8_t *data_array, size_t data_size, int x, int y, bool ce uint16_t getComplementaryColor(uint16_t color); uint16_t getComplementaryColor2(uint16_t color); uint16_t getColorVariation(uint16_t color, int delta = 10, int direction = 0); +// Linear RGB565 mix: t = 0 returns a, t = 255 returns b. Use it to derive dim +// or highlighted shades from the theme instead of hardcoding TFT_* constants. +uint16_t blendColors(uint16_t a, uint16_t b, uint8_t t); +// Fills lut[0..n-1] with a theme ramp going from the background up to a +// brightened primary, for waterfalls and other intensity plots. +void buildHeatPalette(uint16_t *lut, uint8_t n); void resetTftDisplay( int x = 0, int y = 0, uint16_t fc = bruceConfig.priColor, int size = FM,