games: Add loading of games from disk

This commit is contained in:
Zoey Ahmed
2025-11-28 21:10:06 +00:00
parent a5721e41e7
commit 958558d1b6
9 changed files with 81 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

47
cartridges/games.py Normal file
View File

@@ -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()))

View File

@@ -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',
)

View File

@@ -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;
};
}
};
};
};
}

View File

@@ -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)

View File

@@ -1,4 +1,5 @@
cartridges/application.py
cartridges/games.py
cartridges/ui/window.blp
cartridges/ui/window.py
data/page.kramo.Cartridges.desktop.in

View File

@@ -26,6 +26,7 @@ ignore = [
"COM812",
"COM819",
"D100",
"D104",
"D105",
"D107",
"D203",