From aea8a6ed5fcb4a6887ed1941100f92dc7539dbfa Mon Sep 17 00:00:00 2001 From: kramo <93832451+kra-mo@users.noreply.github.com> Date: Sun, 16 Apr 2023 11:04:00 +0200 Subject: [PATCH] Cleanups --- README.md | 1 + src/game.py | 8 +++++--- src/game_cover.py | 23 ++++++++++++++++------- src/utils/create_details_window.py | 26 ++++++++++++++++---------- src/utils/save_cover.py | 3 +++ src/window.py | 29 ++++++++++++----------------- 6 files changed, 53 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index ea9dcd4..ef8d034 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ Cartridges is a simple game launcher written in Python using GTK4 and Libadwaita - Hiding games - Searching and sorting by title, date added and last played - Automatically downloading cover art from [SteamGridDB](https://www.steamgriddb.com/) +- Animated covers For updates and questions, join our [Discord server][discord-url]! diff --git a/src/game.py b/src/game.py index 86bede5..df9b47e 100644 --- a/src/game.py +++ b/src/game.py @@ -62,7 +62,11 @@ class Game(Gtk.Box): self.loading = 0 self.title.set_label(self.name) - self.game_cover = GameCover(self.cover, path=self.get_cover_path()) + if self.game_id in self.win.game_covers: + self.win.game_covers[self.game_id].add_picture(self.cover) + else: + game_cover = GameCover({self.cover}, path=self.get_cover_path()) + self.win.game_covers[self.game_id] = game_cover self.event_contoller_motion = Gtk.EventControllerMotion.new() self.add_controller(self.event_contoller_motion) @@ -124,8 +128,6 @@ class Game(Gtk.Box): if cover_path.is_file(): return cover_path - return None - def show_play(self, _widget, *_unused): self.play_revealer.set_reveal_child(True) self.title_revealer.set_reveal_child(False) diff --git a/src/game_cover.py b/src/game_cover.py index 8479b75..2b886cf 100644 --- a/src/game_cover.py +++ b/src/game_cover.py @@ -30,8 +30,8 @@ class GameCover: "/hu/kramo/Cartridges/library_placeholder.svg", 400, 600, False ) - def __init__(self, picture, pixbuf=None, path=None): - self.picture = picture + def __init__(self, pictures, pixbuf=None, path=None): + self.pictures = pictures self.new_pixbuf(pixbuf, path) # Wrap the function in another one as Gio.Task.run_in_thread does not allow for passing args @@ -72,13 +72,22 @@ class GameCover: def get_animation(self): return self.path if self.animation else None + def add_picture(self, picture): + self.pictures.add(picture) + if not self.animation: + self.set_pixbuf(self.pixbuf) + def set_pixbuf(self, pixbuf): - if self.picture.is_visible(): - if not pixbuf: - pixbuf = self.placeholder_pixbuf - self.picture.set_pixbuf(pixbuf) - else: + self.pictures.discard( + picture for picture in self.pictures if not picture.is_visible() + ) + if not self.pictures: self.animation = None + else: + for picture in self.pictures: + if not pixbuf: + pixbuf = self.placeholder_pixbuf + picture.set_pixbuf(pixbuf) def update_animation(self, data): if self.animation == data[1]: diff --git a/src/utils/create_details_window.py b/src/utils/create_details_window.py index 238d7a9..e420a56 100644 --- a/src/utils/create_details_window.py +++ b/src/utils/create_details_window.py @@ -75,17 +75,10 @@ def create_details_window(win, game_id=None): ) cover = Gtk.Picture.new() - game_cover = GameCover(cover) + game_cover = GameCover({cover}) - if not game_id: - window.set_title(_("Add New Game")) - name = Gtk.Entry() - developer = Gtk.Entry() - executable = Gtk.Entry() - apply_button = Gtk.Button.new_with_label(_("Confirm")) - else: + if game_id: window.set_title(_("Edit Game Details")) - game_cover.new_pixbuf(path=win.games[game_id].get_cover_path()) developer = Gtk.Entry.new_with_buffer( Gtk.EntryBuffer.new(games[game_id].developer, -1) ) @@ -95,8 +88,15 @@ def create_details_window(win, game_id=None): ) apply_button = Gtk.Button.new_with_label(_("Apply")) - if win.games[game_id].get_cover_path(): + game_cover.new_pixbuf(path=win.games[game_id].get_cover_path()) + if game_cover.get_pixbuf(): cover_button_delete_revealer.set_reveal_child(True) + else: + window.set_title(_("Add New Game")) + name = Gtk.Entry() + developer = Gtk.Entry() + executable = Gtk.Entry() + apply_button = Gtk.Button.new_with_label(_("Confirm")) image_filter = Gtk.FileFilter(name=_("Images")) image_filter.add_pixbuf_formats() @@ -241,6 +241,7 @@ def create_details_window(win, game_id=None): def apply_preferences(_widget, _callback=None): nonlocal cover_changed nonlocal game_id + nonlocal cover values = {} @@ -313,6 +314,8 @@ def create_details_window(win, game_id=None): values["developer"] = final_developer or None values["executable"] = final_executable_split + win.game_covers[game_id] = game_cover + if cover_changed: save_cover( win, @@ -336,6 +339,8 @@ def create_details_window(win, game_id=None): if not game_cover.get_pixbuf(): SGDBSave(win, {(game_id, values["name"])}) + win.game_covers[game_id].pictures.remove(cover) + window.close() win.show_details_view(None, game_id) @@ -346,6 +351,7 @@ def create_details_window(win, game_id=None): cancel_button.connect("clicked", close_window) apply_button.connect("clicked", apply_preferences) name.connect("activate", focus_executable) + developer.connect("activate", focus_executable) executable.connect("activate", apply_preferences) shortcut_controller = Gtk.ShortcutController() diff --git a/src/utils/save_cover.py b/src/utils/save_cover.py index 314260d..30eaca5 100644 --- a/src/utils/save_cover.py +++ b/src/utils/save_cover.py @@ -57,6 +57,7 @@ def save_cover( if animation_path: copyfile(animation_path, win.covers_dir / f"{game_id}.gif") + win.game_covers[game_id].new_pixbuf(path=animation_path) return if not pixbuf: @@ -72,3 +73,5 @@ def save_cover( ["compression"], ["8"] if win.schema.get_boolean("high-quality-images") else ["7"], ) + + win.game_covers[game_id].new_pixbuf(pixbuf=pixbuf) diff --git a/src/window.py b/src/window.py index 9a064f6..8662cb2 100644 --- a/src/window.py +++ b/src/window.py @@ -26,7 +26,6 @@ from shutil import rmtree from gi.repository import Adw, Gdk, GdkPixbuf, Gio, GLib, Gtk from .game import Game -from .game_cover import GameCover from .get_games import get_games from .save_game import save_game @@ -93,6 +92,7 @@ class CartridgesWindow(Adw.ApplicationWindow): self.covers_dir = self.data_dir / "cartridges" / "covers" self.games = {} + self.game_covers = {} self.visible_widgets = {} self.hidden_widgets = {} self.filtered = {} @@ -101,9 +101,7 @@ class CartridgesWindow(Adw.ApplicationWindow): self.toasts = {} self.active_game_id = None self.scaled_pixbuf = None - - self.details_view.set_measure_overlay(self.details_view_box, True) - self.details_view.set_clip_overlay(self.details_view_box, False) + self.details_view_game_cover = None self.schema = Gio.Settings.new("hu.kramo.Cartridges") scale_factor = max( @@ -121,18 +119,14 @@ class CartridgesWindow(Adw.ApplicationWindow): rmtree(self.cache_dir / "cartridges" / "deleted_covers", True) + self.details_view.set_measure_overlay(self.details_view_box, True) + self.details_view.set_clip_overlay(self.details_view_box, False) + self.library.set_filter_func(self.search_filter) self.hidden_library.set_filter_func(self.hidden_search_filter) self.update_games(get_games(self)) - self.details_view_game_cover = GameCover(self.details_view_cover) - self.placeholder_pixbuf_scaled = ( - self.details_view_game_cover.placeholder_pixbuf.scale_simple( - 2, 3, GdkPixbuf.InterpType.BILINEAR - ) - ) - # Connect signals self.search_entry.connect("search-changed", self.search_changed, False) self.hidden_search_entry.connect("search-changed", self.search_changed, True) @@ -291,14 +285,15 @@ class CartridgesWindow(Adw.ApplicationWindow): self.active_game_id = game_id - self.details_view_game_cover.new_pixbuf(path=current_game.get_cover_path()) - pixbuf = self.details_view_game_cover.get_pixbuf() + if self.details_view_game_cover: + self.details_view_game_cover.pictures.remove(self.details_view_cover) + self.details_view_game_cover = self.game_covers[game_id] + self.details_view_game_cover.add_picture(self.details_view_cover) self.scaled_pixbuf = ( - pixbuf.scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR) - if pixbuf - else self.placeholder_pixbuf_scaled - ) + self.details_view_game_cover.get_pixbuf() + or self.details_view_game_cover.placeholder_pixbuf + ).scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR) self.details_view_blurred_cover.set_pixbuf(self.scaled_pixbuf) self.set_details_view_opacity()