Implement source filtering
This commit is contained in:
@@ -88,16 +88,44 @@ template $CartridgesWindow : Adw.ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBox {
|
ListBox sidebar {
|
||||||
Box {
|
Box all_games_row_box {
|
||||||
|
margin-top: 12;
|
||||||
|
margin-bottom: 12;
|
||||||
|
margin-start: 6;
|
||||||
|
margin-end: 6;
|
||||||
|
spacing: 12;
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
icon-name: "view-grid";
|
icon-name: "view-grid-symbolic";
|
||||||
margin-start: 3;
|
|
||||||
margin-end: 9;
|
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
halign: start;
|
halign: start;
|
||||||
label: _("All");
|
label: _("All Games");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Box added_row_box {
|
||||||
|
margin-top: 12;
|
||||||
|
margin-bottom: 12;
|
||||||
|
margin-start: 6;
|
||||||
|
margin-end: 6;
|
||||||
|
spacing: 12;
|
||||||
|
|
||||||
|
Image {
|
||||||
|
icon-name: "list-add-symbolic";
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
halign: start;
|
||||||
|
label: _("Added");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListBoxRow {
|
||||||
|
selectable: false;
|
||||||
|
activatable: false;
|
||||||
|
Label {
|
||||||
|
label: _("Imported");
|
||||||
|
styles ["heading"]
|
||||||
|
halign: start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
styles ["navigation-sidebar"]
|
styles ["navigation-sidebar"]
|
||||||
|
|||||||
@@ -109,9 +109,6 @@
|
|||||||
<key name="show-sidebar" type="b">
|
<key name="show-sidebar" type="b">
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
</key>
|
</key>
|
||||||
<key name="filter" type="s">
|
|
||||||
<default>"all"</default>
|
|
||||||
</key>
|
|
||||||
<key name="steam-limiter-tokens-history" type="s">
|
<key name="steam-limiter-tokens-history" type="s">
|
||||||
<default>"[]"</default>
|
<default>"[]"</default>
|
||||||
</key>
|
</key>
|
||||||
|
|||||||
@@ -158,11 +158,12 @@ class DetailsWindow(Adw.Window):
|
|||||||
source_id = "imported"
|
source_id = "imported"
|
||||||
numbers = [0]
|
numbers = [0]
|
||||||
game_id: str
|
game_id: str
|
||||||
for game_id in shared.source_games[source_id]:
|
for game_id in shared.store.source_games.get(source_id, set()):
|
||||||
prefix = "imported_"
|
prefix = "imported_"
|
||||||
if not game_id.startswith(prefix):
|
if not game_id.startswith(prefix):
|
||||||
continue
|
continue
|
||||||
numbers.append(int(game_id.replace(prefix, "", 1)))
|
numbers.append(int(game_id.replace(prefix, "", 1)))
|
||||||
|
|
||||||
game_number = max(numbers) + 1
|
game_number = max(numbers) + 1
|
||||||
|
|
||||||
self.game = Game(
|
self.game = Game(
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ class Importer(ErrorProducer):
|
|||||||
def run(self):
|
def run(self):
|
||||||
"""Use several Gio.Task to import games from added sources"""
|
"""Use several Gio.Task to import games from added sources"""
|
||||||
|
|
||||||
|
shared.win.get_application().state = shared.AppState.IMPORT
|
||||||
shared.win.get_application().lookup_action("import").set_enabled(False)
|
shared.win.get_application().lookup_action("import").set_enabled(False)
|
||||||
|
|
||||||
self.create_dialog()
|
self.create_dialog()
|
||||||
@@ -224,6 +225,8 @@ class Importer(ErrorProducer):
|
|||||||
self.summary_toast = self.create_summary_toast()
|
self.summary_toast = self.create_summary_toast()
|
||||||
self.create_error_dialog()
|
self.create_error_dialog()
|
||||||
shared.win.get_application().lookup_action("import").set_enabled(True)
|
shared.win.get_application().lookup_action("import").set_enabled(True)
|
||||||
|
shared.win.get_application().state = shared.AppState.DEFAULT
|
||||||
|
shared.win.create_source_rows()
|
||||||
|
|
||||||
def create_error_dialog(self):
|
def create_error_dialog(self):
|
||||||
"""Dialog containing all errors raised by importers"""
|
"""Dialog containing all errors raised by importers"""
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ from src.window import CartridgesWindow
|
|||||||
|
|
||||||
|
|
||||||
class CartridgesApplication(Adw.Application):
|
class CartridgesApplication(Adw.Application):
|
||||||
|
state = shared.AppState.DEFAULT
|
||||||
win = None
|
win = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -86,7 +87,10 @@ class CartridgesApplication(Adw.Application):
|
|||||||
# Load games from disk
|
# Load games from disk
|
||||||
shared.store.add_manager(FileManager(), False)
|
shared.store.add_manager(FileManager(), False)
|
||||||
shared.store.add_manager(DisplayManager())
|
shared.store.add_manager(DisplayManager())
|
||||||
|
self.state = shared.AppState.LOAD_FROM_DISK
|
||||||
self.load_games_from_disk()
|
self.load_games_from_disk()
|
||||||
|
self.state = shared.AppState.DEFAULT
|
||||||
|
self.win.create_source_rows()
|
||||||
|
|
||||||
# Add rest of the managers for game imports
|
# Add rest of the managers for game imports
|
||||||
shared.store.add_manager(LocalCoverManager())
|
shared.store.add_manager(LocalCoverManager())
|
||||||
@@ -141,6 +145,9 @@ class CartridgesApplication(Adw.Application):
|
|||||||
game = Game(data)
|
game = Game(data)
|
||||||
shared.store.add_game(game, {"skip_save": True})
|
shared.store.add_game(game, {"skip_save": True})
|
||||||
|
|
||||||
|
def get_source_name(self, source_id):
|
||||||
|
return globals()[f"{source_id.title()}Source"].name
|
||||||
|
|
||||||
def on_about_action(self, *_args):
|
def on_about_action(self, *_args):
|
||||||
# Get the debug info from the log files
|
# Get the debug info from the log files
|
||||||
debug_str = ""
|
debug_str = ""
|
||||||
|
|||||||
@@ -18,10 +18,18 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from enum import IntEnum, auto
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from gi.repository import Gdk, Gio, GLib
|
from gi.repository import Gdk, Gio, GLib
|
||||||
|
|
||||||
|
|
||||||
|
class AppState(IntEnum):
|
||||||
|
DEFAULT = auto()
|
||||||
|
LOAD_FROM_DISK = auto()
|
||||||
|
IMPORT = auto()
|
||||||
|
|
||||||
|
|
||||||
APP_ID = "@APP_ID@"
|
APP_ID = "@APP_ID@"
|
||||||
VERSION = "@VERSION@"
|
VERSION = "@VERSION@"
|
||||||
PREFIX = "@PREFIX@"
|
PREFIX = "@PREFIX@"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from src import shared
|
||||||
from src.game import Game
|
from src.game import Game
|
||||||
from src.game_cover import GameCover
|
from src.game_cover import GameCover
|
||||||
from src.store.managers.manager import Manager
|
from src.store.managers.manager import Manager
|
||||||
@@ -46,27 +47,30 @@ class DisplayManager(Manager):
|
|||||||
"notify::visible", game.toggle_play, None
|
"notify::visible", game.toggle_play, None
|
||||||
)
|
)
|
||||||
game.menu_button.get_popover().connect(
|
game.menu_button.get_popover().connect(
|
||||||
"notify::visible", game.win.set_active_game, game
|
"notify::visible", shared.win.set_active_game, game
|
||||||
)
|
)
|
||||||
|
|
||||||
if game.game_id in game.win.game_covers:
|
if game.game_id in shared.win.game_covers:
|
||||||
game.game_cover = game.win.game_covers[game.game_id]
|
game.game_cover = shared.win.game_covers[game.game_id]
|
||||||
game.game_cover.add_picture(game.cover)
|
game.game_cover.add_picture(game.cover)
|
||||||
else:
|
else:
|
||||||
game.game_cover = GameCover({game.cover}, game.get_cover_path())
|
game.game_cover = GameCover({game.cover}, game.get_cover_path())
|
||||||
game.win.game_covers[game.game_id] = game.game_cover
|
shared.win.game_covers[game.game_id] = game.game_cover
|
||||||
|
|
||||||
if (
|
if (
|
||||||
game.win.navigation_view.get_visible_page() == game.win.details_page
|
shared.win.navigation_view.get_visible_page() == shared.win.details_page
|
||||||
and game.win.active_game == game
|
and shared.win.active_game == game
|
||||||
):
|
):
|
||||||
game.win.show_details_page(game)
|
shared.win.show_details_page(game)
|
||||||
|
|
||||||
if not game.removed and not game.blacklisted:
|
if not game.removed and not game.blacklisted:
|
||||||
if game.hidden:
|
if game.hidden:
|
||||||
game.win.hidden_library.append(game)
|
shared.win.hidden_library.append(game)
|
||||||
else:
|
else:
|
||||||
game.win.library.append(game)
|
shared.win.library.append(game)
|
||||||
game.get_parent().set_focusable(False)
|
game.get_parent().set_focusable(False)
|
||||||
|
|
||||||
game.win.set_library_child()
|
shared.win.set_library_child()
|
||||||
|
|
||||||
|
if shared.win.get_application().state == shared.AppState.DEFAULT:
|
||||||
|
shared.win.create_source_rows()
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
|
|
||||||
overlay_split_view = Gtk.Template.Child()
|
overlay_split_view = Gtk.Template.Child()
|
||||||
navigation_view = Gtk.Template.Child()
|
navigation_view = Gtk.Template.Child()
|
||||||
|
sidebar = Gtk.Template.Child()
|
||||||
|
all_games_row_box = Gtk.Template.Child()
|
||||||
|
added_row_box = Gtk.Template.Child()
|
||||||
toast_overlay = Gtk.Template.Child()
|
toast_overlay = Gtk.Template.Child()
|
||||||
primary_menu_button = Gtk.Template.Child()
|
primary_menu_button = Gtk.Template.Child()
|
||||||
show_sidebar_button = Gtk.Template.Child()
|
show_sidebar_button = Gtk.Template.Child()
|
||||||
@@ -73,6 +76,57 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
active_game = None
|
active_game = None
|
||||||
details_view_game_cover = None
|
details_view_game_cover = None
|
||||||
sort_state = "a-z"
|
sort_state = "a-z"
|
||||||
|
filter_state = "all"
|
||||||
|
source_rows = {}
|
||||||
|
|
||||||
|
def create_source_rows(self):
|
||||||
|
self.sidebar.get_row_at_index(2).set_visible(False)
|
||||||
|
|
||||||
|
while row := self.sidebar.get_row_at_index(3):
|
||||||
|
self.sidebar.remove(row)
|
||||||
|
|
||||||
|
def get_removed(source_id):
|
||||||
|
for game in shared.store.source_games[source_id].values():
|
||||||
|
if game.removed:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
for source_id in shared.store.source_games:
|
||||||
|
if source_id == "imported":
|
||||||
|
continue
|
||||||
|
if get_removed(source_id):
|
||||||
|
continue
|
||||||
|
|
||||||
|
row = Gtk.Label(
|
||||||
|
label=self.get_application().get_source_name(source_id),
|
||||||
|
halign=Gtk.Align.START,
|
||||||
|
margin_top=12,
|
||||||
|
margin_bottom=12,
|
||||||
|
margin_start=6,
|
||||||
|
margin_end=6,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.sidebar.append(row)
|
||||||
|
self.source_rows[row.get_parent()] = source_id
|
||||||
|
self.sidebar.get_row_at_index(2).set_visible(True)
|
||||||
|
|
||||||
|
def row_selected(self, widget, row):
|
||||||
|
if not row:
|
||||||
|
widget.select_row(self.all_games_row_box.get_parent())
|
||||||
|
try:
|
||||||
|
value = self.source_rows[row]
|
||||||
|
except KeyError:
|
||||||
|
match row.get_child():
|
||||||
|
case self.all_games_row_box:
|
||||||
|
value = "all"
|
||||||
|
case self.added_row_box:
|
||||||
|
value = "imported"
|
||||||
|
|
||||||
|
self.filter_state = value
|
||||||
|
self.library.invalidate_filter()
|
||||||
|
|
||||||
|
if self.overlay_split_view.get_collapsed():
|
||||||
|
self.overlay_split_view.set_show_sidebar(False)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
@@ -90,7 +144,11 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
|
|
||||||
self.notice_empty.set_icon_name(shared.APP_ID + "-symbolic")
|
self.notice_empty.set_icon_name(shared.APP_ID + "-symbolic")
|
||||||
|
|
||||||
self.overlay_split_view.set_show_sidebar(shared.state_schema.get_boolean("show-sidebar"))
|
self.overlay_split_view.set_show_sidebar(
|
||||||
|
shared.state_schema.get_boolean("show-sidebar")
|
||||||
|
)
|
||||||
|
|
||||||
|
self.sidebar.select_row(self.all_games_row_box.get_parent())
|
||||||
|
|
||||||
if shared.PROFILE == "development":
|
if shared.PROFILE == "development":
|
||||||
self.add_css_class("devel")
|
self.add_css_class("devel")
|
||||||
@@ -109,6 +167,8 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
self.navigation_view.connect("popped", self.set_show_hidden)
|
self.navigation_view.connect("popped", self.set_show_hidden)
|
||||||
self.navigation_view.connect("pushed", self.set_show_hidden)
|
self.navigation_view.connect("pushed", self.set_show_hidden)
|
||||||
|
|
||||||
|
self.sidebar.connect("row-selected", self.row_selected)
|
||||||
|
|
||||||
style_manager = Adw.StyleManager.get_default()
|
style_manager = Adw.StyleManager.get_default()
|
||||||
style_manager.connect("notify::dark", self.set_details_view_opacity)
|
style_manager.connect("notify::dark", self.set_details_view_opacity)
|
||||||
style_manager.connect("notify::high-contrast", self.set_details_view_opacity)
|
style_manager.connect("notify::high-contrast", self.set_details_view_opacity)
|
||||||
@@ -151,9 +211,6 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
remove_from_overlay(self.hidden_notice_no_results)
|
remove_from_overlay(self.hidden_notice_no_results)
|
||||||
|
|
||||||
def filter_func(self, child):
|
def filter_func(self, child):
|
||||||
if shared.state_schema.get_string("filter") != "all":
|
|
||||||
pass
|
|
||||||
|
|
||||||
game = child.get_child()
|
game = child.get_child()
|
||||||
text = (
|
text = (
|
||||||
(
|
(
|
||||||
@@ -170,6 +227,12 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
or (text in game.developer.lower() if game.developer else False)
|
or (text in game.developer.lower() if game.developer else False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not filtered:
|
||||||
|
if self.filter_state == "all":
|
||||||
|
pass
|
||||||
|
elif game.source != self.filter_state:
|
||||||
|
filtered = True
|
||||||
|
|
||||||
game.filtered = filtered
|
game.filtered = filtered
|
||||||
self.set_library_child()
|
self.set_library_child()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user