This commit is contained in:
kramo
2023-04-16 11:04:00 +02:00
parent 24ad3369c7
commit aea8a6ed5f
6 changed files with 53 additions and 37 deletions

View File

@@ -37,6 +37,7 @@ Cartridges is a simple game launcher written in Python using GTK4 and Libadwaita
- Hiding games - Hiding games
- Searching and sorting by title, date added and last played - Searching and sorting by title, date added and last played
- Automatically downloading cover art from [SteamGridDB](https://www.steamgriddb.com/) - Automatically downloading cover art from [SteamGridDB](https://www.steamgriddb.com/)
- Animated covers
For updates and questions, join our [Discord server][discord-url]! For updates and questions, join our [Discord server][discord-url]!

View File

@@ -62,7 +62,11 @@ class Game(Gtk.Box):
self.loading = 0 self.loading = 0
self.title.set_label(self.name) 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.event_contoller_motion = Gtk.EventControllerMotion.new()
self.add_controller(self.event_contoller_motion) self.add_controller(self.event_contoller_motion)
@@ -124,8 +128,6 @@ class Game(Gtk.Box):
if cover_path.is_file(): if cover_path.is_file():
return cover_path return cover_path
return None
def show_play(self, _widget, *_unused): def show_play(self, _widget, *_unused):
self.play_revealer.set_reveal_child(True) self.play_revealer.set_reveal_child(True)
self.title_revealer.set_reveal_child(False) self.title_revealer.set_reveal_child(False)

View File

@@ -30,8 +30,8 @@ class GameCover:
"/hu/kramo/Cartridges/library_placeholder.svg", 400, 600, False "/hu/kramo/Cartridges/library_placeholder.svg", 400, 600, False
) )
def __init__(self, picture, pixbuf=None, path=None): def __init__(self, pictures, pixbuf=None, path=None):
self.picture = picture self.pictures = pictures
self.new_pixbuf(pixbuf, path) self.new_pixbuf(pixbuf, path)
# Wrap the function in another one as Gio.Task.run_in_thread does not allow for passing args # 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): def get_animation(self):
return self.path if self.animation else None 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): def set_pixbuf(self, pixbuf):
if self.picture.is_visible(): self.pictures.discard(
if not pixbuf: picture for picture in self.pictures if not picture.is_visible()
pixbuf = self.placeholder_pixbuf )
self.picture.set_pixbuf(pixbuf) if not self.pictures:
else:
self.animation = None 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): def update_animation(self, data):
if self.animation == data[1]: if self.animation == data[1]:

View File

