Add a per-widget text-size picker for calendar/tasks legibility
Build and push server image / test (push) Successful in 42s
Build and push server image / build-and-push (push) Successful in 3m33s
Build and push server image / deploy (push) Failing after 1m24s

Calendar and tasks pack the most body text at the smallest default
sizes, so those two gear-icon dialogs get a "Text size" card (Normal/
Large/X-Large) alongside the existing Border card -- a new Widget-level
font_scale column with its own POST .../font-scale endpoint, same
Widget-property-not-config-field shape as border_style. Threaded through
every classic (calendar_render.py) and modern (html_render.py/
calendar_html_render.py) size calc via one shared panel_style.
scaled_size() so row heights/max_rows already derived from font size
re-fit around the bigger text automatically.
This commit is contained in:
2026-08-02 03:23:27 +00:00
parent 09119e775f
commit 2868087467
22 changed files with 426 additions and 60 deletions
+22
View File
@@ -36,6 +36,28 @@ CONTENT_MARGIN = 20
CARD_RADIUS = 12
CHIP_RADIUS = 4
# models.Widget.font_scale's allowed values -- a per-widget text-size
# multiplier (the Layout dialog's "Text size" picker), same "reject
# invalid, don't silently coerce" posture as border_style. Deliberately a
# small fixed set (a <select>, not a raw slider) rather than an arbitrary
# float: every _AGENDA_FONTS/_TASKS_FONTS-style tuple in calendar_render.py
# and every proportional size in html_render.py/calendar_html_render.py
# derives row heights/max_rows from the same scaled font size, so an
# unbounded scale risks a layout that no longer fits its own box.
FONT_SCALE_CHOICES = (1.0, 1.25, 1.5)
def scaled_size(value: float, font_scale: float) -> int:
"""Applies a widget's font_scale to a text-size value and rounds to
an int px, floored at 1 so an extreme scale can never zero out a
font. Shared by both the classic (PIL, calendar_render.py) and modern
(HTML/CSS, html_render.py/calendar_html_render.py) renderers so "make
this widget's text bigger" behaves identically regardless of
render_style -- every caller applies this immediately after its own
tier lookup/floor calc, so row heights/max_rows computed from the
result already account for the bigger text."""
return max(1, round(value * font_scale))
# Index constants into DEFAULT_PALETTE_RGB/a frame's own Frame.
# palette_rgb override -- same order as image_pipeline.PALETTE_LABELS.
BLACK, WHITE, YELLOW, RED, BLUE, GREEN = range(6)