testsAndMisc/python_pkg/wallpaper_rotator/_palette.py
Krzysztof kuhy Rudnicki d502580e3f Dark wallpaper rotator: new style every 3 h
Six text-free styles (gradient, flow/Voronoi, habit heatmap, shutdown
clock, Earth day/night, plasma) replace the white i3 root. A 15-minute
systemd user timer picks a new random style per monitor every 3 hours,
unlike its previous one and the other monitor's; live styles refresh in
between. Also syncs i3/config with the live config and prunes the
oldest evidence artifact for the 60-file cap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWX51FMD58yKUC1eYWf
2026-11-11 16:31:06 +01:00

42 lines
1.2 KiB
Python

"""Dracula-family colours shared by every style (matches the i3bar)."""
from __future__ import annotations
from typing import TYPE_CHECKING
import numpy as np
if TYPE_CHECKING:
from numpy.typing import NDArray
Rgb = tuple[int, int, int]
DEEP: Rgb = (0x1A, 0x1B, 0x24)
BG: Rgb = (0x28, 0x2A, 0x36)
LINE: Rgb = (0x44, 0x47, 0x5A)
COMMENT: Rgb = (0x62, 0x72, 0xA4)
CYAN: Rgb = (0x8B, 0xE9, 0xFD)
GREEN: Rgb = (0x50, 0xFA, 0x7B)
ORANGE: Rgb = (0xFF, 0xB8, 0x6C)
PINK: Rgb = (0xFF, 0x79, 0xC6)
PURPLE: Rgb = (0xBD, 0x93, 0xF9)
RED: Rgb = (0xFF, 0x55, 0x55)
ACCENTS: tuple[Rgb, ...] = (CYAN, GREEN, ORANGE, PINK, PURPLE, RED)
def mix(a: Rgb, b: Rgb, t: float) -> Rgb:
"""Linear blend from ``a`` (t=0) to ``b`` (t=1)."""
return (
round(a[0] + (b[0] - a[0]) * t),
round(a[1] + (b[1] - a[1]) * t),
round(a[2] + (b[2] - a[2]) * t),
)
def ramp(t: NDArray[np.float64], stops: tuple[Rgb, ...]) -> NDArray[np.uint8]:
"""Map values in [0, 1] through evenly spaced colour stops to RGB."""
xs = np.linspace(0.0, 1.0, len(stops))
clipped = np.clip(t, 0.0, 1.0)
channels = [np.interp(clipped, xs, [stop[c] for stop in stops]) for c in range(3)]
return np.stack(channels, axis=-1).round().astype(np.uint8)