Introduces app/panel_style.py, a shared style module every render module now draws through instead of independently duplicating margins/ colors/fonts: Inter Bold/Regular (already vendored, previously only used by widgets/text.py) replace PIL's single-weight bundled default font everywhere else; a per-widget-kind accent color (calendar=blue, tasks=green, weather=black header) replaces plain black-on-white chrome and is centralized in one THEME mapping so a future global theme only needs to touch panel_style.py; a small per-widget gutter separates adjacent widgets without touching grid.py's cell math; header bars, color chips, and the battery icon get rounded corners. Also drops the MUTED gray text color used throughout calendar_render.py and weather_render.py -- a non-palette color that has no close match in the panel's 6-ink palette and dithers into visible speckle once the composited canvas is quantized. Secondary text now reads through size/ weight alone, always exact black. widgets/battery.py and manage_overlay.py's previously-duplicated battery-glyph-drawing code now share one implementation (panel_style. draw_battery_icon). widgets/_shared.py's placeholder image is fixed to use exact palette colors and route through image_pipeline.draw_text, same as everything else -- it was quietly violating both rules already. image_pipeline.draw_widget_border gains an opt-in radius param (default 0, unused by any call site) for a possible future rounded-border setting -- doesn't touch the exact-corner-pixel behavior test_widget_ border.py already pins. Deliberately out of scope: DEFAULT_PALETTE_RGB and the Floyd-Steinberg quantization pipeline are untouched, per the prior reverted measured- palette/OKLab attempt (05b417a/dfe9d701).
33 lines
1.1 KiB
Python
33 lines
1.1 KiB
Python
"""Tiny widget-region placeholder image, shared by every widget-type
|
|
module for the "not configured yet" / "temporarily unavailable" case --
|
|
deliberately much simpler than image_pipeline.render_placeholder (no QR
|
|
code, no full-panel-scale fonts): a widget's own region can be a small
|
|
fraction of the panel, so its placeholder needs to scale down with it.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from PIL import Image, ImageDraw
|
|
|
|
from .. import panel_style
|
|
from ..image_pipeline import draw_text
|
|
|
|
_BG = (255, 255, 255)
|
|
|
|
|
|
def placeholder_image(target_w: int, target_h: int, lines: list[str]) -> Image.Image:
|
|
img = Image.new("RGB", (target_w, target_h), _BG)
|
|
draw = ImageDraw.Draw(img)
|
|
font_size = max(10, min(20, target_h // 8))
|
|
font = panel_style.font_regular(font_size)
|
|
line_h = font_size + 4
|
|
total_h = line_h * len(lines)
|
|
y = max(4, (target_h - total_h) // 2)
|
|
for line in lines:
|
|
bbox = draw.textbbox((0, 0), line, font=font)
|
|
line_w = bbox[2] - bbox[0]
|
|
x = max(4, (target_w - line_w) // 2)
|
|
draw_text(img, (x, y), line, font)
|
|
y += line_h
|
|
return img
|