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

@@ -1,7 +1,7 @@
using Gtk 4.0; using Gtk 4.0;
using Adw 1; using Adw 1;
template game : Box { template Game : Box {
orientation: vertical; orientation: vertical;
halign: center; halign: center;
valign: start; valign: start;
@@ -12,11 +12,18 @@ template game : Box {
orientation: vertical; orientation: vertical;
Button cover_button { Button cover_button {
overflow: hidden; overflow: hidden;
Picture cover { Overlay {
width-request: 200; [overlay]
height-request: 300; Spinner spinner {
hexpand: true; margin-start: 72;
vexpand: true; margin-end: 72;
}
Picture cover {
width-request: 200;
height-request: 300;
hexpand: true;
vexpand: true;
}
} }
styles [ styles [

View File

@@ -61,7 +61,7 @@ ShortcutsWindow help_overlay {
ShortcutsShortcut { ShortcutsShortcut {
title: _("Remove game"); title: _("Remove game");
action-name: "app.remove_game_overview"; action-name: "app.remove_game_details_view";
} }
} }
} }

View File

@@ -1,7 +1,7 @@
@define-color accent_color @purple_1; @define-color accent_color @purple_1;
@define-color accent_bg_color @purple_4; @define-color accent_bg_color @purple_4;
#overview_play_button { #details_view_play_button {
color: @dark_5; color: @dark_5;
background-color: @light_1; background-color: @light_1;
} }

View File

@@ -1,7 +1,7 @@
@define-color accent_color @purple_5; @define-color accent_color @purple_5;
@define-color accent_bg_color @purple_3; @define-color accent_bg_color @purple_3;
#overview_play_button { #details_view_play_button {
color: @light_1; color: @light_1;
background-color: @dark_5; background-color: @dark_5;
opacity: 0.8; opacity: 0.8;

View File

@@ -33,9 +33,9 @@ template CartridgesWindow : Adw.ApplicationWindow {
visible-child: library_view; visible-child: library_view;
transition-type: over_left; transition-type: over_left;
Overlay overview { Overlay details_view {
[overlay] [overlay]
Box overview_box { Box details_view_box {
orientation: vertical; orientation: vertical;
Adw.HeaderBar { Adw.HeaderBar {
@@ -47,7 +47,7 @@ template CartridgesWindow : Adw.ApplicationWindow {
} }
[title] [title]
Adw.WindowTitle overview_header_bar_title { Adw.WindowTitle details_view_header_bar_title {
title: _("Game Details"); title: _("Game Details");
} }
@@ -72,12 +72,12 @@ template CartridgesWindow : Adw.ApplicationWindow {
maximum-size: 200; maximum-size: 200;
Overlay { Overlay {
[overlay] [overlay]
Spinner overview_spinner { Spinner details_view_spinner {
margin-start: 72; margin-start: 72;
margin-end: 72; margin-end: 72;
} }
Picture overview_cover { Picture details_view_cover {
halign: end; halign: end;
valign: start; valign: start;
width-request: 200; width-request: 200;
@@ -96,7 +96,7 @@ template CartridgesWindow : Adw.ApplicationWindow {
vexpand: true; vexpand: true;
valign: center; valign: center;
Label overview_title { Label details_view_title {
label: _("Game Title"); label: _("Game Title");
hexpand: true; hexpand: true;
halign: start; halign: start;
@@ -109,7 +109,7 @@ template CartridgesWindow : Adw.ApplicationWindow {
] ]
} }
Label overview_developer { Label details_view_developer {
margin-top: 3; margin-top: 3;
hexpand: true; hexpand: true;
halign: start; halign: start;
@@ -128,12 +128,12 @@ template CartridgesWindow : Adw.ApplicationWindow {
hexpand: true; hexpand: true;
halign: start; halign: start;
Label overview_added { Label details_view_added {
wrap: true; wrap: true;
wrap-mode: word_char; wrap-mode: word_char;
natural-wrap-mode: word; natural-wrap-mode: word;
} }
Label overview_last_played { Label details_view_last_played {
margin-start: 12; margin-start: 12;
wrap: true; wrap: true;
wrap-mode: word_char; wrap-mode: word_char;
@@ -145,8 +145,8 @@ template CartridgesWindow : Adw.ApplicationWindow {
vexpand: true; vexpand: true;
valign: center; valign: center;
Button overview_play_button { Button details_view_play_button {
name: "overview_play_button"; name: "details_view_play_button";
action-name: "app.launch_game"; action-name: "app.launch_game";
label: _("Play"); label: _("Play");
halign: start; halign: start;
@@ -173,7 +173,7 @@ template CartridgesWindow : Adw.ApplicationWindow {
"circular", "circular",
] ]
} }
Button overview_hide_button { Button details_view_hide_button {
action-name: "app.hide_game"; action-name: "app.hide_game";
styles [ styles [
@@ -218,7 +218,7 @@ template CartridgesWindow : Adw.ApplicationWindow {
"background", "background",
] ]
Picture overview_blurred_cover { Picture details_view_blurred_cover {
can-shrink: true; can-shrink: true;
keep-aspect-ratio: false; keep-aspect-ratio: false;
hexpand: true; hexpand: true;

View File

@@ -2,19 +2,17 @@ data/hu.kramo.Cartridges.desktop.in
data/hu.kramo.Cartridges.gschema.xml data/hu.kramo.Cartridges.gschema.xml
data/hu.kramo.Cartridges.metainfo.xml.in data/hu.kramo.Cartridges.metainfo.xml.in
data/gtk/window.blp
data/gtk/game.blp data/gtk/game.blp
data/gtk/help-overlay.blp data/gtk/help-overlay.blp
data/gtk/preferences.blp data/gtk/preferences.blp
data/gtk/window.blp
src/main.py src/main.py
src/window.py src/window.py
src/game.py src/game.py
src/preferences.py src/preferences.py
src/utils/importer.py
src/utils/bottles_parser.py
src/utils/create_details_window.py src/utils/create_details_window.py
src/utils/create_dialog.py src/utils/create_dialog.py
src/utils/heroic_parser.py src/utils/importer.py
src/utils/steam_parser.py src/utils/steamgriddb.py

View File

@@ -30,13 +30,14 @@ 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")
class game(Gtk.Box): # pylint: disable=invalid-name class Game(Gtk.Box):
__gtype_name__ = "game" __gtype_name__ = "Game"
overlay = Gtk.Template.Child() overlay = Gtk.Template.Child()
title = Gtk.Template.Child() title = Gtk.Template.Child()
play_button = Gtk.Template.Child() play_button = Gtk.Template.Child()
cover = Gtk.Template.Child() cover = Gtk.Template.Child()
spinner = Gtk.Template.Child()
cover_button = Gtk.Template.Child() cover_button = Gtk.Template.Child()
menu_button = Gtk.Template.Child() menu_button = Gtk.Template.Child()
play_revealer = 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.removed = "removed" in data
self.blacklisted = "blacklisted" 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.title.set_label(self.name)
self.game_cover = GameCover(self.cover, path=self.get_cover_path())
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)
self.overlay.set_measure_overlay(self.play_revealer, True) self.overlay.set_measure_overlay(self.play_revealer, True)
@@ -105,7 +107,9 @@ class game(Gtk.Box): # pylint: disable=invalid-name
sys.exit() sys.exit()
def toggle_hidden(self): 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"] 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"): if self.parent_widget.schema.get_boolean("cover-launches-game"):
self.launch_game(None) self.launch_game(None)
else: 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): def play_button_clicked(self, _widget):
if self.parent_widget.schema.get_boolean("cover-launches-game"): 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: else:
self.launch_game(None) self.launch_game(None)
@@ -156,3 +160,10 @@ class game(Gtk.Box): # pylint: disable=invalid-name
def schema_changed(self, _settings, key): def schema_changed(self, _settings, key):
if key == "cover-launches-game": if key == "cover-launches-game":
self.set_play_label() 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 # Copyright 2022-2023 kramo
# #
@@ -23,7 +23,7 @@ from time import time
import yaml import yaml
def bottles_parser(parent_widget): def bottles_importer(parent_widget):
schema = parent_widget.schema schema = parent_widget.schema
bottles_dir = Path(schema.get_string("bottles-location")).expanduser() 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 # Copyright 2022-2023 kramo
# #
@@ -24,7 +24,7 @@ from pathlib import Path
from time import time from time import time
def heroic_parser(parent_widget): def heroic_importer(parent_widget):
schema = parent_widget.schema schema = parent_widget.schema
heroic_dir = Path(schema.get_string("heroic-location")).expanduser() 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 # 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)) 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 schema = parent_widget.schema
database_path = (Path(schema.get_string("itch-location")) / "db").expanduser() 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 # Copyright 2022-2023 kramo
# #
@@ -23,8 +23,7 @@ from sqlite3 import connect
from time import time from time import time
def lutris_parser(parent_widget): def lutris_importer(parent_widget):
schema = parent_widget.schema schema = parent_widget.schema
database_path = (Path(schema.get_string("lutris-location"))).expanduser() 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 # 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 schema = parent_widget.schema
steam_dir = Path(schema.get_string("steam-location")).expanduser() 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")) schema.set_string("steam-location", str(steam_dir / "Steam"))
else: else:
steam_not_found() steam_not_found()
steam_parser(parent_widget) steam_importer(parent_widget)
return return
steam_dir = Path(schema.get_string("steam-location")).expanduser() 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 # pylint: disable=wrong-import-position
from gi.repository import Adw, Gio, GLib, Gtk 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 .create_details_window import create_details_window
from .get_games import get_games from .get_games import get_games
from .heroic_parser import heroic_parser from .heroic_importer import heroic_importer
from .importer import Importer from .importer import Importer
from .itch_parser import itch_parser from .itch_importer import itch_importer
from .lutris_parser import lutris_parser from .lutris_importer import lutris_importer
from .preferences import PreferencesWindow from .preferences import PreferencesWindow
from .save_game import save_game from .save_game import save_game
from .steam_parser import steam_parser from .steam_importer import steam_importer
from .window import CartridgesWindow 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("add_game", self.on_add_game_action, ["<primary>n"])
self.create_action("import", self.on_import_action, ["<primary>i"]) self.create_action("import", self.on_import_action, ["<primary>i"])
self.create_action( 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("remove_game", self.on_remove_game_action)
self.create_action("igdb_search", self.on_igdb_search_action) self.create_action("igdb_search", self.on_igdb_search_action)
@@ -121,8 +123,10 @@ class CartridgesApplication(Adw.Application):
developers=[ developers=[
"kramo https://kramo.hu", "kramo https://kramo.hu",
"Paweł Lidwin https://github.com/imLinguin", "Paweł Lidwin https://github.com/imLinguin",
"Domenico https://github.com/Domefemia",
"Bananaman https://github.com/Bananaman", "Bananaman https://github.com/Bananaman",
"Geoffrey Coulaud https://geoffrey-coulaud.fr", "Geoffrey Coulaud https://geoffrey-coulaud.fr",
"Rafael Mardojai CM https://mardojai.com",
], ],
designers=["kramo https://kramo.hu"], designers=["kramo https://kramo.hu"],
copyright="© 2022-2023 kramo", copyright="© 2022-2023 kramo",
@@ -167,7 +171,7 @@ class CartridgesApplication(Adw.Application):
if not game_id: if not game_id:
game_id = self.win.active_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.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]) self.win.update_games([game_id])
@@ -200,19 +204,19 @@ class CartridgesApplication(Adw.Application):
self.win.importer.blocker = True self.win.importer.blocker = True
if self.win.schema.get_boolean("steam"): if self.win.schema.get_boolean("steam"):
steam_parser(self.win) steam_importer(self.win)
if self.win.schema.get_boolean("lutris"): if self.win.schema.get_boolean("lutris"):
lutris_parser(self.win) lutris_importer(self.win)
if self.win.schema.get_boolean("heroic"): if self.win.schema.get_boolean("heroic"):
heroic_parser(self.win) heroic_importer(self.win)
if self.win.schema.get_boolean("bottles"): if self.win.schema.get_boolean("bottles"):
bottles_parser(self.win) bottles_importer(self.win)
if self.win.schema.get_boolean("itch"): if self.win.schema.get_boolean("itch"):
itch_parser(self.win) itch_importer(self.win)
self.win.importer.blocker = False self.win.importer.blocker = False
@@ -229,7 +233,7 @@ class CartridgesApplication(Adw.Application):
save_game(self.win, data) save_game(self.win, data)
self.win.update_games([game_id]) 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) self.win.on_go_back_action(None, None)
title = self.win.games[game_id].name title = self.win.games[game_id].name
@@ -241,8 +245,8 @@ class CartridgesApplication(Adw.Application):
self.win.toasts[(game_id, "remove")] = toast self.win.toasts[(game_id, "remove")] = toast
self.win.toast_overlay.add_toast(toast) self.win.toast_overlay.add_toast(toast)
def on_remove_game_overview_action(self, _widget, _callback=None): def on_remove_game_details_view_action(self, _widget, _callback=None):
if self.win.stack.get_visible_child() == self.win.overview: if self.win.stack.get_visible_child() == self.win.details_view:
self.on_remove_game_action(None) self.on_remove_game_action(None)
def on_quit_action(self, _widget, _callback=None): def on_quit_action(self, _widget, _callback=None):

View File

@@ -23,13 +23,13 @@ cartridges_sources = [
'preferences.py', 'preferences.py',
'game.py', 'game.py',
'game_cover.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/importer.py',
'utils/steamgriddb.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/get_games.py',
'utils/save_game.py', 'utils/save_game.py',
'utils/save_cover.py', 'utils/save_cover.py',

View File

@@ -19,7 +19,7 @@
import os import os
from pathlib import Path from pathlib import Path
from shutil import move from shutil import move, copyfile
from gi.repository import Adw, Gio, GLib, Gtk from gi.repository import Adw, Gio, GLib, Gtk
@@ -367,7 +367,7 @@ class PreferencesWindow(Adw.PreferencesWindow):
if not cover_path.is_file(): if not cover_path.is_file():
continue 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.parent_widget.update_games(self.removed_games)
self.removed_games = [] self.removed_games = []
@@ -386,12 +386,17 @@ class PreferencesWindow(Adw.PreferencesWindow):
save_game(self.parent_widget, game) save_game(self.parent_widget, game)
cover_path = self.parent_widget.games[game["game_id"]].get_cover_path() cover_path = self.parent_widget.games[game["game_id"]].get_cover_path()
if not cover_path:
continue
if cover_path.is_file(): 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) 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.parent_widget.on_go_back_action(None, None)
self.add_toast(self.toast) 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}.tiff").unlink(missing_ok=True)
(parent_widget.covers_dir / f"{game_id}.gif").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( save_cover(
parent_widget, parent_widget,
game_id, game_id,
@@ -337,9 +334,13 @@ def create_details_window(parent_widget, game_id=None):
else: else:
save_game(parent_widget, values) 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() window.close()
parent_widget.show_overview(None, game_id) parent_widget.show_details_view(None, game_id)
def focus_executable(_widget): def focus_executable(_widget):
window.set_focus(executable) window.set_focus(executable)

View File

@@ -35,7 +35,7 @@ class SGDBSave:
) )
): ):
if not self.importer: 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/" url = "https://www.steamgriddb.com/api/v2/"
headers = { headers = {
@@ -106,8 +106,6 @@ class SGDBSave:
self.importer.queue -= 1 self.importer.queue -= 1
self.importer.done() self.importer.done()
self.importer.sgdb_exception = self.exception self.importer.sgdb_exception = self.exception
else:
self.parent_widget.loading = None
if self.exception: if self.exception:
create_dialog( create_dialog(

View File

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