Cleanups
This commit is contained in:
119
src/game.py
119
src/game.py
@@ -23,7 +23,6 @@ import os
|
|||||||
from gi.repository import Gio, GLib, Gtk
|
from gi.repository import Gio, GLib, Gtk
|
||||||
|
|
||||||
from .game_cover import GameCover
|
from .game_cover import GameCover
|
||||||
from .save_game import save_game
|
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/hu/kramo/Cartridges/gtk/game.ui")
|
@Gtk.Template(resource_path="/hu/kramo/Cartridges/gtk/game.ui")
|
||||||
@@ -45,36 +44,23 @@ class Game(Gtk.Box):
|
|||||||
loading = 0
|
loading = 0
|
||||||
filtered = False
|
filtered = False
|
||||||
|
|
||||||
|
added = None
|
||||||
|
executable = None
|
||||||
|
game_id = None
|
||||||
|
hidden = None
|
||||||
|
last_played = None
|
||||||
|
name = None
|
||||||
|
developer = None
|
||||||
|
removed = None
|
||||||
|
blacklisted = None
|
||||||
|
|
||||||
def __init__(self, win, data, **kwargs):
|
def __init__(self, win, data, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.win = win
|
self.win = win
|
||||||
self.app = win.get_application()
|
self.app = win.get_application()
|
||||||
|
|
||||||
self.added = data["added"]
|
|
||||||
self.executable = data["executable"]
|
|
||||||
self.game_id = data["game_id"]
|
|
||||||
self.hidden = data["hidden"]
|
|
||||||
self.last_played = data["last_played"]
|
|
||||||
self.name = data["name"]
|
|
||||||
self.developer = data["developer"] if "developer" in data else None
|
|
||||||
self.removed = "removed" in data
|
|
||||||
self.blacklisted = "blacklisted" in data
|
|
||||||
|
|
||||||
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}, self.get_cover_path())
|
|
||||||
self.win.game_covers[self.game_id] = game_cover
|
|
||||||
|
|
||||||
if self.hidden:
|
|
||||||
self.menu_button.set_menu_model(self.hidden_game_options)
|
|
||||||
else:
|
|
||||||
self.menu_button.set_menu_model(self.game_options)
|
|
||||||
|
|
||||||
self.title.set_label(self.name)
|
|
||||||
self.set_play_label()
|
self.set_play_label()
|
||||||
|
|
||||||
self.overlay.set_measure_overlay(self.play_revealer, True)
|
self.overlay.set_measure_overlay(self.play_revealer, True)
|
||||||
|
|
||||||
self.event_contoller_motion = Gtk.EventControllerMotion.new()
|
self.event_contoller_motion = Gtk.EventControllerMotion.new()
|
||||||
@@ -85,12 +71,86 @@ class Game(Gtk.Box):
|
|||||||
self.cover_button.connect("clicked", self.cover_button_clicked)
|
self.cover_button.connect("clicked", self.cover_button_clicked)
|
||||||
self.play_button.connect("clicked", self.play_button_clicked)
|
self.play_button.connect("clicked", self.play_button_clicked)
|
||||||
|
|
||||||
|
self.win.schema.connect("changed", self.schema_changed)
|
||||||
|
|
||||||
|
self.update_values(data)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if self.win.stack.get_visible_child() == self.win.details_view:
|
||||||
|
self.win.show_details_view(None, self.game_id)
|
||||||
|
|
||||||
|
self.win.games[self.game_id] = self
|
||||||
|
|
||||||
|
if self.get_parent():
|
||||||
|
self.get_parent().get_parent().remove(self)
|
||||||
|
if self.get_parent():
|
||||||
|
self.get_parent().set_child()
|
||||||
|
|
||||||
|
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}, self.get_cover_path())
|
||||||
|
self.win.game_covers[self.game_id] = game_cover
|
||||||
|
|
||||||
|
self.menu_button.set_menu_model(
|
||||||
|
self.hidden_game_options if self.hidden else self.game_options
|
||||||
|
)
|
||||||
|
|
||||||
|
self.title.set_label(self.name)
|
||||||
|
|
||||||
self.menu_button.get_popover().connect("notify::visible", self.hide_play)
|
self.menu_button.get_popover().connect("notify::visible", self.hide_play)
|
||||||
self.menu_button.get_popover().connect(
|
self.menu_button.get_popover().connect(
|
||||||
"notify::visible", self.win.set_active_game, self.game_id
|
"notify::visible", self.win.set_active_game, self.game_id
|
||||||
)
|
)
|
||||||
|
|
||||||
self.win.schema.connect("changed", self.schema_changed)
|
if not self.removed or self.blacklisted:
|
||||||
|
if self.hidden:
|
||||||
|
self.win.hidden_library.append(self)
|
||||||
|
else:
|
||||||
|
self.win.library.append(self)
|
||||||
|
self.get_parent().set_focusable(False)
|
||||||
|
|
||||||
|
def update_values(self, data):
|
||||||
|
for key, value in data.items():
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
self.win.games_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
attrs = (
|
||||||
|
"added",
|
||||||
|
"executable",
|
||||||
|
"game_id",
|
||||||
|
"hidden",
|
||||||
|
"last_played",
|
||||||
|
"name",
|
||||||
|
"developer",
|
||||||
|
"removed",
|
||||||
|
"blacklisted",
|
||||||
|
)
|
||||||
|
|
||||||
|
json.dump(
|
||||||
|
{attr: getattr(self, attr) for attr in attrs if attr},
|
||||||
|
(self.win.games_dir / f"{self.game_id}.json").open("w"),
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
self.win.library_bin.set_child(
|
||||||
|
self.win.scrolledwindow
|
||||||
|
if any(not game.hidden for game in self.win.games.values())
|
||||||
|
else self.win.notice_empty
|
||||||
|
)
|
||||||
|
|
||||||
|
self.win.hidden_library_bin.set_child(
|
||||||
|
self.win.hidden_scrolledwindow
|
||||||
|
if any(game.hidden for game in self.win.games.values())
|
||||||
|
else self.win.hidden_notice_empty
|
||||||
|
)
|
||||||
|
|
||||||
def launch(self):
|
def launch(self):
|
||||||
# Generate launch arguments, either list (no shell) or a string (for shell).
|
# Generate launch arguments, either list (no shell) or a string (for shell).
|
||||||
@@ -105,11 +165,8 @@ class Game(Gtk.Box):
|
|||||||
self.app.quit()
|
self.app.quit()
|
||||||
|
|
||||||
def toggle_hidden(self):
|
def toggle_hidden(self):
|
||||||
data = json.load((self.win.games_dir / f"{self.game_id}.json").open())
|
self.hidden = not self.hidden
|
||||||
|
self.save()
|
||||||
data["hidden"] = not data["hidden"]
|
|
||||||
|
|
||||||
save_game(self.win, data)
|
|
||||||
|
|
||||||
def get_cover_path(self):
|
def get_cover_path(self):
|
||||||
cover_path = self.win.covers_dir / f"{self.game_id}.gif"
|
cover_path = self.win.covers_dir / f"{self.game_id}.gif"
|
||||||
@@ -120,6 +177,8 @@ 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)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class GameCover:
|
|||||||
|
|
||||||
def __init__(self, pictures, path=None):
|
def __init__(self, pictures, path=None):
|
||||||
self.pictures = pictures
|
self.pictures = pictures
|
||||||
self.new_pixbuf(path)
|
self.new_cover(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
|
||||||
def create_func(self, path):
|
def create_func(self, path):
|
||||||
@@ -44,7 +44,7 @@ class GameCover:
|
|||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
def new_pixbuf(self, path=None):
|
def new_cover(self, path=None):
|
||||||
self.animation = None
|
self.animation = None
|
||||||
self.pixbuf = None
|
self.pixbuf = None
|
||||||
self.path = path
|
self.path = path
|
||||||
@@ -62,9 +62,6 @@ class GameCover:
|
|||||||
def get_pixbuf(self):
|
def get_pixbuf(self):
|
||||||
return self.animation.get_static_image() if self.animation else self.pixbuf
|
return self.animation.get_static_image() if self.animation else self.pixbuf
|
||||||
|
|
||||||
def get_animation(self):
|
|
||||||
return self.path if self.animation else None
|
|
||||||
|
|
||||||
def add_picture(self, picture):
|
def add_picture(self, picture):
|
||||||
self.pictures.add(picture)
|
self.pictures.add(picture)
|
||||||
if not self.animation:
|
if not self.animation:
|
||||||
|
|||||||
38
src/main.py
38
src/main.py
@@ -30,13 +30,11 @@ from gi.repository import Adw, Gio, GLib, Gtk
|
|||||||
|
|
||||||
from .bottles_importer import bottles_importer
|
from .bottles_importer import bottles_importer
|
||||||
from .create_details_window import create_details_window
|
from .create_details_window import create_details_window
|
||||||
from .get_games import get_games
|
|
||||||
from .heroic_importer import heroic_importer
|
from .heroic_importer import heroic_importer
|
||||||
from .importer import Importer
|
from .importer import Importer
|
||||||
from .itch_importer import itch_importer
|
from .itch_importer import itch_importer
|
||||||
from .lutris_importer import lutris_importer
|
from .lutris_importer import lutris_importer
|
||||||
from .preferences import PreferencesWindow
|
from .preferences import PreferencesWindow
|
||||||
from .save_game import save_game
|
|
||||||
from .steam_importer import steam_importer
|
from .steam_importer import steam_importer
|
||||||
from .window import CartridgesWindow
|
from .window import CartridgesWindow
|
||||||
|
|
||||||
@@ -150,24 +148,13 @@ class CartridgesApplication(Adw.Application):
|
|||||||
|
|
||||||
def on_launch_game_action(self, _widget, _callback=None):
|
def on_launch_game_action(self, _widget, _callback=None):
|
||||||
# Launch the game and update the last played value
|
# Launch the game and update the last played value
|
||||||
|
game = self.win.games[self.win.active_game_id]
|
||||||
|
|
||||||
game_id = self.win.active_game_id
|
game.last_played = int(time.time())
|
||||||
last_played = int(time.time())
|
game.save()
|
||||||
|
game.launch()
|
||||||
|
|
||||||
data = get_games(self.win, {game_id})[game_id]
|
title = game.name
|
||||||
data["last_played"] = last_played
|
|
||||||
save_game(self.win, data)
|
|
||||||
|
|
||||||
self.win.games[game_id].launch()
|
|
||||||
|
|
||||||
# Update state
|
|
||||||
self.win.games[game_id].last_played = last_played
|
|
||||||
self.win.library.invalidate_sort()
|
|
||||||
self.win.hidden_library.invalidate_sort()
|
|
||||||
if self.win.stack.get_visible_child() == self.win.details_view:
|
|
||||||
self.win.show_details_view(None, game_id)
|
|
||||||
|
|
||||||
title = self.win.games[game_id].name
|
|
||||||
# The variable is the title of the game
|
# The variable is the title of the game
|
||||||
toast = Adw.Toast.new(_("{} launched").format(title))
|
toast = Adw.Toast.new(_("{} launched").format(title))
|
||||||
toast.set_priority(Adw.ToastPriority.HIGH)
|
toast.set_priority(Adw.ToastPriority.HIGH)
|
||||||
@@ -180,7 +167,6 @@ class CartridgesApplication(Adw.Application):
|
|||||||
if self.win.stack.get_visible_child() == self.win.details_view:
|
if self.win.stack.get_visible_child() == self.win.details_view:
|
||||||
self.win.on_go_back_action(None, None)
|
self.win.on_go_back_action(None, None)
|
||||||
self.win.games[game_id].toggle_hidden()
|
self.win.games[game_id].toggle_hidden()
|
||||||
self.win.update_games({game_id})
|
|
||||||
|
|
||||||
if not toast:
|
if not toast:
|
||||||
return
|
return
|
||||||
@@ -235,23 +221,21 @@ class CartridgesApplication(Adw.Application):
|
|||||||
|
|
||||||
def on_remove_game_action(self, _widget, _callback=None):
|
def on_remove_game_action(self, _widget, _callback=None):
|
||||||
# Add "removed=True" to the game properties so it can be deleted on next init
|
# Add "removed=True" to the game properties so it can be deleted on next init
|
||||||
game_id = self.win.active_game_id
|
game = self.win.games[self.win.active_game_id]
|
||||||
|
|
||||||
data = get_games(self.win, {game_id})[game_id]
|
game.removed = True
|
||||||
data["removed"] = True
|
game.save()
|
||||||
save_game(self.win, data)
|
|
||||||
|
|
||||||
self.win.update_games({game_id})
|
|
||||||
if self.win.stack.get_visible_child() == self.win.details_view:
|
if self.win.stack.get_visible_child() == self.win.details_view:
|
||||||
self.win.on_go_back_action(None, None)
|
self.win.on_go_back_action(None, None)
|
||||||
|
|
||||||
title = self.win.games[game_id].name
|
title = game.name
|
||||||
# The variable is the title of the game
|
# The variable is the title of the game
|
||||||
toast = Adw.Toast.new(_("{} removed").format(title))
|
toast = Adw.Toast.new(_("{} removed").format(title))
|
||||||
toast.set_button_label(_("Undo"))
|
toast.set_button_label(_("Undo"))
|
||||||
toast.connect("button-clicked", self.win.on_undo_action, game_id, "remove")
|
toast.connect("button-clicked", self.win.on_undo_action, game.game_id, "remove")
|
||||||
toast.set_priority(Adw.ToastPriority.HIGH)
|
toast.set_priority(Adw.ToastPriority.HIGH)
|
||||||
self.win.toasts[(game_id, "remove")] = toast
|
self.win.toasts[(game.game_id, "remove")] = toast
|
||||||
self.win.toast_overlay.add_toast(toast)
|
self.win.toast_overlay.add_toast(toast)
|
||||||
|
|
||||||
def on_remove_game_details_view_action(self, _widget, _callback=None):
|
def on_remove_game_details_view_action(self, _widget, _callback=None):
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ cartridges_sources = [
|
|||||||
'utils/importer.py',
|
'utils/importer.py',
|
||||||
'utils/steamgriddb.py',
|
'utils/steamgriddb.py',
|
||||||
'utils/get_games.py',
|
'utils/get_games.py',
|
||||||
'utils/save_game.py',
|
|
||||||
'utils/save_cover.py',
|
'utils/save_cover.py',
|
||||||
'utils/create_dialog.py',
|
'utils/create_dialog.py',
|
||||||
'utils/create_details_window.py',
|
'utils/create_details_window.py',
|
||||||
|
|||||||
@@ -24,11 +24,9 @@ from gi.repository import Adw, Gio, GLib, Gtk
|
|||||||
|
|
||||||
from .bottles_importer import bottles_installed
|
from .bottles_importer import bottles_installed
|
||||||
from .create_dialog import create_dialog
|
from .create_dialog import create_dialog
|
||||||
from .get_games import get_games
|
|
||||||
from .heroic_importer import heroic_installed
|
from .heroic_importer import heroic_installed
|
||||||
from .itch_importer import itch_installed
|
from .itch_importer import itch_installed
|
||||||
from .lutris_importer import lutris_cache_exists, lutris_installed
|
from .lutris_importer import lutris_cache_exists, lutris_installed
|
||||||
from .save_game import save_game
|
|
||||||
from .steam_importer import steam_installed
|
from .steam_importer import steam_installed
|
||||||
|
|
||||||
|
|
||||||
@@ -335,23 +333,20 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
|
|
||||||
def undo_remove_all(self, _widget, _unused):
|
def undo_remove_all(self, _widget, _unused):
|
||||||
for game_id in self.removed_games:
|
for game_id in self.removed_games:
|
||||||
data = get_games(self.win, {game_id})[game_id]
|
self.win.games[game_id].removed = False
|
||||||
if "removed" in data:
|
self.win.games[game_id].save()
|
||||||
data.pop("removed")
|
|
||||||
save_game(self.win, data)
|
|
||||||
|
|
||||||
self.win.update_games(self.removed_games)
|
|
||||||
self.removed_games = set()
|
self.removed_games = set()
|
||||||
self.toast.dismiss()
|
self.toast.dismiss()
|
||||||
|
|
||||||
def remove_all_games(self, _widget):
|
def remove_all_games(self, _widget):
|
||||||
for game in get_games(self.win).values():
|
for game in self.win.games:
|
||||||
if "removed" not in game:
|
if not game.removed:
|
||||||
self.removed_games.add(game["game_id"])
|
self.removed_games.add(game.game_id)
|
||||||
game["removed"] = True
|
|
||||||
save_game(self.win, game)
|
game.removed = True
|
||||||
|
game.save()
|
||||||
|
|
||||||
self.win.update_games(self.win.games)
|
|
||||||
if self.win.stack.get_visible_child() == self.win.details_view:
|
if self.win.stack.get_visible_child() == self.win.details_view:
|
||||||
self.win.on_go_back_action(None, None)
|
self.win.on_go_back_action(None, None)
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ from gi.repository import Adw, Gio, GLib, GObject, Gtk
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .create_dialog import create_dialog
|
from .create_dialog import create_dialog
|
||||||
|
from .game import Game
|
||||||
from .game_cover import GameCover
|
from .game_cover import GameCover
|
||||||
from .save_cover import resize_cover, save_cover
|
from .save_cover import resize_cover, save_cover
|
||||||
from .save_game import save_game
|
|
||||||
from .steamgriddb import SGDBSave
|
from .steamgriddb import SGDBSave
|
||||||
|
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ def create_details_window(win, game_id=None):
|
|||||||
nonlocal game_cover
|
nonlocal game_cover
|
||||||
nonlocal cover_changed
|
nonlocal cover_changed
|
||||||
|
|
||||||
game_cover.new_pixbuf()
|
game_cover.new_cover()
|
||||||
|
|
||||||
cover_button_delete_revealer.set_reveal_child(False)
|
cover_button_delete_revealer.set_reveal_child(False)
|
||||||
cover_changed = True
|
cover_changed = True
|
||||||
@@ -89,7 +89,7 @@ def create_details_window(win, game_id=None):
|
|||||||
)
|
)
|
||||||
apply_button = Gtk.Button.new_with_label(_("Apply"))
|
apply_button = Gtk.Button.new_with_label(_("Apply"))
|
||||||
|
|
||||||
game_cover.new_pixbuf(win.games[game_id].get_cover_path())
|
game_cover.new_cover(win.games[game_id].get_cover_path())
|
||||||
if game_cover.get_pixbuf():
|
if game_cover.get_pixbuf():
|
||||||
cover_button_delete_revealer.set_reveal_child(True)
|
cover_button_delete_revealer.set_reveal_child(True)
|
||||||
else:
|
else:
|
||||||
@@ -233,7 +233,7 @@ def create_details_window(win, game_id=None):
|
|||||||
cover_button_delete_revealer.set_reveal_child(True)
|
cover_button_delete_revealer.set_reveal_child(True)
|
||||||
cover_changed = True
|
cover_changed = True
|
||||||
|
|
||||||
game_cover.new_pixbuf(resize_cover(win, path))
|
game_cover.new_cover(resize_cover(win, path))
|
||||||
|
|
||||||
def close_window(_widget, _callback=None):
|
def close_window(_widget, _callback=None):
|
||||||
window.close()
|
window.close()
|
||||||
@@ -323,16 +323,10 @@ def create_details_window(win, game_id=None):
|
|||||||
game_cover.path,
|
game_cover.path,
|
||||||
)
|
)
|
||||||
|
|
||||||
path = win.games_dir / f"{game_id}.json"
|
if game_id in win.games:
|
||||||
|
win.games[game_id].update_values(values)
|
||||||
if path.exists():
|
|
||||||
data = json.load(path.open())
|
|
||||||
data.update(values)
|
|
||||||
save_game(win, data)
|
|
||||||
else:
|
else:
|
||||||
save_game(win, values)
|
Game(win, values).save()
|
||||||
|
|
||||||
win.update_games({game_id})
|
|
||||||
|
|
||||||
if not game_cover.get_pixbuf():
|
if not game_cover.get_pixbuf():
|
||||||
SGDBSave(win, {(game_id, values["name"])})
|
SGDBSave(win, {(game_id, values["name"])})
|
||||||
|
|||||||
@@ -20,16 +20,10 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def get_games(win, game_ids=None):
|
def get_games(win):
|
||||||
games = {}
|
games = {}
|
||||||
|
|
||||||
game_files = (
|
for open_file in win.games_dir.iterdir():
|
||||||
{win.games_dir / f"{game_id}.json" for game_id in game_ids}
|
|
||||||
if game_ids
|
|
||||||
else win.games_dir.iterdir()
|
|
||||||
)
|
|
||||||
|
|
||||||
for open_file in game_files:
|
|
||||||
if open_file.exists():
|
if open_file.exists():
|
||||||
data = json.load(open_file.open())
|
data = json.load(open_file.open())
|
||||||
games[data["game_id"]] = data
|
games[data["game_id"]] = data
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ from pathlib import Path
|
|||||||
from gi.repository import Adw, Gtk
|
from gi.repository import Adw, Gtk
|
||||||
|
|
||||||
from .create_dialog import create_dialog
|
from .create_dialog import create_dialog
|
||||||
|
from .game import Game
|
||||||
from .save_cover import resize_cover, save_cover
|
from .save_cover import resize_cover, save_cover
|
||||||
from .save_game import save_game
|
|
||||||
from .steamgriddb import SGDBSave
|
from .steamgriddb import SGDBSave
|
||||||
|
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ class Importer:
|
|||||||
|
|
||||||
def save_game(self, values=None, cover_path=None):
|
def save_game(self, values=None, cover_path=None):
|
||||||
if values:
|
if values:
|
||||||
save_game(self.win, values)
|
Game(self.win, values).save()
|
||||||
|
|
||||||
if cover_path:
|
if cover_path:
|
||||||
save_cover(
|
save_cover(
|
||||||
@@ -66,7 +66,7 @@ class Importer:
|
|||||||
self.games.add((values["game_id"], values["name"]))
|
self.games.add((values["game_id"], values["name"]))
|
||||||
|
|
||||||
self.games_no += 1
|
self.games_no += 1
|
||||||
if "blacklisted" in values:
|
if values.get("blacklisted"):
|
||||||
self.games_no -= 1
|
self.games_no -= 1
|
||||||
|
|
||||||
self.queue -= 1
|
self.queue -= 1
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from PIL import Image, ImageSequence
|
|||||||
|
|
||||||
def resize_cover(win, cover_path=None, pixbuf=None):
|
def resize_cover(win, cover_path=None, pixbuf=None):
|
||||||
if not cover_path and not pixbuf:
|
if not cover_path and not pixbuf:
|
||||||
return
|
return None
|
||||||
|
|
||||||
if pixbuf:
|
if pixbuf:
|
||||||
cover_path = Path(Gio.File.new_tmp("XXXXXX.tiff")[0].get_path())
|
cover_path = Path(Gio.File.new_tmp("XXXXXX.tiff")[0].get_path())
|
||||||
@@ -65,6 +65,9 @@ def resize_cover(win, cover_path=None, pixbuf=None):
|
|||||||
|
|
||||||
|
|
||||||
def save_cover(win, game_id, cover_path):
|
def save_cover(win, game_id, cover_path):
|
||||||
|
if not cover_path:
|
||||||
|
return
|
||||||
|
|
||||||
win.covers_dir.mkdir(parents=True, exist_ok=True)
|
win.covers_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
animated_path = win.covers_dir / f"{game_id}.gif"
|
animated_path = win.covers_dir / f"{game_id}.gif"
|
||||||
@@ -80,7 +83,6 @@ def save_cover(win, game_id, cover_path):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if game_id in win.game_covers:
|
if game_id in win.game_covers:
|
||||||
win.game_covers[game_id].new_pixbuf(
|
win.game_covers[game_id].new_cover(
|
||||||
animated_path if cover_path.suffix == ".gif" else static_path
|
animated_path if cover_path.suffix == ".gif" else static_path
|
||||||
)
|
)
|
||||||
return
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
# save_game.py
|
|
||||||
#
|
|
||||||
# Copyright 2022-2023 kramo
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
|
|
||||||
def save_game(win, game):
|
|
||||||
win.games_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
(win.games_dir / f'{game["game_id"]}.json').write_text(
|
|
||||||
json.dumps(game, indent=4, sort_keys=True), "utf-8"
|
|
||||||
)
|
|
||||||
@@ -111,8 +111,10 @@ class SGDBSave:
|
|||||||
_("Preferences"),
|
_("Preferences"),
|
||||||
).connect("response", self.response)
|
).connect("response", self.response)
|
||||||
|
|
||||||
game_id = result.propagate_value()[1]
|
if not self.importer:
|
||||||
self.win.update_games({game_id})
|
game = self.win.games[result.propagate_value()[1]]
|
||||||
|
game.set_loading(-1)
|
||||||
|
game.update()
|
||||||
|
|
||||||
def response(self, _widget, response):
|
def response(self, _widget, response):
|
||||||
if response == "open_preferences":
|
if response == "open_preferences":
|
||||||
|
|||||||
@@ -19,14 +19,13 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
from struct import unpack_from
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from struct import unpack_from
|
||||||
|
|
||||||
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 .get_games import get_games
|
from .get_games import get_games
|
||||||
from .save_game import save_game
|
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/hu/kramo/Cartridges/gtk/window.ui")
|
@Gtk.Template(resource_path="/hu/kramo/Cartridges/gtk/window.ui")
|
||||||
@@ -107,9 +106,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
)
|
)
|
||||||
self.image_size = (200 * scale_factor, 300 * scale_factor)
|
self.image_size = (200 * scale_factor, 300 * scale_factor)
|
||||||
|
|
||||||
games = get_games(self)
|
for game_id, game in get_games(self).items():
|
||||||
for game_id in games:
|
if game.get("removed"):
|
||||||
if "removed" in games[game_id]:
|
|
||||||
(self.games_dir / f"{game_id}.json").unlink(missing_ok=True)
|
(self.games_dir / f"{game_id}.json").unlink(missing_ok=True)
|
||||||
(self.covers_dir / f"{game_id}.tiff").unlink(missing_ok=True)
|
(self.covers_dir / f"{game_id}.tiff").unlink(missing_ok=True)
|
||||||
(self.covers_dir / f"{game_id}.gif").unlink(missing_ok=True)
|
(self.covers_dir / f"{game_id}.gif").unlink(missing_ok=True)
|
||||||
@@ -123,7 +121,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
self.library.set_sort_func(self.sort_func)
|
self.library.set_sort_func(self.sort_func)
|
||||||
self.hidden_library.set_sort_func(self.sort_func)
|
self.hidden_library.set_sort_func(self.sort_func)
|
||||||
|
|
||||||
self.update_games(get_games(self))
|
for game in get_games(self).values():
|
||||||
|
Game(self, game).update()
|
||||||
|
|
||||||
# Connect signals
|
# Connect signals
|
||||||
self.search_entry.connect("search-changed", self.search_changed, False)
|
self.search_entry.connect("search-changed", self.search_changed, False)
|
||||||
@@ -140,41 +139,6 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
"notify::high-contrast", self.set_details_view_opacity
|
"notify::high-contrast", self.set_details_view_opacity
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_games(self, games):
|
|
||||||
for game_id in games:
|
|
||||||
if game_id in self.games and self.games[game_id].get_parent():
|
|
||||||
self.games[game_id].get_parent().get_parent().remove(
|
|
||||||
self.games[game_id]
|
|
||||||
)
|
|
||||||
|
|
||||||
entry = Game(self, get_games(self, {game_id})[game_id])
|
|
||||||
self.games[game_id] = entry
|
|
||||||
|
|
||||||
if entry.removed or entry.blacklisted:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if entry.hidden:
|
|
||||||
self.hidden_library.append(entry)
|
|
||||||
else:
|
|
||||||
self.library.append(entry)
|
|
||||||
|
|
||||||
entry.get_parent().set_focusable(False)
|
|
||||||
|
|
||||||
self.library_bin.set_child(
|
|
||||||
self.scrolledwindow
|
|
||||||
if any(not game.hidden for game in self.games.values())
|
|
||||||
else self.notice_empty
|
|
||||||
)
|
|
||||||
|
|
||||||
self.hidden_library_bin.set_child(
|
|
||||||
self.hidden_scrolledwindow
|
|
||||||
if any(game.hidden for game in self.games.values())
|
|
||||||
else self.hidden_notice_empty
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.stack.get_visible_child() == self.details_view:
|
|
||||||
self.show_details_view(None, self.active_game_id)
|
|
||||||
|
|
||||||
def search_changed(self, _widget, hidden):
|
def search_changed(self, _widget, hidden):
|
||||||
# Refresh search filter on keystroke in search box
|
# Refresh search filter on keystroke in search box
|
||||||
if hidden:
|
if hidden:
|
||||||
@@ -190,14 +154,15 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
.lower()
|
.lower()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
game = child.get_child()
|
||||||
|
|
||||||
filtered = text != "" and not (
|
filtered = text != "" and not (
|
||||||
text in child.get_first_child().name.lower()
|
text in game.name.lower() or text in game.developer.lower()
|
||||||
or text in child.get_first_child().developer.lower()
|
if game.developer
|
||||||
if child.get_first_child().developer
|
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
||||||
child.get_first_child().filtered = filtered
|
game.filtered = filtered
|
||||||
|
|
||||||
(self.hidden_library_bin if hidden else self.library_bin).set_child(
|
(self.hidden_library_bin if hidden else self.library_bin).set_child(
|
||||||
(self.hidden_scrolledwindow if hidden else self.scrolledwindow)
|
(self.hidden_scrolledwindow if hidden else self.scrolledwindow)
|
||||||
@@ -327,7 +292,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def sort_func(self, child1, child2):
|
def sort_func(self, child1, child2):
|
||||||
games = (child1.get_first_child(), child2.get_first_child())
|
games = (child1.get_child(), child2.get_child())
|
||||||
var, order = "name", True
|
var, order = "name", True
|
||||||
|
|
||||||
if self.sort_state in ("newest", "oldest"):
|
if self.sort_state in ("newest", "oldest"):
|
||||||
@@ -437,10 +402,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
elif undo == "remove":
|
elif undo == "remove":
|
||||||
data = get_games(self, {game_id})[game_id]
|
self.games[game_id].removed = False
|
||||||
data.pop("removed", None)
|
self.games[game_id].save()
|
||||||
save_game(self, data)
|
|
||||||
self.update_games({game_id})
|
|
||||||
|
|
||||||
self.toasts[(game_id, undo)].dismiss()
|
self.toasts[(game_id, undo)].dismiss()
|
||||||
self.toasts.pop((game_id, undo))
|
self.toasts.pop((game_id, undo))
|
||||||
|
|||||||
Reference in New Issue
Block a user