"""The colour palettes everything in the UI draws from. Every colour in Beefy Player is a stock ANSI palette *name*, never RGB, so the TUI adopts whatever colours the terminal is configured with. A palette here is therefore a short ladder of those names — the "gradient" is a quantised walk from the quiet end to the hot end, not an interpolation. The active palette drives the spectrum analyser, the album-art mosaic, the provider wordmarks and the pane corners; `c` cycles through them and the choice is remembered in the config file. """ from __future__ import annotations #: Dark → hot ladders of ANSI names. Sixteen of them: seven hue gradients, a #: few near-monochromes, and the original spectrum. PALETTES: dict[str, tuple[str, ...]] = { "spectrum": ( "cyan", "blue", "magenta", "bright_magenta", "yellow", "bright_yellow", "red", ), "rainbow": ( "red", "bright_yellow", "bright_green", "bright_cyan", "bright_blue", "bright_magenta", ), "ocean": ( "bright_black", "blue", "bright_blue", "cyan", "bright_cyan", "bright_white", ), "ember": ( "bright_black", "red", "bright_red", "yellow", "bright_yellow", "bright_white", ), "mint": ( "bright_black", "green", "bright_green", "cyan", "bright_cyan", "bright_white", ), "sunset": ("magenta", "bright_magenta", "red", "bright_red", "yellow"), "violet": ("blue", "bright_blue", "magenta", "bright_magenta", "bright_white"), "acid": ("bright_black", "green", "bright_green", "yellow", "bright_yellow"), "neon": ( "bright_magenta", "bright_red", "bright_yellow", "bright_green", "bright_cyan", ), "sand": ("bright_black", "yellow", "bright_yellow", "white", "bright_white"), "blood": ("bright_black", "red", "bright_red", "bright_magenta"), "forest": ("bright_black", "green", "bright_green", "yellow", "bright_white"), "ice": ("bright_white", "bright_cyan", "cyan", "bright_blue", "blue"), "steel": ("bright_black", "white", "bright_white", "bright_cyan"), "candy": ("magenta", "bright_magenta", "bright_cyan", "bright_yellow"), "mono": ("bright_black", "white", "bright_white"), } #: The stock names from dark to bright. These are xterm's default values in #: Rec. 601 luma order — the closest thing to a stock answer. A theme may #: disagree about the exact numbers, but the ordering is what the frame fades #: need: a ladder is a *hue* walk, so where it ends says nothing about which #: end is brighter. BRIGHTNESS: tuple[str, ...] = ( "black", "blue", "red", "bright_red", "magenta", "bright_magenta", "bright_blue", "green", "bright_black", "cyan", "bright_green", "bright_cyan", "yellow", "white", "bright_yellow", "bright_white", ) _RANK = {name: rank for rank, name in enumerate(BRIGHTNESS)} #: Cycle order for the palette key. PALETTE_ORDER: tuple[str, ...] = tuple(PALETTES) #: What you get until you press `c`. DEFAULT_PALETTE = "spectrum" def palette_stops(name: str | None) -> tuple[str, ...]: """The ladder for ``name``, falling back to the default palette.""" key = (name or "").strip().lower() return PALETTES.get(key, PALETTES[DEFAULT_PALETTE]) def brightness(colour: str) -> int: """How bright a stock name is: 0 (black) to 15 (bright white).""" return _RANK.get(colour.strip().lower(), 0)