Themes: add 'Pride' rainbow-background preset
The theme system stores one flat background colour per element, so a rainbow background can't be expressed as a preset alone. Add a small display hook: when Pride is selected, displayClearBuf()/displayClearRows() paint the six pride-flag stripes across the framebuffer instead of a flat fill (gated on a flag only the Pride preset sets, and behind HAS_COLOURS so mono builds are untouched). Non-selected menu rows draw text straight over the canvas, while the title/header/notifications paint solid white boxes, so chrome stays readable over the stripes; blue/violet are lightened slightly for black-text contrast. Docs and changelog updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5efd14d8b7
commit
3ec4eafbc9
6 changed files with 77 additions and 6 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -7,10 +7,15 @@ single running list until the first versioned release.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
- **Two new theme presets** (Display Options → "Theme"): **Red** (black-on-red
|
- **Three new theme presets** (Display Options → "Theme"): **Red** (black-on-red
|
||||||
day / red-on-black night) and **Neon 80s**, an 80s-synthwave palette that maps
|
day / red-on-black night); **Neon 80s**, an 80s-synthwave palette that maps
|
||||||
several neon colours (cyan, magenta, violet, green, yellow) across the
|
several neon colours (cyan, magenta, violet, green, yellow) across the
|
||||||
individual UI elements over a dark background.
|
individual UI elements over a dark background; and **Pride**, which paints the
|
||||||
|
background as a rainbow pride flag with black text and white menu/header boxes
|
||||||
|
kept readable over the stripes.
|
||||||
|
- **Build:** each build now prints a per-region memory-usage summary
|
||||||
|
(FLASH / RAM / CCMRAM used, size and free) so the remaining headroom is
|
||||||
|
visible after every build.
|
||||||
|
|
||||||
## 0.7.1
|
## 0.7.1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,11 @@ Pick a colour theme on the radio at **Menu → Options → Display Options → "
|
||||||
- **Red** — black-on-red by day, red-on-black at night.
|
- **Red** — black-on-red by day, red-on-black at night.
|
||||||
- **Neon 80s** — an 80s-synthwave palette with several neon colours (cyan,
|
- **Neon 80s** — an 80s-synthwave palette with several neon colours (cyan,
|
||||||
magenta, violet, green, yellow) across the UI over a dark background.
|
magenta, violet, green, yellow) across the UI over a dark background.
|
||||||
|
- **Pride** — the background is painted as a rainbow pride flag; body text is
|
||||||
|
black over the stripes, and the menu title, header and notifications use white
|
||||||
|
boxes so they stay readable. (Text drawn directly over the brightest stripes
|
||||||
|
has lower contrast than a solid-background theme — that's inherent to a
|
||||||
|
rainbow background.)
|
||||||
|
|
||||||
Editing colours in the CPS only affects **Custom**; the built-in presets are
|
Editing colours in the CPS only affects **Custom**; the built-in presets are
|
||||||
fixed. Every element (S-meter, frequencies, menus) follows the selected theme.
|
fixed. Every element (S-meter, frequencies, menus) follows the selected theme.
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,7 @@ typedef enum
|
||||||
THEME_PRESET_VERTEXIC, // amber/orange (black-on-amber day / amber-on-black night)
|
THEME_PRESET_VERTEXIC, // amber/orange (black-on-amber day / amber-on-black night)
|
||||||
THEME_PRESET_RED, // red (black-on-red day / red-on-black night)
|
THEME_PRESET_RED, // red (black-on-red day / red-on-black night)
|
||||||
THEME_PRESET_NEON80S, // 80s synthwave: cyan/magenta/violet/green neon on dark
|
THEME_PRESET_NEON80S, // 80s synthwave: cyan/magenta/violet/green neon on dark
|
||||||
|
THEME_PRESET_PRIDE, // pride flag: black text + white chrome over a rainbow background
|
||||||
NUM_THEME_PRESETS
|
NUM_THEME_PRESETS
|
||||||
} themePreset_t;
|
} themePreset_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,21 @@ static uint16_t backgroundColour = 0xFFFFU;
|
||||||
|
|
||||||
static uint16_t screenBufData[DISPLAY_SIZE_X * DISPLAY_SIZE_Y];
|
static uint16_t screenBufData[DISPLAY_SIZE_X * DISPLAY_SIZE_Y];
|
||||||
uint16_t *screenBuf = screenBufData;
|
uint16_t *screenBuf = screenBufData;
|
||||||
|
|
||||||
|
#if defined(HAS_COLOURS)
|
||||||
|
// When the Pride theme is active the background canvas is painted as six
|
||||||
|
// horizontal rainbow stripes instead of a single flat colour.
|
||||||
|
static bool prideBackgroundActive = false;
|
||||||
|
static uint16_t prideStripes[6];
|
||||||
|
|
||||||
|
// Pride stripe colour for a linear screen-buffer index (row = index / width).
|
||||||
|
static inline uint16_t pridePixelColour(int index)
|
||||||
|
{
|
||||||
|
int band = ((index / DISPLAY_SIZE_X) * 6) / DISPLAY_SIZE_Y;
|
||||||
|
|
||||||
|
return prideStripes[(band < 0) ? 0 : ((band > 5) ? 5 : band)];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
//#define DISPLAY_CHECK_BOUNDS
|
//#define DISPLAY_CHECK_BOUNDS
|
||||||
|
|
||||||
#ifdef DISPLAY_CHECK_BOUNDS
|
#ifdef DISPLAY_CHECK_BOUNDS
|
||||||
|
|
@ -326,6 +341,16 @@ int displayPrintCoreDoubleHeight(int16_t xPos, int16_t yPos, const char *szMsg,
|
||||||
|
|
||||||
void displayClearBuf(void)
|
void displayClearBuf(void)
|
||||||
{
|
{
|
||||||
|
#if defined(HAS_COLOURS)
|
||||||
|
if (prideBackgroundActive)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < DISPLAY_SIZE_X * DISPLAY_SIZE_Y; i++)
|
||||||
|
{
|
||||||
|
screenBuf[i] = pridePixelColour(i);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// may be able to do this using DMA
|
// may be able to do this using DMA
|
||||||
for(int i = 0; i < DISPLAY_SIZE_X * DISPLAY_SIZE_Y; i++)
|
for(int i = 0; i < DISPLAY_SIZE_X * DISPLAY_SIZE_Y; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -353,7 +378,11 @@ void displayClearRows(int16_t startRow, int16_t endRow, bool isInverted)
|
||||||
|
|
||||||
for(int i = startRow; i < endRow; i++)
|
for(int i = startRow; i < endRow; i++)
|
||||||
{
|
{
|
||||||
|
#if defined(HAS_COLOURS)
|
||||||
|
screenBuf[i] = ((prideBackgroundActive && (isInverted == false)) ? pridePixelColour(i) : fillColour);
|
||||||
|
#else
|
||||||
screenBuf[i] = fillColour;
|
screenBuf[i] = fillColour;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1584,12 +1613,27 @@ static void themeSetNeon80s(DayTime_t daytime, uint32_t bg)
|
||||||
themeSetItem(daytime, THEME_ITEM_FG_BD_COLOUR, orange);
|
themeSetItem(daytime, THEME_ITEM_FG_BD_COLOUR, orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pride: the background canvas is painted as a rainbow (see pridePixelColour);
|
||||||
|
// the theme items only need black text plus white "chrome" boxes (menu title,
|
||||||
|
// header, notifications) so those stay readable over any stripe. The selected
|
||||||
|
// menu row already inverts to a black bar with white text.
|
||||||
|
static void themeSetPride(DayTime_t daytime)
|
||||||
|
{
|
||||||
|
themeSetAllItems(daytime, 0x000000, 0xFFFFFF); // black text, white chrome backgrounds
|
||||||
|
|
||||||
|
// Keep warning/error notifications colour-coded on their white box.
|
||||||
|
themeSetItem(daytime, THEME_ITEM_FG_WARNING_NOTIFICATION, 0xC07800);
|
||||||
|
themeSetItem(daytime, THEME_ITEM_FG_ERROR_NOTIFICATION, 0xC00000);
|
||||||
|
}
|
||||||
|
|
||||||
void themeApplyPreset(uint8_t preset)
|
void themeApplyPreset(uint8_t preset)
|
||||||
{
|
{
|
||||||
// Start from the monochrome defaults, then overlay the chosen preset.
|
// Start from the monochrome defaults, then overlay the chosen preset.
|
||||||
themeInitToDefaultValues(NIGHT, true);
|
themeInitToDefaultValues(NIGHT, true);
|
||||||
themeInitToDefaultValues(DAY, false);
|
themeInitToDefaultValues(DAY, false);
|
||||||
|
|
||||||
|
prideBackgroundActive = false; // only the Pride preset re-enables the rainbow canvas
|
||||||
|
|
||||||
switch (preset)
|
switch (preset)
|
||||||
{
|
{
|
||||||
case THEME_PRESET_BASIC80S: // Commodore 64 BASIC: light blue on blue (day & night)
|
case THEME_PRESET_BASIC80S: // Commodore 64 BASIC: light blue on blue (day & night)
|
||||||
|
|
@ -1617,6 +1661,22 @@ void themeApplyPreset(uint8_t preset)
|
||||||
themeSetNeon80s(NIGHT, 0x08040F); // near-black purple
|
themeSetNeon80s(NIGHT, 0x08040F); // near-black purple
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case THEME_PRESET_PRIDE: // rainbow background canvas
|
||||||
|
{
|
||||||
|
// Classic 6-stripe pride flag; blue/violet lightened a little so
|
||||||
|
// black text stays legible over the lower stripes.
|
||||||
|
static const uint32_t prideRGB[6] = { 0xE40303, 0xFF8C00, 0xFFED00, 0x22A93F, 0x3D7DF0, 0xB05CD6 };
|
||||||
|
|
||||||
|
for (int s = 0; s < 6; s++)
|
||||||
|
{
|
||||||
|
prideStripes[s] = PLATFORM_COLOUR_FORMAT_SWAP_BYTES(RGB888_TO_PLATFORM_COLOUR_FORMAT(prideRGB[s]));
|
||||||
|
}
|
||||||
|
prideBackgroundActive = true;
|
||||||
|
themeSetPride(DAY);
|
||||||
|
themeSetPride(NIGHT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case THEME_PRESET_CUSTOM:
|
case THEME_PRESET_CUSTOM:
|
||||||
default:
|
default:
|
||||||
// Overlay the user's Custom theme from the codeplug, if present (CPS edits
|
// Overlay the user's Custom theme from the codeplug, if present (CPS edits
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ static void updateScreen(bool isFirstRun)
|
||||||
case DISPLAY_THEME_PRESET:
|
case DISPLAY_THEME_PRESET:
|
||||||
{
|
{
|
||||||
// Preset names are plain literals -> rightSideVar (voice-safe).
|
// Preset names are plain literals -> rightSideVar (voice-safe).
|
||||||
const char *presetNames[] = { "Custom", "BASIC 80s", "Terminal", "Vertexic", "Red", "Neon 80s" };
|
const char *presetNames[] = { "Custom", "BASIC 80s", "Terminal", "Vertexic", "Red", "Neon 80s", "Pride" };
|
||||||
uint8_t p = themeGetPreset();
|
uint8_t p = themeGetPreset();
|
||||||
leftSide = "Theme";
|
leftSide = "Theme";
|
||||||
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", presetNames[(p < NUM_THEME_PRESETS) ? p : 0]);
|
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", presetNames[(p < NUM_THEME_PRESETS) ? p : 0]);
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ FreeTRX keeps OpenGD77's core (DMR/FM, hotspot, CPS compatibility) and adds:
|
||||||
incoming-message popup (see the manual for details).
|
incoming-message popup (see the manual for details).
|
||||||
- **Theme presets** — pick a colour theme on the radio: **Custom** (CPS-editable,
|
- **Theme presets** — pick a colour theme on the radio: **Custom** (CPS-editable,
|
||||||
default), **BASIC 80s** (Commodore 64), **Terminal** (green-on-black),
|
default), **BASIC 80s** (Commodore 64), **Terminal** (green-on-black),
|
||||||
**Vertexic** (amber/orange), **Red**, or **Neon 80s** (multi-colour synthwave).
|
**Vertexic** (amber/orange), **Red**, **Neon 80s** (multi-colour synthwave),
|
||||||
CPS edits only affect Custom.
|
or **Pride** (rainbow background). CPS edits only affect Custom.
|
||||||
- **On-radio channel management** — create and delete channels directly from the
|
- **On-radio channel management** — create and delete channels directly from the
|
||||||
Channel quick menu, no PC/CPS required (see [Managing channels](#managing-channels-on-the-radio)).
|
Channel quick menu, no PC/CPS required (see [Managing channels](#managing-channels-on-the-radio)).
|
||||||
- **DMR reliability fix** — resolves a hard-fault (freeze needing a battery pull)
|
- **DMR reliability fix** — resolves a hard-fault (freeze needing a battery pull)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue