This commit is contained in:
kramo
2023-04-11 23:31:16 +02:00
parent cebf080619
commit fd66d07ac3
18 changed files with 162 additions and 135 deletions

View File

@@ -30,13 +30,14 @@ from .save_game import save_game
@Gtk.Template(resource_path="/hu/kramo/Cartridges/gtk/game.ui")
class game(Gtk.Box): # pylint: disable=invalid-name
__gtype_name__ = "game"
class Game(Gtk.Box):
__gtype_name__ = "Game"
overlay = Gtk.Template.Child()
title = Gtk.Template.Child()
play_button = Gtk.Template.Child()
cover = Gtk.Template.Child()
spinner = Gtk.Template.Child()
cover_button = Gtk.Template.Child()
menu_button = Gtk.Template.Child()
play_revealer = Gtk.Template.Child()
@@ -58,10 +59,11 @@ class game(Gtk.Box): # pylint: disable=invalid-name
self.removed = "removed" in data
self.blacklisted = "blacklisted" in data
self.game_cover = GameCover(self.cover, path=self.get_cover_path())
self.loading = 0
self.title.set_label(self.name)
self.game_cover = GameCover(self.cover, path=self.get_cover_path())
self.event_contoller_motion = Gtk.EventControllerMotion.new()
self.add_controller(self.event_contoller_motion)
self.overlay.set_measure_overlay(self.play_revealer, True)
@@ -105,7 +107,9 @@ class game(Gtk.Box): # pylint: disable=invalid-name
sys.exit()
def toggle_hidden(self):
data = json.loads((self.games_dir / f"{self.game_id}.json").read_text("utf-8"))
data = json.loads(
(self.parent_widget.games_dir / f"{self.game_id}.json").read_text("utf-8")
)
data["hidden"] = not data["hidden"]
@@ -139,11 +143,11 @@ class game(Gtk.Box): # pylint: disable=invalid-name
if self.parent_widget.schema.get_boolean("cover-launches-game"):
self.launch_game(None)
else:
self.parent_widget.show_overview(None, self.game_id)
self.parent_widget.show_details_view(None, self.game_id)
def play_button_clicked(self, _widget):
if self.parent_widget.schema.get_boolean("cover-launches-game"):
self.parent_widget.show_overview(None, self.game_id)
self.parent_widget.show_details_view(None, self.game_id)
else:
self.launch_game(None)
@@ -156,3 +160,10 @@ class game(Gtk.Box): # pylint: disable=invalid-name
def schema_changed(self, _settings, key):
if key == "cover-launches-game":
self.set_play_label()
def set_loading(self, state):
self.loading += state
loading = self.loading > 0
self.cover.set_opacity(int(not loading))
self.spinner.set_spinning(loading)

View File

@@ -1,4 +1,4 @@
# bottles_parser.py
# bottles_importer.py
#
# Copyright 2022-2023 kramo
#
@@ -23,7 +23,7 @@ from time import time
import yaml
def bottles_parser(parent_widget):
def bottles_importer(parent_widget):
schema = parent_widget.schema
bottles_dir = Path(schema.get_string("bottles-location")).expanduser()

View File

@@ -1,4 +1,4 @@
# heroic_parser.py
# heroic_importer.py
#
# Copyright 2022-2023 kramo
#
@@ -24,7 +24,7 @@ from pathlib import Path
from time import time
def heroic_parser(parent_widget):
def heroic_importer(parent_widget):
schema = parent_widget.schema
heroic_dir = Path(schema.get_string("heroic-location")).expanduser()

View File

@@ -1,4 +1,4 @@
# itch_parser.py
# itch_importer.py
#
# Copyright 2022-2023 kramo
#
@@ -115,7 +115,7 @@ def get_games_async(parent_widget, rows, importer):
task.run_in_thread(create_func(current_time, parent_widget, row))
def itch_parser(parent_widget):
def itch_importer(parent_widget):
schema = parent_widget.schema
database_path = (Path(schema.get_string("itch-location")) / "db").expanduser()

View File

@@ -1,4 +1,4 @@
# lutris_parser.py
# lutris_importer.py
#
# Copyright 2022-2023 kramo
#
@@ -23,8 +23,7 @@ from sqlite3 import connect
from time import time
def lutris_parser(parent_widget):
def lutris_importer(parent_widget):
schema = parent_widget.schema
database_path = (Path(schema.get_string("lutris-location"))).expanduser()

View File

@@ -1,4 +1,4 @@
# steam_parser.py
# steam_importer.py
#
# Copyright 2022-2023 kramo
#
@@ -123,7 +123,7 @@ def get_games_async(parent_widget, appmanifests, steam_dir, importer):
)
def steam_parser(parent_widget):
def steam_importer(parent_widget):
schema = parent_widget.schema
steam_dir = Path(schema.get_string("steam-location")).expanduser()
@@ -150,7 +150,7 @@ def steam_parser(parent_widget):
schema.set_string("steam-location", str(steam_dir / "Steam"))
else:
steam_not_found()
steam_parser(parent_widget)
steam_importer(parent_widget)
return
steam_dir = Path(schema.get_string("steam-location")).expanduser()

View File

@@ -28,16 +28,16 @@ gi.require_version("Adw", "1")
# pylint: disable=wrong-import-position
from gi.repository import Adw, Gio, GLib, Gtk
from .bottles_parser import bottles_parser
from .bottles_importer import bottles_importer
from .create_details_window import create_details_window
from .get_games import get_games
from .heroic_parser import heroic_parser
from .heroic_importer import heroic_importer
from .importer import Importer
from .itch_parser import itch_parser
from .lutris_parser import lutris_parser
from .itch_importer import itch_importer
from .lutris_importer import lutris_importer
from .preferences import PreferencesWindow
from .save_game import save_game
from .steam_parser import steam_parser
from .steam_importer import steam_importer
from .window import CartridgesWindow
@@ -57,7 +57,9 @@ class CartridgesApplication(Adw.Application):
self.create_action("add_game", self.on_add_game_action, ["<primary>n"])
self.create_action("import", self.on_import_action, ["<primary>i"])
self.create_action(
"remove_game_overview", self.on_remove_game_overview_action, ["Delete"]
"remove_game_details_view",
self.on_remove_game_details_view_action,
["Delete"],
)
self.create_action("remove_game", self.on_remove_game_action)
self.create_action("igdb_search", self.on_igdb_search_action)
@@ -121,8 +123,10 @@ class CartridgesApplication(Adw.Application):
developers=[
"kramo https://kramo.hu",
"Paweł Lidwin https://github.com/imLinguin",
"Domenico https://github.com/Domefemia",
"Bananaman https://github.com/Bananaman",
"Geoffrey Coulaud https://geoffrey-coulaud.fr",
"Rafael Mardojai CM https://mardojai.com",
],
designers=["kramo https://kramo.hu"],
copyright="© 2022-2023 kramo",
@@ -167,7 +171,7 @@ class CartridgesApplication(Adw.Application):
if not game_id:
game_id = self.win.active_game_id
if self.win.stack.get_visible_child() == self.win.overview:
if self.win.stack.get_visible_child() == self.win.details_view:
self.win.on_go_back_action(None, None)
self.win.games[game_id].toggle_hidden()
self.win.update_games([game_id])
@@ -200,19 +204,19 @@ class CartridgesApplication(Adw.Application):
self.win.importer.blocker = True
if self.win.schema.get_boolean("steam"):
steam_parser(self.win)
steam_importer(self.win)
if self.win.schema.get_boolean("lutris"):
lutris_parser(self.win)
lutris_importer(self.win)
if self.win.schema.get_boolean("heroic"):
heroic_parser(self.win)
heroic_importer(self.win)
if self.win.schema.get_boolean("bottles"):
bottles_parser(self.win)
bottles_importer(self.win)
if self.win.schema.get_boolean("itch"):
itch_parser(self.win)
itch_importer(self.win)
self.win.importer.blocker = False
@@ -229,7 +233,7 @@ class CartridgesApplication(Adw.Application):
save_game(self.win, data)
self.win.update_games([game_id])
if self.win.stack.get_visible_child() == self.win.overview:
if self.win.stack.get_visible_child() == self.win.details_view:
self.win.on_go_back_action(None, None)
title = self.win.games[game_id].name
@@ -241,8 +245,8 @@ class CartridgesApplication(Adw.Application):
self.win.toasts[(game_id, "remove")] = toast
self.win.toast_overlay.add_toast(toast)
def on_remove_game_overview_action(self, _widget, _callback=None):
if self.win.stack.get_visible_child() == self.win.overview:
def on_remove_game_details_view_action(self, _widget, _callback=None):
if self.win.stack.get_visible_child() == self.win.details_view:
self.on_remove_game_action(None)
def on_quit_action(self, _widget, _callback=None):

View File

@@ -23,13 +23,13 @@ cartridges_sources = [
'preferences.py',
'game.py',
'game_cover.py',
'importers/steam_importer.py',
'importers/lutris_importer.py',
'importers/heroic_importer.py',
'importers/bottles_importer.py',
'importers/itch_importer.py',
'utils/importer.py',
'utils/steamgriddb.py',
'utils/steam_parser.py',
'utils/lutris_parser.py',
'utils/heroic_parser.py',
'utils/bottles_parser.py',
'utils/itch_parser.py',
'utils/get_games.py',
'utils/save_game.py',
'utils/save_cover.py',

View File

@@ -19,7 +19,7 @@
import os
from pathlib import Path
from shutil import move
from shutil import move, copyfile
from gi.repository import Adw, Gio, GLib, Gtk
@@ -367,7 +367,7 @@ class PreferencesWindow(Adw.PreferencesWindow):
if not cover_path.is_file():
continue
move(cover_path, self.parent_widget.covers_dir)
move(cover_path, self.parent_widget.covers_dir, copyfile)
self.parent_widget.update_games(self.removed_games)
self.removed_games = []
@@ -386,12 +386,17 @@ class PreferencesWindow(Adw.PreferencesWindow):
save_game(self.parent_widget, game)
cover_path = self.parent_widget.games[game["game_id"]].get_cover_path()
if not cover_path:
continue
if cover_path.is_file():
move(cover_path, deleted_covers_dir)
move(cover_path, deleted_covers_dir, copyfile)
self.parent_widget.update_games(self.parent_widget.games)
if self.parent_widget.stack.get_visible_child() == self.parent_widget.overview:
if (
self.parent_widget.stack.get_visible_child()
== self.parent_widget.details_view
):
self.parent_widget.on_go_back_action(None, None)
self.add_toast(self.toast)

View File

@@ -317,9 +317,6 @@ def create_details_window(parent_widget, game_id=None):
(parent_widget.covers_dir / f"{game_id}.tiff").unlink(missing_ok=True)
(parent_widget.covers_dir / f"{game_id}.gif").unlink(missing_ok=True)
if not game_cover.get_pixbuf():
SGDBSave(parent_widget, {(game_id, values["name"])})
save_cover(
parent_widget,
game_id,
@@ -337,9 +334,13 @@ def create_details_window(parent_widget, game_id=None):
else:
save_game(parent_widget, values)
parent_widget.update_games([game_id])
if game_cover.get_pixbuf():
parent_widget.update_games([game_id])
else:
SGDBSave(parent_widget, {(game_id, values["name"])})
window.close()
parent_widget.show_overview(None, game_id)
parent_widget.show_details_view(None, game_id)
def focus_executable(_widget):
window.set_focus(executable)

View File

@@ -35,7 +35,7 @@ class SGDBSave:
)
):
if not self.importer:
self.parent_widget.loading = game[0]
self.parent_widget.games[game[0]].set_loading(1)
url = "https://www.steamgriddb.com/api/v2/"
headers = {
@@ -106,8 +106,6 @@ class SGDBSave:
self.importer.queue -= 1
self.importer.done()
self.importer.sgdb_exception = self.exception
else:
self.parent_widget.loading = None
if self.exception:
create_dialog(

View File

@@ -25,7 +25,7 @@ from shutil import rmtree
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 .save_game import save_game
@@ -38,7 +38,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
toast_overlay = Gtk.Template.Child()
primary_menu_button = Gtk.Template.Child()
stack = Gtk.Template.Child()
overview = Gtk.Template.Child()
details_view = Gtk.Template.Child()
library_view = Gtk.Template.Child()
library = Gtk.Template.Child()
scrolledwindow = Gtk.Template.Child()
@@ -49,17 +49,17 @@ class CartridgesWindow(Adw.ApplicationWindow):
search_entry = Gtk.Template.Child()
search_button = Gtk.Template.Child()
overview_box = Gtk.Template.Child()
overview_cover = Gtk.Template.Child()
overview_spinner = Gtk.Template.Child()
overview_title = Gtk.Template.Child()
overview_header_bar_title = Gtk.Template.Child()
overview_play_button = Gtk.Template.Child()
overview_blurred_cover = Gtk.Template.Child()
overview_developer = Gtk.Template.Child()
overview_added = Gtk.Template.Child()
overview_last_played = Gtk.Template.Child()
overview_hide_button = Gtk.Template.Child()
details_view_box = Gtk.Template.Child()
details_view_cover = Gtk.Template.Child()
details_view_spinner = Gtk.Template.Child()
details_view_title = Gtk.Template.Child()
details_view_header_bar_title = Gtk.Template.Child()
details_view_play_button = Gtk.Template.Child()
details_view_blurred_cover = Gtk.Template.Child()
details_view_developer = Gtk.Template.Child()
details_view_added = Gtk.Template.Child()
details_view_last_played = Gtk.Template.Child()
details_view_hide_button = Gtk.Template.Child()
hidden_library = Gtk.Template.Child()
hidden_library_view = Gtk.Template.Child()
@@ -100,11 +100,10 @@ class CartridgesWindow(Adw.ApplicationWindow):
self.previous_page = self.library_view
self.toasts = {}
self.active_game_id = None
self.loading = None
self.scaled_pixbuf = None
self.overview.set_measure_overlay(self.overview_box, True)
self.overview.set_clip_overlay(self.overview_box, False)
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")
scale_factor = max(
@@ -127,7 +126,12 @@ class CartridgesWindow(Adw.ApplicationWindow):
self.update_games(get_games(self))
self.overview_game_cover = GameCover(self.overview_cover)
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)
@@ -138,10 +142,10 @@ class CartridgesWindow(Adw.ApplicationWindow):
self.add_controller(back_mouse_button)
Adw.StyleManager.get_default().connect(
"notify::dark", self.set_overview_opacity
"notify::dark", self.set_details_view_opacity
)
Adw.StyleManager.get_default().connect(
"notify::high-contrast", self.set_overview_opacity
"notify::high-contrast", self.set_details_view_opacity
)
def update_games(self, games):
@@ -159,7 +163,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
current_game = current_games[game_id]
entry = game(self, current_game)
entry = Game(self, current_game)
self.games[current_game["game_id"]] = entry
if entry.removed:
@@ -189,8 +193,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
else:
self.hidden_library_bin.set_child(self.hidden_scrolledwindow)
if self.stack.get_visible_child() == self.overview:
self.show_overview(None, self.active_game_id)
if self.stack.get_visible_child() == self.details_view:
self.show_details_view(None, self.active_game_id)
self.library.invalidate_filter()
self.hidden_library.invalidate_filter()
@@ -262,46 +266,46 @@ class CartridgesWindow(Adw.ApplicationWindow):
return GLib.DateTime.new_from_unix_utc(timestamp).format("%A")
return GLib.DateTime.new_from_unix_utc(timestamp).format("%x")
def show_overview(self, _widget, game_id):
loading = game_id == self.loading
self.overview_cover.set_visible(not loading)
self.overview_spinner.set_spinning(loading)
def show_details_view(self, _widget, game_id):
current_game = self.games[game_id]
self.details_view_cover.set_visible(not current_game.loading)
self.details_view_spinner.set_spinning(current_game.loading)
if current_game.developer:
self.overview_developer.set_label(current_game.developer)
self.overview_developer.set_visible(True)
self.details_view_developer.set_label(current_game.developer)
self.details_view_developer.set_visible(True)
else:
self.overview_developer.set_visible(False)
self.details_view_developer.set_visible(False)
if current_game.hidden:
self.overview_hide_button.set_icon_name("view-reveal-symbolic")
self.overview_hide_button.set_tooltip_text(_("Unhide"))
self.details_view_hide_button.set_icon_name("view-reveal-symbolic")
self.details_view_hide_button.set_tooltip_text(_("Unhide"))
else:
self.overview_hide_button.set_icon_name("view-conceal-symbolic")
self.overview_hide_button.set_tooltip_text(_("Hide"))
self.details_view_hide_button.set_icon_name("view-conceal-symbolic")
self.details_view_hide_button.set_tooltip_text(_("Hide"))
if self.stack.get_visible_child() != self.overview:
if self.stack.get_visible_child() != self.details_view:
self.stack.set_transition_type(Gtk.StackTransitionType.OVER_LEFT)
self.stack.set_visible_child(self.overview)
self.stack.set_visible_child(self.details_view)
self.active_game_id = game_id
self.overview_game_cover.new_pixbuf(path=current_game.get_cover_path())
pixbuf = (
self.overview_game_cover.get_pixbuf()
or self.overview_game_cover.placeholder_pixbuf
self.details_view_game_cover.new_pixbuf(path=current_game.get_cover_path())
pixbuf = self.details_view_game_cover.get_pixbuf()
self.scaled_pixbuf = (
pixbuf.scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR)
if pixbuf
else self.placeholder_pixbuf_scaled
)
self.details_view_blurred_cover.set_pixbuf(self.scaled_pixbuf)
self.set_details_view_opacity()
self.scaled_pixbuf = pixbuf.scale_simple(2, 3, GdkPixbuf.InterpType.BILINEAR)
self.overview_blurred_cover.set_pixbuf(self.scaled_pixbuf)
self.set_overview_opacity()
self.overview_title.set_label(current_game.name)
self.overview_header_bar_title.set_title(current_game.name)
self.details_view_title.set_label(current_game.name)
self.details_view_header_bar_title.set_title(current_game.name)
date = self.get_time(current_game.added)
self.overview_added.set_label(
self.details_view_added.set_label(
# The variable is the date when the game was added
_("Added: {}").format(date)
)
@@ -310,20 +314,20 @@ class CartridgesWindow(Adw.ApplicationWindow):
if current_game.last_played != 0
else _("Never")
)
self.overview_last_played.set_label(
self.details_view_last_played.set_label(
# The variable is the date when the game was last played
_("Last played: {}").format(last_played_date)
)
def set_overview_opacity(self, _widget=None, _unused=None):
if self.stack.get_visible_child() == self.overview:
def set_details_view_opacity(self, _widget=None, _unused=None):
if self.stack.get_visible_child() == self.details_view:
style_manager = Adw.StyleManager.get_default()
if (
style_manager.get_high_contrast()
or not style_manager.get_system_supports_color_schemes()
):
self.overview_blurred_cover.set_opacity(0.2)
self.details_view_blurred_cover.set_opacity(0.2)
return
pixels = self.scaled_pixbuf.get_pixels()
@@ -347,11 +351,11 @@ class CartridgesWindow(Adw.ApplicationWindow):
luminances.append((alpha * (luminance - 255)) / 255**2 + 1)
if dark_theme:
self.overview_blurred_cover.set_opacity(
self.details_view_blurred_cover.set_opacity(
1.3 - (sum(luminances) / len(luminances) + max(luminances)) / 2
)
else:
self.overview_blurred_cover.set_opacity(
self.details_view_blurred_cover.set_opacity(
0.1 + (sum(luminances) / len(luminances) + min(luminances)) / 2
)
@@ -397,11 +401,11 @@ class CartridgesWindow(Adw.ApplicationWindow):
def on_go_back_action(self, _widget, _unused, _x=None, _y=None):
if self.stack.get_visible_child() == self.hidden_library_view:
self.on_show_library_action(None, None)
elif self.stack.get_visible_child() == self.overview:
elif self.stack.get_visible_child() == self.details_view:
self.on_go_to_parent_action(None, None)
def on_go_to_parent_action(self, _widget, _unused):
if self.stack.get_visible_child() == self.overview:
if self.stack.get_visible_child() == self.details_view:
if self.previous_page == self.library_view:
self.on_show_library_action(None, None)
else:
@@ -469,7 +473,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
search_entry.set_text("")
def on_escape_action(self, _widget, _unused):
if self.stack.get_visible_child() == self.overview:
if self.stack.get_visible_child() == self.details_view:
self.on_go_back_action(None, None)
return
if self.stack.get_visible_child() == self.library_view:
@@ -509,5 +513,5 @@ class CartridgesWindow(Adw.ApplicationWindow):
self.toasts.pop((game_id, undo))
def on_open_menu_action(self, _widget, _unused):
if self.stack.get_visible_child() != self.overview:
if self.stack.get_visible_child() != self.details_view:
self.primary_menu_button.set_active(True)