Implement source filtering

This commit is contained in:
kramo
2023-07-07 21:25:08 +02:00
parent 2d00d3a1bc
commit e7d27cc1c4
8 changed files with 135 additions and 24 deletions

View File

@@ -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"]

View File

@@ -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>

View File

@@ -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(

View File

@@ -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"""

View File

@@ -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 = ""

View File

@@ -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@"

View File

@@ -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()

View File

@@ -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()