Compare commits

...

2 commits

Author SHA1 Message Date
Marcus Kida
3fe33b931d Release 0.8.0
New colour theme presets (Red, Neon 80s, and the rainbow-background Pride),
plus a per-region memory-usage summary printed after every build.

Bump version to 0.8.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:48:17 +02:00
Marcus Kida
3ec4eafbc9 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>
2026-07-14 14:47:45 +02:00
7 changed files with 84 additions and 9 deletions

View file

@ -7,10 +7,19 @@ single running list until the first versioned release.
## Unreleased
- **Two new theme presets** (Display Options → "Theme"): **Red** (black-on-red
day / red-on-black night) and **Neon 80s**, an 80s-synthwave palette that maps
_Nothing yet._
## 0.8.0
- **Three new theme presets** (Display Options → "Theme"): **Red** (black-on-red
day / red-on-black night); **Neon 80s**, an 80s-synthwave palette that maps
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

View file

@ -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.
- **Neon 80s** — an 80s-synthwave palette with several neon colours (cyan,
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
fixed. Every element (S-meter, frequencies, menus) follows the selected theme.

View file

@ -5,9 +5,9 @@
#define _FREETRX_VERSION_H_
#define FREETRX_VERSION_MAJOR 0
#define FREETRX_VERSION_MINOR 7
#define FREETRX_VERSION_PATCH 1
#define FREETRX_VERSION_MINOR 8
#define FREETRX_VERSION_PATCH 0
#define FREETRX_VERSION "0.7.1"
#define FREETRX_VERSION "0.8.0"
#endif // _FREETRX_VERSION_H_

View file

@ -279,6 +279,7 @@ typedef enum
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_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
} themePreset_t;

View file

@ -67,6 +67,21 @@ static uint16_t backgroundColour = 0xFFFFU;
static uint16_t screenBufData[DISPLAY_SIZE_X * DISPLAY_SIZE_Y];
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
#ifdef DISPLAY_CHECK_BOUNDS
@ -326,6 +341,16 @@ int displayPrintCoreDoubleHeight(int16_t xPos, int16_t yPos, const char *szMsg,
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
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++)
{
#if defined(HAS_COLOURS)
screenBuf[i] = ((prideBackgroundActive && (isInverted == false)) ? pridePixelColour(i) : fillColour);
#else
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);
}
// 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)
{
// Start from the monochrome defaults, then overlay the chosen preset.
themeInitToDefaultValues(NIGHT, true);
themeInitToDefaultValues(DAY, false);
prideBackgroundActive = false; // only the Pride preset re-enables the rainbow canvas
switch (preset)
{
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
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:
default:
// Overlay the user's Custom theme from the codeplug, if present (CPS edits

View file

@ -276,7 +276,7 @@ static void updateScreen(bool isFirstRun)
case DISPLAY_THEME_PRESET:
{
// 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();
leftSide = "Theme";
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", presetNames[(p < NUM_THEME_PRESETS) ? p : 0]);

View file

@ -41,8 +41,8 @@ FreeTRX keeps OpenGD77's core (DMR/FM, hotspot, CPS compatibility) and adds:
incoming-message popup (see the manual for details).
- **Theme presets** — pick a colour theme on the radio: **Custom** (CPS-editable,
default), **BASIC 80s** (Commodore 64), **Terminal** (green-on-black),
**Vertexic** (amber/orange), **Red**, or **Neon 80s** (multi-colour synthwave).
CPS edits only affect Custom.
**Vertexic** (amber/orange), **Red**, **Neon 80s** (multi-colour synthwave),
or **Pride** (rainbow background). CPS edits only affect Custom.
- **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)).
- **DMR reliability fix** — resolves a hard-fault (freeze needing a battery pull)