From 3e69f3f05c1d6fa4ea2ae3f19603d74a459f4897 Mon Sep 17 00:00:00 2001 From: ekklesia Date: Fri, 4 Sep 2026 22:33:37 -0500 Subject: [PATCH] refactor: share the stylesheet renderer The DVD control bar has to look like the dock, which is best guaranteed by drawing it from the same template with the same measurements rather than by keeping two stylesheets in step by hand. Co-Authored-By: Claude Opus 5 --- lib/classroom_style.py | 35 +++++++++++++++++++++++++++++++++++ scripts/classroom-dock | 30 ++---------------------------- 2 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 lib/classroom_style.py diff --git a/lib/classroom_style.py b/lib/classroom_style.py new file mode 100644 index 0000000..b80199e --- /dev/null +++ b/lib/classroom_style.py @@ -0,0 +1,35 @@ +"""The classroom stylesheet, resolved at the room's UI scale. + +The dock and the DVD control bar share this so they cannot drift apart: +one template, one set of measurements, one look. +""" + +from pathlib import Path + +from classroom_config import scaled + +TEMPLATE = Path("/etc/ekklesia-classroom/dock/style.css.in") + +# Every measurement in the template, at UI_SCALE=1.0. +MEASUREMENTS = { + "dock-radius": 24, + "dock-padding-v": 8, + "dock-padding-h": 10, + "button-radius": 16, + "button-padding": 6, + "button-size": 44, + "clock-radius": 16, + "clock-padding-v": 7, + "clock-padding-h": 12, + "clock-font": 17, +} + + +def render(scale, template=None): + """Resolve the measurement tokens in the stylesheet template.""" + css = (template or TEMPLATE).read_text() + + for token, value in MEASUREMENTS.items(): + css = css.replace(f"@{token}@", str(scaled(value, scale))) + + return css diff --git a/scripts/classroom-dock b/scripts/classroom-dock index ed38524..6bf6723 100755 --- a/scripts/classroom-dock +++ b/scripts/classroom-dock @@ -14,6 +14,7 @@ from gi.repository import Gtk, Gdk, GdkPixbuf, GLib, GtkLayerShell sys.path.insert(0, "/usr/local/lib/ekklesia-classroom") +import classroom_style as style # noqa: E402 from classroom_config import ( # noqa: E402 enabled, read_device_config, @@ -30,7 +31,6 @@ except ImportError: optical = None -CSS_FILE = Path("/etc/ekklesia-classroom/dock/style.css.in") ICON_DIR = Path("/etc/ekklesia-classroom/icons") DVD_POLL_SECONDS = 2 @@ -358,39 +358,13 @@ class ClassroomShell(Gtk.Window): return True -def render_css(scale): - """Resolve the measurement tokens in the stylesheet template.""" - css = CSS_FILE.read_text() - - measurements = { - "dock-radius": 24, - "dock-padding-v": 8, - "dock-padding-h": 10, - "button-radius": 16, - "button-padding": 6, - "button-size": 44, - "clock-radius": 16, - "clock-padding-v": 7, - "clock-padding-h": 12, - "clock-font": 17, - } - - for token, value in measurements.items(): - css = css.replace( - f"@{token}@", - str(scaled(value, scale)), - ) - - return css - - def load_css(scale): # Styling is worth losing before the dock is. A stylesheet that will # not parse leaves an unstyled but working shell rather than no shell. try: provider = Gtk.CssProvider() provider.load_from_data( - render_css(scale).encode("utf-8") + style.render(scale).encode("utf-8") ) except (OSError, GLib.Error) as error: print(