Better image handling
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
|
||||
from gi.repository import Gtk
|
||||
|
||||
from .get_cover import get_cover
|
||||
|
||||
@Gtk.Template(resource_path='/hu/kramo/Cartridges/gtk/game.ui')
|
||||
class game(Gtk.Box):
|
||||
__gtype_name__ = 'game'
|
||||
@@ -33,7 +35,7 @@ class game(Gtk.Box):
|
||||
play_revealer = Gtk.Template.Child()
|
||||
title_revealer = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, parent_widget, data, pixbuf, **kwargs):
|
||||
def __init__(self, parent_widget, data, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.parent_widget = parent_widget
|
||||
@@ -49,10 +51,10 @@ class game(Gtk.Box):
|
||||
else:
|
||||
self.removed = False
|
||||
|
||||
self.pixbuf = pixbuf
|
||||
self.pixbuf = get_cover(self.game_id, self.parent_widget)
|
||||
|
||||
self.title.set_label(self.name)
|
||||
self.cover.set_pixbuf(self.pixbuf)
|
||||
self.title.set_label(self.name)
|
||||
|
||||
self.event_contoller_motion = Gtk.EventControllerMotion.new()
|
||||
self.add_controller(self.event_contoller_motion)
|
||||
|
||||
@@ -122,7 +122,7 @@ class CartridgesApplication(Adw.Application):
|
||||
data["last_played"] = int(time.time())
|
||||
save_games({game_id : data})
|
||||
|
||||
run_command(self.win, self.win.games_temp[self.win.active_game_id].executable)
|
||||
run_command(self.win, self.win.games[self.win.active_game_id].executable)
|
||||
|
||||
self.win.update_games([game_id])
|
||||
|
||||
@@ -155,7 +155,7 @@ class CartridgesApplication(Adw.Application):
|
||||
self.win.on_go_back_action(None, None)
|
||||
|
||||
# Create toast for undoing the remove action
|
||||
toast = Adw.Toast.new(self.win.games_temp[game_id].name + " " + (_("removed")))
|
||||
toast = Adw.Toast.new(self.win.games[game_id].name + " " + (_("removed")))
|
||||
toast.set_button_label(_("Undo"))
|
||||
toast.connect("button-clicked", self.win.on_undo_remove_action, game_id)
|
||||
toast.set_priority(Adw.ToastPriority.HIGH)
|
||||
|
||||
@@ -78,7 +78,7 @@ def bottles_parser(parent_widget, action):
|
||||
|
||||
values["game_id"] = "bottles_" + game["id"]
|
||||
|
||||
if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed:
|
||||
if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed:
|
||||
continue
|
||||
|
||||
values["name"] = game["name"]
|
||||
@@ -89,7 +89,7 @@ def bottles_parser(parent_widget, action):
|
||||
values["last_played"] = 0
|
||||
|
||||
if game["thumbnail"]:
|
||||
values["pixbuf_options"] = save_cover(values, parent_widget, os.path.join(bottles_dir, "bottles", game["bottle"]["path"], "grids", game["thumbnail"].split(":")[1]))
|
||||
save_cover(values, parent_widget, os.path.join(bottles_dir, "bottles", game["bottle"]["path"], "grids", game["thumbnail"].split(":")[1]))
|
||||
|
||||
bottles_games[values["game_id"]] = values
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ def create_details_window(parent_widget, game_id = None):
|
||||
from .create_dialog import create_dialog
|
||||
from .save_games import save_games
|
||||
from .save_cover import save_cover
|
||||
from .get_cover import get_cover
|
||||
|
||||
window = Adw.Window(
|
||||
modal = True,
|
||||
@@ -31,7 +32,7 @@ def create_details_window(parent_widget, game_id = None):
|
||||
transient_for = parent_widget
|
||||
)
|
||||
|
||||
games = parent_widget.games_temp
|
||||
games = parent_widget.games
|
||||
pixbuf = None
|
||||
|
||||
if game_id == None:
|
||||
@@ -42,7 +43,7 @@ def create_details_window(parent_widget, game_id = None):
|
||||
apply_button = Gtk.Button.new_with_label(_("Confirm"))
|
||||
else:
|
||||
window.set_title(_("Edit Game Details"))
|
||||
cover = Gtk.Picture.new_for_pixbuf((parent_widget.visible_widgets | parent_widget.hidden_widgets)[game_id].pixbuf)
|
||||
cover = Gtk.Picture.new_for_pixbuf(get_cover(game_id, parent_widget))
|
||||
name = Gtk.Entry.new_with_buffer(Gtk.EntryBuffer.new(games[game_id].name, -1))
|
||||
executable = Gtk.Entry.new_with_buffer(Gtk.EntryBuffer.new((games[game_id].executable), -1))
|
||||
apply_button = Gtk.Button.new_with_label(_("Apply"))
|
||||
@@ -173,7 +174,7 @@ def create_details_window(parent_widget, game_id = None):
|
||||
return
|
||||
|
||||
if pixbuf != None:
|
||||
values["pixbuf_options"] = save_cover(None, parent_widget, None, pixbuf, game_id)
|
||||
save_cover(None, parent_widget, None, pixbuf, game_id)
|
||||
|
||||
values["name"] = final_name
|
||||
values["executable"] = final_executable
|
||||
|
||||
@@ -17,17 +17,15 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
def get_cover(game_id, pixbuf_options, parent_widget):
|
||||
def get_cover(game_id, parent_widget):
|
||||
from gi.repository import GdkPixbuf
|
||||
import os, zlib
|
||||
import os
|
||||
|
||||
cover_path = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers", game_id + ".dat")
|
||||
if game_id in parent_widget.pixbufs.keys():
|
||||
return parent_widget.pixbufs[game_id]
|
||||
cover_path = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers", game_id + ".png")
|
||||
|
||||
if os.path.isfile(cover_path) == False:
|
||||
return parent_widget.placeholder_pixbuf
|
||||
|
||||
open_file = open(cover_path, "rb")
|
||||
data = zlib.decompress(open_file.read())
|
||||
open_file.close()
|
||||
|
||||
return GdkPixbuf.Pixbuf.new_from_data(data, *pixbuf_options)
|
||||
return GdkPixbuf.Pixbuf.new_from_file(cover_path)
|
||||
|
||||
@@ -83,7 +83,7 @@ def heroic_parser(parent_widget, action):
|
||||
app_name = game["app_name"]
|
||||
values["game_id"] = "heroic_epic_" + app_name
|
||||
|
||||
if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed:
|
||||
if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed:
|
||||
continue
|
||||
|
||||
values["name"] = game["title"]
|
||||
@@ -95,7 +95,7 @@ def heroic_parser(parent_widget, action):
|
||||
|
||||
image_path = os.path.join(heroic_dir, "images-cache", hashlib.sha256((game["art_square"] + "?h=400&resize=1&w=300").encode()).hexdigest())
|
||||
if os.path.exists(image_path):
|
||||
values["pixbuf_options"] = save_cover(values, parent_widget, image_path)
|
||||
save_cover(values, parent_widget, image_path)
|
||||
|
||||
heroic_games[values["game_id"]] = values
|
||||
|
||||
@@ -113,7 +113,7 @@ def heroic_parser(parent_widget, action):
|
||||
|
||||
values["game_id"] = "heroic_gog_" + app_name
|
||||
|
||||
if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed:
|
||||
if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed:
|
||||
continue
|
||||
|
||||
# Get game title from library.json as it's not present in installed.json
|
||||
@@ -127,7 +127,7 @@ def heroic_parser(parent_widget, action):
|
||||
image_path = os.path.join(heroic_dir, "images-cache",
|
||||
hashlib.sha256(game["art_square"].encode()).hexdigest())
|
||||
if os.path.exists(image_path):
|
||||
values["pixbuf_options"] = save_cover(values, parent_widget, image_path)
|
||||
save_cover(values, parent_widget, image_path)
|
||||
break
|
||||
|
||||
values["executable"] = "xdg-open heroic://launch/" + app_name
|
||||
@@ -152,7 +152,7 @@ def heroic_parser(parent_widget, action):
|
||||
|
||||
values["game_id"] = "heroic_sideload_" + app_name
|
||||
|
||||
if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed:
|
||||
if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed:
|
||||
continue
|
||||
|
||||
values["name"] = item["title"]
|
||||
@@ -164,7 +164,7 @@ def heroic_parser(parent_widget, action):
|
||||
image_path = os.path.join(heroic_dir, "images-cache",
|
||||
hashlib.sha256(item["art_square"].encode()).hexdigest())
|
||||
if os.path.exists(image_path):
|
||||
values["pixbuf_options"] = save_cover(values, parent_widget, image_path)
|
||||
save_cover(values, parent_widget, image_path)
|
||||
|
||||
heroic_games[values["game_id"]] = values
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
def save_cover(game, parent_widget, file_path, pixbuf = None, game_id = None):
|
||||
from gi.repository import GdkPixbuf
|
||||
import os, zlib
|
||||
from gi.repository import Gio, GdkPixbuf
|
||||
import os
|
||||
|
||||
covers_dir = os.path.join(os.environ.get("XDG_DATA_HOME"), "cartridges", "covers")
|
||||
if os.path.exists(covers_dir) == False:
|
||||
@@ -33,7 +33,9 @@ def save_cover(game, parent_widget, file_path, pixbuf = None, game_id = None):
|
||||
if pixbuf == None:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(file_path, 600, 900, False)
|
||||
|
||||
open_file = open(cover_path, "wb")
|
||||
open_file.write(zlib.compress(bytes(pixbuf.get_pixels()), 1))
|
||||
open_file.close()
|
||||
return [pixbuf.get_colorspace(), pixbuf.get_has_alpha(), pixbuf.get_bits_per_sample(), pixbuf.get_width(), pixbuf.get_height(), pixbuf.get_rowstride()]
|
||||
def cover_callback(*args):
|
||||
pass
|
||||
|
||||
file = Gio.File.new_for_path(os.path.join(covers_dir, game_id + ".png"))
|
||||
parent_widget.pixbufs[game_id] = pixbuf
|
||||
pixbuf.save_to_streamv_async(file.replace(None, False, Gio.FileCreateFlags.NONE), "png", None, None, None, cover_callback)
|
||||
|
||||
@@ -87,7 +87,7 @@ def steam_parser(parent_widget, action):
|
||||
|
||||
values["game_id"] = "steam_" + values["appid"]
|
||||
|
||||
if values["game_id"] in parent_widget.games_temp and not parent_widget.games_temp[values["game_id"]].removed:
|
||||
if values["game_id"] in parent_widget.games and not parent_widget.games[values["game_id"]].removed:
|
||||
continue
|
||||
|
||||
values["executable"] = "xdg-open steam://rungameid/" + values["appid"]
|
||||
@@ -97,7 +97,7 @@ def steam_parser(parent_widget, action):
|
||||
values["last_played"] = 0
|
||||
|
||||
if os.path.isfile(os.path.join(steam_dir, "appcache", "librarycache", values["appid"] + "_library_600x900.jpg")):
|
||||
values["pixbuf_options"] = save_cover(values, parent_widget, os.path.join(steam_dir, "appcache", "librarycache", values["appid"] + "_library_600x900.jpg"))
|
||||
save_cover(values, parent_widget, os.path.join(steam_dir, "appcache", "librarycache", values["appid"] + "_library_600x900.jpg"))
|
||||
|
||||
steam_games[values["game_id"]] = values
|
||||
|
||||
|
||||
@@ -68,14 +68,14 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.games_temp = {}
|
||||
self.games = {}
|
||||
self.visible_widgets = {}
|
||||
self.hidden_widgets = {}
|
||||
self.filtered = {}
|
||||
self.hidden_filtered = {}
|
||||
self.previous_page = self.library_view
|
||||
self.toasts = {}
|
||||
self.busy_games = []
|
||||
self.pixbufs = {}
|
||||
|
||||
self.overview.set_measure_overlay(self.overview_box, True)
|
||||
self.overview.set_clip_overlay(self.overview_box, False)
|
||||
@@ -119,16 +119,13 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
||||
|
||||
current_game = current_games[game_id]
|
||||
|
||||
entry = game(self, current_game, get_cover(current_game["game_id"], current_game["pixbuf_options"] if "pixbuf_options" in current_game.keys() else None, self))
|
||||
self.games_temp[current_game["game_id"]] = entry
|
||||
entry = game(self, current_game)
|
||||
self.games[current_game["game_id"]] = entry
|
||||
|
||||
if entry.removed:
|
||||
continue
|
||||
|
||||
if game_id in self.busy_games:
|
||||
continue
|
||||
|
||||
if not self.games_temp[game_id].hidden:
|
||||
if not self.games[game_id].hidden:
|
||||
self.visible_widgets[game_id] = entry
|
||||
self.library.append(entry)
|
||||
else:
|
||||
@@ -212,7 +209,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
||||
return GLib.DateTime.new_from_unix_utc(timestamp).format("%x")
|
||||
|
||||
def show_overview(self, widget, game_id):
|
||||
game = self.games_temp[game_id]
|
||||
game = self.games[game_id]
|
||||
|
||||
if not game.hidden:
|
||||
self.overview_menu_button.set_menu_model(self.game_options)
|
||||
@@ -224,7 +221,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
||||
self.stack.set_visible_child(self.overview)
|
||||
|
||||
self.active_game_id = game_id
|
||||
pixbuf = (self.visible_widgets | self.hidden_widgets)[self.active_game_id].pixbuf
|
||||
pixbuf = get_cover(self.active_game_id, self)
|
||||
self.overview_cover.set_pixbuf(pixbuf)
|
||||
self.overview_blurred_cover.set_pixbuf(pixbuf.scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR))
|
||||
self.overview_title.set_label(game.name)
|
||||
@@ -256,8 +253,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
||||
return self.a_z_sort(child1, child2)
|
||||
|
||||
def newest_sort(self, child1, child2):
|
||||
time1 = self.games_temp[child1.get_first_child().game_id].added
|
||||
time2 = self.games_temp[child2.get_first_child().game_id].added
|
||||
time1 = self.games[child1.get_first_child().game_id].added
|
||||
time2 = self.games[child2.get_first_child().game_id].added
|
||||
if time1 > time2:
|
||||
return -1
|
||||
elif time1 < time2:
|
||||
@@ -266,8 +263,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
||||
return self.a_z_sort(child1, child2)
|
||||
|
||||
def oldest_sort(self, child1, child2):
|
||||
time1 = self.games_temp[child1.get_first_child().game_id].added
|
||||
time2 = self.games_temp[child2.get_first_child().game_id].added
|
||||
time1 = self.games[child1.get_first_child().game_id].added
|
||||
time2 = self.games[child2.get_first_child().game_id].added
|
||||
if time1 > time2:
|
||||
return 1
|
||||
elif time1 < time2:
|
||||
@@ -276,8 +273,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
||||
return self.a_z_sort(child1, child2)
|
||||
|
||||
def last_played_sort(self, child1, child2):
|
||||
time1 = self.games_temp[child1.get_first_child().game_id].last_played
|
||||
time2 = self.games_temp[child2.get_first_child().game_id].last_played
|
||||
time1 = self.games[child1.get_first_child().game_id].last_played
|
||||
time2 = self.games[child2.get_first_child().game_id].last_played
|
||||
if time1 > time2:
|
||||
return -1
|
||||
elif time1 < time2:
|
||||
|
||||
Reference in New Issue
Block a user