Public Access
Settings > Theme and Settings > Light or dark pick the colours of every screen (issue #10): roro9stack (the website's, the default), Catppuccin, Dracula, Nord, ANSI terminal, Gruvbox and Solarized. - A palette is 14 roles (lib/ui/src/palette.h). theme::kText and the others are now references into the one in use, so the Apps are unchanged; the main loop applies it when a Setting changes. - Every colour is one the RGB332 frame buffer holds exactly: the themes' own were rounded, and those that fell together or lost contrast were picked by hand. test_palette checks exactness and 18 contrast ratios for each palette. - The Sky view's constellation colours come from the theme. - `theme [0-6] [light|dark]` on the consoles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
60 lines
4.3 KiB
C++
60 lines
4.3 KiB
C++
#include "palette.h"
|
|
|
|
namespace roro::ui {
|
|
|
|
namespace {
|
|
// 0xRRGGBB to RGB565. Every colour below is one the RGB332 frame buffer holds exactly: three bits
|
|
// of red and of green (00 24 49 6d 92 b6 db ff) and two of blue (00 55 aa ff). The themes' own
|
|
// colours were rounded to those, then the ones that fell together or lost their contrast were
|
|
// chosen by hand (test_palette checks both).
|
|
constexpr uint16_t c(uint32_t rgb) {
|
|
return static_cast<uint16_t>(((rgb >> 19) & 0x1F) << 11 | ((rgb >> 10) & 0x3F) << 5 | ((rgb >> 3) & 0x1F));
|
|
}
|
|
|
|
const char* const kNames[kThemeCount] = {"roro9stack", "Catppuccin", "Dracula", "Nord", "ANSI terminal", "Gruvbox", "Solarized"};
|
|
|
|
// background, text, muted, faint, bar, barMuted, accent, onAccent, warning, message, good, red, yellow, violet
|
|
constexpr Palette kPalettes[kThemeCount][2] = {
|
|
{
|
|
{c(0x000000), c(0xffffff), c(0x9292aa), c(0x494955), c(0x494955), c(0xb6b6aa), c(0x00dbff), c(0x000055), c(0xff9200), c(0xff92ff), c(0x49db55), c(0xff2455), c(0xffdb00), c(0xb692ff)}, // roro9stack, dark
|
|
{c(0xffffff), c(0x000055), c(0x4949aa), c(0xb6dbff), c(0xb6dbff), c(0x4949aa), c(0x0092aa), c(0xffffff), c(0xb64900), c(0xb600aa), c(0x006d00), c(0xb60000), c(0x926d00), c(0x6d49ff)}, // roro9stack, light
|
|
},
|
|
{
|
|
{c(0x000000), c(0xdbdbff), c(0x9292ff), c(0x494955), c(0x242455), c(0xb6b6ff), c(0xdbb6ff), c(0x000000), c(0xffb655), c(0xff92ff), c(0x92ffaa), c(0xff6daa), c(0xffdb55), c(0x6db6ff)}, // Catppuccin, dark
|
|
{c(0xffffff), c(0x242455), c(0x6d6daa), c(0xb6b6aa), c(0xb6b6aa), c(0x494955), c(0x9249ff), c(0xffffff), c(0xdb6d00), c(0xdb6daa), c(0x499255), c(0xdb0055), c(0xdb9200), c(0x246dff)}, // Catppuccin, light
|
|
},
|
|
{
|
|
{c(0x242455), c(0xffffff), c(0x6d6daa), c(0x494955), c(0x494955), c(0xb6b6aa), c(0xb692ff), c(0x242455), c(0xffb655), c(0xff6daa), c(0x49ff55), c(0xff4955), c(0xffffaa), c(0x92dbff)}, // Dracula, dark
|
|
{c(0xffffff), c(0x242400), c(0x6d6d55), c(0xdbdbff), c(0xdbdbff), c(0x6d6d55), c(0x6d49aa), c(0xffffff), c(0x924900), c(0x922455), c(0x246d00), c(0xdb4900), c(0x926d00), c(0x006daa)}, // Dracula, light
|
|
},
|
|
{
|
|
{c(0x242455), c(0xdbffff), c(0x9292aa), c(0x494955), c(0x494955), c(0xdbdbff), c(0x92dbff), c(0x242455), c(0xdb9255), c(0xb692aa), c(0x92b6aa), c(0xb66d55), c(0xdbdbaa), c(0x9292aa)}, // Nord, dark
|
|
{c(0xdbffff), c(0x242455), c(0x494955), c(0xdbdbff), c(0xdbdbff), c(0x494955), c(0x496daa), c(0xdbffff), c(0xb64900), c(0x9249aa), c(0x496d00), c(0xb66d55), c(0xb66d00), c(0x9292aa)}, // Nord, light
|
|
},
|
|
{
|
|
{c(0x000000), c(0xb6b6aa), c(0x6d6d55), c(0x494955), c(0x0000aa), c(0xb6b6aa), c(0x49ff55), c(0x000000), c(0xffff55), c(0xff49ff), c(0x49ffff), c(0xff4955), c(0xffff55), c(0x4949ff)}, // ANSI terminal, dark
|
|
{c(0xffffff), c(0x000000), c(0x494955), c(0xb6b6aa), c(0xb6b6aa), c(0x494955), c(0x0000aa), c(0xffffff), c(0xb64900), c(0xb600aa), c(0x006d00), c(0xb60000), c(0xb64900), c(0x00b6aa)}, // ANSI terminal, light
|
|
},
|
|
{
|
|
{c(0x242400), c(0xdbdbaa), c(0x929255), c(0x492400), c(0x492400), c(0xdbb6aa), c(0xffb655), c(0x242400), c(0xff9200), c(0xdb92aa), c(0xb6b600), c(0xff4955), c(0xffb655), c(0x92b6aa)}, // Gruvbox, dark
|
|
{c(0xffffaa), c(0x494955), c(0x6d6d55), c(0xdbdbaa), c(0xdbdbaa), c(0x494955), c(0xb64900), c(0xffffaa), c(0xb66d00), c(0x924955), c(0x6d6d00), c(0x920000), c(0xb66d00), c(0x006d55)}, // Gruvbox, light
|
|
},
|
|
{
|
|
{c(0x002455), c(0xb6b6aa), c(0x6d92aa), c(0x004955), c(0x004955), c(0x9292aa), c(0x2492aa), c(0xffffff), c(0xdb4900), c(0xdb24aa), c(0x929200), c(0xdb2455), c(0xb69200), c(0x6d6daa)}, // Solarized, dark
|
|
{c(0xffffff), c(0x244955), c(0x9292aa), c(0xdbdbaa), c(0xdbdbaa), c(0x6d6daa), c(0x2492aa), c(0xffffff), c(0xdb4900), c(0xdb24aa), c(0x929200), c(0xdb2455), c(0xb69200), c(0x6d6daa)}, // Solarized, light
|
|
},
|
|
};
|
|
} // namespace
|
|
|
|
const char* themeName(int theme) { return kNames[theme < 0 || theme >= kThemeCount ? 0 : theme]; }
|
|
|
|
const Palette& palette(int theme, bool light) { return kPalettes[theme < 0 || theme >= kThemeCount ? 0 : theme][light ? 1 : 0]; }
|
|
|
|
uint32_t rgb888(uint16_t c) {
|
|
// As the display shows an RGB332 pixel: the bits kept, spread over 8.
|
|
uint32_t r = ((c >> 13) & 7) * 0x49 >> 1, g = ((c >> 8) & 7) * 0x49 >> 1, b = ((c >> 3) & 3) * 0x55;
|
|
return r << 16 | g << 8 | b;
|
|
}
|
|
|
|
} // namespace roro::ui
|