mirror of
https://github.com/Cheviiot/Vual.git
synced 2026-08-03 15:57:25 +00:00
129 lines
4.4 KiB
Python
129 lines
4.4 KiB
Python
"""Main application window — single-page tile grid."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "4.0")
|
|
gi.require_version("Adw", "1")
|
|
|
|
from gi.repository import Adw, Gio, GLib, Gtk # noqa: E402
|
|
|
|
from vual import APP_NAME # noqa: E402
|
|
from vual.config import Config # noqa: E402
|
|
from vual.i18n import _ # noqa: E402
|
|
|
|
|
|
class VualWindow(Adw.ApplicationWindow):
|
|
def __init__(self, config: Config, **kwargs) -> None:
|
|
super().__init__(
|
|
default_width=config.window_width,
|
|
default_height=config.window_height,
|
|
title=APP_NAME,
|
|
**kwargs,
|
|
)
|
|
self.config = config
|
|
self._build_ui()
|
|
|
|
# ── UI construction ──────────────────────────────────────────
|
|
|
|
def _build_ui(self) -> None:
|
|
self.toast_overlay = Adw.ToastOverlay()
|
|
self.set_content(self.toast_overlay)
|
|
|
|
toolbar_view = Adw.ToolbarView()
|
|
self.toast_overlay.set_child(toolbar_view)
|
|
|
|
# Single main page
|
|
from vual.ui.main_page import MainPage
|
|
|
|
self.main_page = MainPage(config=self.config, window=self)
|
|
|
|
# Header bar
|
|
header = Adw.HeaderBar()
|
|
header.add_css_class("flat")
|
|
|
|
# Title widget: search + counter
|
|
title_box = Gtk.Box(spacing=8)
|
|
title_box.append(self.main_page._search)
|
|
self._counter = Gtk.Label(css_classes=["games-counter"])
|
|
title_box.append(self._counter)
|
|
header.set_title_widget(title_box)
|
|
|
|
b_refresh = Gtk.Button(
|
|
icon_name="view-refresh-symbolic",
|
|
css_classes=["flat", "header-btn"],
|
|
tooltip_text=_("Refresh"),
|
|
)
|
|
b_refresh.connect("clicked", lambda _: self.main_page._load())
|
|
header.pack_start(b_refresh)
|
|
|
|
b_on = Gtk.Button(
|
|
icon_name="object-select-symbolic",
|
|
css_classes=["flat", "header-btn"],
|
|
tooltip_text=_("Enable All"),
|
|
)
|
|
b_on.connect("clicked", self.main_page._on_enable_all)
|
|
header.pack_start(b_on)
|
|
|
|
b_off = Gtk.Button(
|
|
icon_name="edit-clear-all-symbolic",
|
|
css_classes=["flat", "header-btn"],
|
|
tooltip_text=_("Disable All"),
|
|
)
|
|
b_off.connect("clicked", self.main_page._on_disable_all)
|
|
header.pack_start(b_off)
|
|
|
|
# Sort menu
|
|
sort_menu = Gio.Menu()
|
|
sort_menu.append(_("By name"), "win.sort::name")
|
|
sort_menu.append(_("By status"), "win.sort::status")
|
|
|
|
sort_btn = Gtk.MenuButton(
|
|
icon_name="view-sort-descending-symbolic",
|
|
css_classes=["flat", "header-btn"],
|
|
menu_model=sort_menu,
|
|
tooltip_text=_("Sort"),
|
|
)
|
|
header.pack_end(sort_btn)
|
|
|
|
# Sort action
|
|
sort_action = Gio.SimpleAction.new("sort", GLib.VariantType.new("s"))
|
|
sort_action.connect("activate", self._on_sort_changed)
|
|
self.add_action(sort_action)
|
|
|
|
menu_button = Gtk.MenuButton(
|
|
icon_name="open-menu-symbolic",
|
|
css_classes=["flat", "header-btn"],
|
|
menu_model=self._build_menu(),
|
|
)
|
|
header.pack_end(menu_button)
|
|
toolbar_view.add_top_bar(header)
|
|
|
|
toolbar_view.set_content(self.main_page)
|
|
|
|
def _on_sort_changed(self, action: Gio.SimpleAction, param: GLib.Variant) -> None:
|
|
sort_by = param.get_string()
|
|
self.config.sort_by = sort_by
|
|
self.main_page._update_sort()
|
|
|
|
def update_counter(self, count: int) -> None:
|
|
"""Update the games counter label."""
|
|
self._counter.set_label(_("%d games") % count)
|
|
|
|
# ── App menu ─────────────────────────────────────────────────
|
|
|
|
def _build_menu(self) -> Gio.Menu:
|
|
menu = Gio.Menu()
|
|
menu.append(_("Preferences"), "app.preferences")
|
|
menu.append(_("About"), "app.about")
|
|
menu.append(_("Quit"), "app.quit")
|
|
return menu
|
|
|
|
# ── Toast helper ─────────────────────────────────────────────
|
|
|
|
def show_toast(self, message: str, timeout: int = 3) -> None:
|
|
toast = Adw.Toast(title=message, timeout=timeout)
|
|
self.toast_overlay.add_toast(toast)
|
|
return False
|