Files
taninux/scripts/demo/ui_demo.py
T
karim 774809a579 chore(repo): stop tracking build artifacts; add README, license metadata, ruff config
Untrack iso/out/ (3.4 GB ISO), packaging/*/pkg/ trees, *.pkg.tar.zst and
tanin-icons/src/ (529 files) and ignore them going forward. Files stay on
disk. NOTE: history still carries ~13 GiB of old ISO blobs — needs a
git filter-repo pass (see README/report).

Also: first README.md, license + license-files in pyproject, minimal ruff
config, demo scripts moved to scripts/demo/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 21:21:28 +02:00

162 lines
4.8 KiB
Python

#!/usr/bin/env python3
"""Visuelle Demo der nativen ui.* -Widgets (Apple-Optik, libadwaita-frei).
PYTHONPATH=src python ui_demo.py # hell
PYTHONPATH=src python ui_demo.py --dark # dunkel
Baut bewusst dieselben Zeilen-Typen nach, die maintain.py / defaultapps.py über
Adw nutzen (Titel/Untertitel, Prefix-Icon, farbiger Punkt, Switch, Dropdown,
flat-Buttons) — damit der Schnitt 1:1 vergleichbar ist.
"""
from __future__ import annotations
import subprocess
import sys
import gi
gi.require_version("Gtk", "4.0")
from gi.repository import GLib, Gtk # noqa: E402
from taninux.gui.ui import native as ui # noqa: E402
DARK = "--dark" in sys.argv
SHOT = next((a for a in sys.argv if a.startswith("--shot=")), None)
SHOT = SHOT.split("=", 1)[1] if SHOT else None
TOGGLE = next((a for a in sys.argv if a.startswith("--toggle=")), None)
TOGGLE = TOGGLE.split("=", 1)[1] if TOGGLE else None
def _dot(css_class: str) -> Gtk.Label:
dot = Gtk.Label(label="")
dot.add_css_class(css_class)
dot.set_valign(Gtk.Align.CENTER)
return dot
def _flat(label: str, destructive: bool = False) -> Gtk.Button:
btn = Gtk.Button(label=label)
btn.add_css_class("flat")
if destructive:
btn.add_css_class("destructive-action")
btn.set_valign(Gtk.Align.CENTER)
return btn
def build_page() -> ui.Page:
page = ui.Page()
# --- Gruppe 1: Cleanup-Summary (wie maintain.py) ---------------------
g1 = ui.Group(title="Cleanup")
rescan = Gtk.Button(icon_name="view-refresh-symbolic")
rescan.add_css_class("flat")
rescan.set_valign(Gtk.Align.CENTER)
g1.set_header_suffix(rescan)
r = ui.Row(title="Reclaimable", subtitle="2.4 GiB can be reclaimed safely")
r.add_prefix(_dot("success"))
g1.add(r)
legend = ui.Row(title="Legend")
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=14)
for cls, txt in (("success", "safe"), ("warning", "likely orphan"),
("dim-label", "unknown")):
item = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
item.append(_dot(cls))
lbl = Gtk.Label(label=txt)
lbl.add_css_class("dim-label")
item.append(lbl)
box.append(item)
legend.add_suffix(box)
g1.add(legend)
page.add(g1)
# --- Gruppe 2: Findings mit flat-Buttons ----------------------------
g2 = ui.Group(title="Orphan packages",
description="6 findings · 410 MiB reclaimable")
for name, sub, cls in (
("python-debug-symbols", "safe · 182 MiB", "success"),
("lib32-mesa-demos", "likely orphan · 96 MiB", "warning"),
("ttf-ancient-fonts", "unknown · 132 MiB", "dim-label"),
):
row = ui.Row(title=name, subtitle=sub)
row.add_prefix(_dot(cls))
row.add_suffix(_flat("Keep"))
row.add_suffix(_flat("Trash", destructive=True))
g2.add(row)
page.add(g2)
# --- Gruppe 3: echte Control-Rows (Switch/Combo/Entry/Spin) ---------
g3 = ui.Group(title="Default applications")
sw = ui.SwitchRow(title="Empty Trash automatically",
subtitle="Remove items older than 30 days")
sw.set_active(True)
g3.add(sw)
combo = ui.ComboRow(title="Web Browser")
combo.add_prefix(Gtk.Image.new_from_icon_name("web-browser-symbolic"))
combo.set_model(["Firefox", "Chromium", "Zen"])
g3.add(combo)
entry = ui.EntryRow(title="Hostname")
entry.set_text("taninux")
g3.add(entry)
spin = ui.SpinRow(title="Keep snapshots")
spin.set_range(1, 30)
spin.set_value(7)
g3.add(spin)
page.add(g3)
return page
def _override_toggle(hex_color: str) -> None:
"""Optionaler Provider: Toggle-Farbe überschreiben (z.B. Fuji-Akzent)."""
from gi.repository import Gdk
provider = Gtk.CssProvider()
provider.load_from_data(
f".tn-row switch:checked {{ background-color: {hex_color}; }}".encode()
)
Gtk.StyleContext.add_provider_for_display(
Gdk.Display.get_default(), provider,
Gtk.STYLE_PROVIDER_PRIORITY_USER + 1,
)
def on_activate(app: Gtk.Application) -> None:
ui.ensure_css()
if TOGGLE:
_override_toggle(TOGGLE)
win = Gtk.ApplicationWindow(application=app, title="TANINUX · ui demo")
win.set_default_size(720, 720)
ui.set_dark(win, DARK)
header = Gtk.HeaderBar()
win.set_titlebar(header)
win.set_child(build_page())
win.present()
if SHOT:
win.fullscreen()
def _capture() -> bool:
subprocess.run(["grim", SHOT], check=False)
app.quit()
return False
GLib.timeout_add(800, _capture)
def main() -> int:
app = Gtk.Application(application_id="ch.gabrielevarano.Taninux.UiDemo")
app.connect("activate", on_activate)
return app.run([])
if __name__ == "__main__":
raise SystemExit(main())