@@ -75,17 +75,10 @@ def create_details_window(win, game_id=None):
) )
cover = Gtk.Picture.new() cover = Gtk.Picture.new()
game_cover = GameCover(cover) game_cover = GameCover({cover})
if not game_id: if 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:
window.set_title(_("Edit Game Details")) window.set_title(_("Edit Game Details"))
game_cover.new_pixbuf(path=win.games[game_id].get_cover_path())
developer = Gtk.Entry.new_with_buffer( developer = Gtk.Entry.new_with_buffer(
Gtk.EntryBuffer.new(games[game_id].developer, -1) 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")) 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) 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 = Gtk.FileFilter(name=_("Images"))
image_filter.add_pixbuf_formats() image_filter.add_pixbuf_formats()
@@ -241,6 +241,7 @@ def create_details_window(win, game_id=None):
def apply_preferences(_widget, _callback=None): def apply_preferences(_widget, _callback=None):
nonlocal cover_changed nonlocal cover_changed
nonlocal game_id nonlocal game_id
nonlocal cover
values = {} values = {}
@@ -313,6 +314,8 @@ def create_details_window(win, game_id=None):
values["developer"] = final_developer or None values["developer"] = final_developer or None
values["executable"] = final_executable_split values["executable"] = final_executable_split
win.game_covers[game_id] = game_cover
if cover_changed: if cover_changed:
save_cover( save_cover(
win, win,
@@ -336,6 +339,8 @@ def create_details_window(win, game_id=None):
if not game_cover.get_pixbuf(): if not game_cover.get_pixbuf():
SGDBSave(win, {(game_id, values["name"])}) SGDBSave(win, {(game_id, values["name"])})
win.game_covers[game_id].pictures.remove(cover)
window.close() window.close()
win.show_details_view(None, game_id) 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) cancel_button.connect("clicked", close_window)
apply_button.connect("clicked", apply_preferences) apply_button.connect("clicked", apply_preferences)
name.connect("activate", focus_executable) name.connect("activate", focus_executable)
developer.connect("activate", focus_executable)
executable.connect("activate", apply_preferences) executable.connect("activate", apply_preferences)
shortcut_controller = Gtk.ShortcutController() shortcut_controller = Gtk.ShortcutController()

View File

@@ -57,6 +57,7 @@ def save_cover(
if animation_path: if animation_path:
copyfile(animation_path, win.covers_dir / f"{game_id}.gif") copyfile(animation_path, win.covers_dir / f"{game_id}.gif")
win.game_covers[game_id].new_pixbuf(path=animation_path)
return return
if not pixbuf: if not pixbuf:
@@ -72,3 +73,5 @@ def save_cover(
["compression"], ["compression"],
["8"] if win.schema.get_boolean("high-quality-images") else ["7"], ["8"] if win.schema.get_boolean("high-quality-images") else ["7"],
) )
win.game_covers[game_id].new_pixbuf(pixbuf=pixbuf)

View File

@@ -26,7 +26,6 @@ from shutil import rmtree
from gi.repository import Adw, Gdk, GdkPixbuf, Gio, GLib, Gtk from gi.repository import Adw, Gdk, GdkPixbuf, Gio, GLib, Gtk
from .game import Game from .game import Game
from .game_cover import GameCover
from .get_games import get_games from .get_games import get_games
from .save_game import save_game from .save_game import save_game
@@ -93,6 +92,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
self.covers_dir = self.data_dir / "cartridges" / "covers" self.covers_dir = self.data_dir / "cartridges" / "covers"
self.games = {} self.games = {}
self.game_covers = {}
self.visible_widgets = {} self.visible_widgets = {}
self.hidden_widgets = {} self.hidden_widgets = {}
self.filtered = {} self.filtered = {}
@@ -101,9 +101,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
self.toasts = {} self.toasts = {}
self.active_game_id = None self.active_game_id = None
self.scaled_pixbuf = None self.scaled_pixbuf = None
self.details_view_game_cover = None
self.details_view.set_measure_overlay(self.details_view_box, True)
self.details_view.set_clip_overlay(self.details_view_box, False)
self.schema = Gio.Settings.new("hu.kramo.Cartridges") self.schema = Gio.Settings.new("hu.kramo.Cartridges")
scale_factor = max( scale_factor = max(
@@ -121,18 +119,14 @@ class CartridgesWindow(Adw.ApplicationWindow):
rmtree(self.cache_dir / "cartridges" / "deleted_covers", True) 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.library.set_filter_func(self.search_filter)
self.hidden_library.set_filter_func(self.hidden_search_filter) self.hidden_library.set_filter_func(self.hidden_search_filter)
self.update_games(get_games(self)) 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 # Connect signals
self.search_entry.connect("search-changed", self.search_changed, False) self.search_entry.connect("search-changed", self.search_changed, False)
self.hidden_search_entry.connect("search-changed", self.search_changed, True) 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.active_game_id = game_id
self.details_view_game_cover.new_pixbuf(path=current_game.get_cover_path()) if self.details_view_game_cover:
pixbuf = self.details_view_game_cover.get_pixbuf() 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 = ( self.scaled_pixbuf = (
pixbuf.scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR) self.details_view_game_cover.get_pixbuf()
if pixbuf or self.details_view_game_cover.placeholder_pixbuf
else self.placeholder_pixbuf_scaled ).scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR)
)
self.details_view_blurred_cover.set_pixbuf(self.scaled_pixbuf) self.details_view_blurred_cover.set_pixbuf(self.scaled_pixbuf)
self.set_details_view_opacity() self.set_details_view_opacity()