gui: native libadwaita-free UI backend + dark shell; packaging/iso updates
- 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)
This commit is contained in:
+161
@@ -0,0 +1,161 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user