games: Load cover art

This commit is contained in:
kramo
2025-11-29 11:20:34 +01:00
parent 958558d1b6
commit af6c424207
5 changed files with 72 additions and 17 deletions

View File

@@ -1,18 +1,22 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 Zoey Ahmed
# SPDX-FileCopyrightText: Copyright 2025 kramo
from collections.abc import Generator
from pathlib import Path
from typing import cast
from gi.repository import (
Gdk,
Gio,
GLib,
GObject,
Json, # pyright: ignore[reportAttributeAccessIssue, reportUnknownVariableType]
)
GAMES_DIR = Path(GLib.get_user_data_dir(), "cartridges", "games")
DATA_DIR = Path(GLib.get_user_data_dir(), "cartridges")
GAMES_DIR = DATA_DIR / "games"
COVERS_DIR = DATA_DIR / "covers"
class Game(GObject.Object):
@@ -32,16 +36,32 @@ class Game(GObject.Object):
blacklisted = GObject.Property(type=bool, default=False)
version = GObject.Property(type=float, default=2.0)
cover = GObject.Property(type=Gdk.Texture)
def load() -> Generator[Game]:
"""Load the user's games from disk."""
for game in GAMES_DIR.iterdir():
data = game.read_text("utf-8")
for path in GAMES_DIR.glob("*.json"):
try:
yield Json.gobject_from_data(Game, data, len(data))
data = path.read_text("utf-8")
except UnicodeError:
continue
try:
game = cast(Game, Json.gobject_from_data(Game, data, len(data)))
except GLib.Error:
continue
cover_path = COVERS_DIR / game.game_id
for ext in ".gif", ".tiff":
filename = str(cover_path.with_suffix(ext))
try:
game.cover = Gdk.Texture.new_from_filename(filename)
except GLib.Error:
continue
yield game
model = Gio.ListStore.new(Game)
model.splice(0, 0, tuple(load()))

8
cartridges/ui/style.css Normal file
View File

@@ -0,0 +1,8 @@
#grid {
padding: 6px 12px 12px;
}
#grid > child {
padding: 12px;
border-radius: 24px;
}

View File

@@ -2,5 +2,6 @@
<gresources>
<gresource prefix="@PREFIX@">
<file>window.ui</file>
<file>style.css</file>
</gresource>
</gresources>

View File

@@ -3,8 +3,8 @@ using Adw 1;
template $Window: Adw.ApplicationWindow {
title: _("Cartridges");
default-width: 800;
default-height: 600;
default-width: 920;
default-height: 700;
ShortcutController {
Shortcut {
@@ -28,18 +28,43 @@ template $Window: Adw.ApplicationWindow {
}
}
content: GridView {
model: NoSelection {
model: bind template.games;
};
content: ScrolledWindow {
child: GridView {
name: "grid";
factory: BuilderListItemFactory {
template ListItem {
child: Label {
label: bind template.item as <$Game>.name;
};
}
model: NoSelection {
model: bind template.games;
};
factory: BuilderListItemFactory {
template ListItem {
child: Box {
orientation: vertical;
spacing: 12;
Picture {
paintable: bind template.item as <$Game>.cover;
width-request: 200;
height-request: 300;
halign: center;
styles [
"card",
]
}
Label {
label: bind template.item as <$Game>.name;
ellipsize: middle;
}
};
}
};
};
};
styles [
"view",
]
};
}

View File

@@ -56,6 +56,7 @@ ignore = [
"Q002",
"Q003",
"S310",
"TC006",
"TD",
"TRY301",
"W191",