e8d93e6b1d
- gui/ui: native GTK4 widget vocabulary (.tn-*) behind the ui.* seam, default backend now native; style_apple.css design language - shell: sidebar/topbar/content all #0f0f0f in dark (matches eww panels) - new pages: wine, online_accounts - packaging: tanin-icons (accent folder theme), tanin-calendar, gtklock, taninux-gtk3-theme, flatpak install handler - iso/distro: profile + manifest tweaks (ISO binary not included)
162 lines
4.8 KiB
Python
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())
|