diff --git a/cartridges/__init__.py b/cartridges/__init__.py index 1d13412..4fb6de3 100644 --- a/cartridges/__init__.py +++ b/cartridges/__init__.py @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: Copyright 2025 Zoey Ahmed + import gettext import locale import signal @@ -9,6 +12,7 @@ import gi gi.require_versions({ "Gtk": "4.0", "Adw": "1", + "Json": "1.0", }) from gi.repository import Gio diff --git a/cartridges/__main__.py b/cartridges/__main__.py index 508e606..645a6aa 100644 --- a/cartridges/__main__.py +++ b/cartridges/__main__.py @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: Copyright 2025 Zoey Ahmed + import sys from gi.events import GLibEventLoopPolicy diff --git a/cartridges/application.py b/cartridges/application.py index 9527ff0..7b29454 100644 --- a/cartridges/application.py +++ b/cartridges/application.py @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: Copyright 2025 Zoey Ahmed + from gettext import gettext as _ from typing import override diff --git a/cartridges/games.py b/cartridges/games.py new file mode 100644 index 0000000..3490250 --- /dev/null +++ b/cartridges/games.py @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: Copyright 2025 Zoey Ahmed + +from collections.abc import Generator +from pathlib import Path + +from gi.repository import ( + Gio, + GLib, + GObject, + Json, # pyright: ignore[reportAttributeAccessIssue, reportUnknownVariableType] +) + + +GAMES_DIR = Path(GLib.get_user_data_dir(), "cartridges", "games") + + +class Game(GObject.Object): + """Game data class.""" + + __gtype_name__ = __qualname__ + + added = GObject.Property(type=int) + executable = GObject.Property(type=str) + game_id = GObject.Property(type=str) + source = GObject.Property(type=str) + hidden = GObject.Property(type=bool, default=False) + last_played = GObject.Property(type=int, default=0) + name = GObject.Property(type=str) + developer = GObject.Property(type=str) + removed = GObject.Property(type=bool, default=False) + blacklisted = GObject.Property(type=bool, default=False) + version = GObject.Property(type=float, default=2.0) + + +def load() -> Generator[Game]: + """Load the user's games from disk.""" + for game in GAMES_DIR.iterdir(): + data = game.read_text("utf-8") + try: + yield Json.gobject_from_data(Game, data, len(data)) + except GLib.Error: + continue + + +model = Gio.ListStore.new(Game) +model.splice(0, 0, tuple(load())) diff --git a/cartridges/meson.build b/cartridges/meson.build index 16d22a3..331e689 100644 --- a/cartridges/meson.build +++ b/cartridges/meson.build @@ -1,5 +1,5 @@ python.install_sources( - files('__init__.py', '__main__.py', 'application.py'), + files('__init__.py', '__main__.py', 'application.py', 'games.py'), subdir: 'cartridges', ) diff --git a/cartridges/ui/window.blp b/cartridges/ui/window.blp index 238ed35..f38d39c 100644 --- a/cartridges/ui/window.blp +++ b/cartridges/ui/window.blp @@ -28,12 +28,18 @@ template $Window: Adw.ApplicationWindow { } } - content: Label { - label: _("Hello, World!"); + content: GridView { + model: NoSelection { + model: bind template.games; + }; - styles [ - "title-1", - ] + factory: BuilderListItemFactory { + template ListItem { + child: Label { + label: bind template.item as <$Game>.name; + }; + } + }; }; }; } diff --git a/cartridges/ui/window.py b/cartridges/ui/window.py index 2fa9bbc..30424a5 100644 --- a/cartridges/ui/window.py +++ b/cartridges/ui/window.py @@ -1,7 +1,11 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: Copyright 2025 Zoey Ahmed + from typing import Any -from gi.repository import Adw, Gtk +from gi.repository import Adw, Gio, GObject, Gtk +from cartridges import games from cartridges.config import PREFIX, PROFILE @@ -11,6 +15,11 @@ class Window(Adw.ApplicationWindow): __gtype_name__ = __qualname__ + @GObject.Property(type=Gio.ListStore) + def games(self) -> Gio.ListStore: + """Model of the user's games.""" + return games.model + def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) diff --git a/po/POTFILES.in b/po/POTFILES.in index a416001..0dadddd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,4 +1,5 @@ cartridges/application.py +cartridges/games.py cartridges/ui/window.blp cartridges/ui/window.py data/page.kramo.Cartridges.desktop.in diff --git a/pyproject.toml b/pyproject.toml index 2fc257d..828d03d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ ignore = [ "COM812", "COM819", "D100", + "D104", "D105", "D107", "D203",