[gnome-games/wip/exalm/db: 26/29] ui: Use GameModel and PlatformModel for collection
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/wip/exalm/db: 26/29] ui: Use GameModel and PlatformModel for collection
- Date: Mon, 10 Feb 2020 18:36:35 +0000 (UTC)
commit 246e1729df3ce6929d46d6d431e6c0e2c0bbc720
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Sat Feb 8 19:25:48 2020 +0500
ui: Use GameModel and PlatformModel for collection
Make the code more organized, and prepare for database caching.
Unfortunately, it also means we cannot use set_filter_func() and have to
implement filters manually. Long-term we should use GTK4's filter model,
but now this will have to do.
src/ui/application-window.vala | 8 +--
src/ui/application.vala | 8 +--
src/ui/collection-box.vala | 16 +++---
src/ui/collection-icon-view.vala | 90 ++++++------------------------
src/ui/collection-view.vala | 14 ++---
src/ui/platform-list-item.vala | 4 --
src/ui/platforms-view.vala | 115 +++++++++++++++------------------------
7 files changed, 86 insertions(+), 169 deletions(-)
---
diff --git a/src/ui/application-window.vala b/src/ui/application-window.vala
index 3f1970da..63115f60 100644
--- a/src/ui/application-window.vala
+++ b/src/ui/application-window.vala
@@ -59,10 +59,10 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
private uint inhibit_cookie;
private Gtk.ApplicationInhibitFlags inhibit_flags;
- public ListModel collection { get; construct; }
+ public GameModel game_model { get; construct; }
- public ApplicationWindow (Application application, ListModel collection) {
- Object (application: application, collection: collection);
+ public ApplicationWindow (Application application, GameModel game_model) {
+ Object (application: application, game_model: game_model);
current_view = collection_view;
}
@@ -82,7 +82,7 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
if (settings.get_boolean ("window-maximized"))
maximize ();
- collection_view = new CollectionView (this, collection);
+ collection_view = new CollectionView (this, game_model);
display_view = new DisplayView (this);
content_box.add (collection_view.content_box);
diff --git a/src/ui/application.vala b/src/ui/application.vala
index 20acd729..02a35307 100644
--- a/src/ui/application.vala
+++ b/src/ui/application.vala
@@ -12,7 +12,7 @@ public class Games.Application : Gtk.Application {
private bool game_list_loaded;
private GameCollection game_collection;
- private ListStore list_store;
+ private GameModel game_model;
private CoverLoader cover_loader;
private Manette.Monitor manette_monitor;
@@ -203,8 +203,8 @@ public class Games.Application : Gtk.Application {
init_game_sources ();
load_game_list.begin ();
- list_store = new ListStore (typeof (Game));
- game_collection.game_added.connect (game => list_store.append (game));
+ game_model = new GameModel ();
+ game_collection.game_added.connect (game_model.add_game);
cover_loader = new CoverLoader ();
}
@@ -215,7 +215,7 @@ public class Games.Application : Gtk.Application {
return;
}
- window = new ApplicationWindow (this, list_store);
+ window = new ApplicationWindow (this, game_model);
window.destroy.connect (() => {
quit_application ();
});
diff --git a/src/ui/collection-box.vala b/src/ui/collection-box.vala
index 81f6181c..31931139 100644
--- a/src/ui/collection-box.vala
+++ b/src/ui/collection-box.vala
@@ -4,7 +4,7 @@
private class Games.CollectionBox : Gtk.Box {
public signal void game_activated (Game game);
- public ListModel collection { get; construct; }
+ public GameModel game_model { get; construct; }
public bool search_mode { get; set; }
public bool loading_notification { get; set; }
@@ -65,12 +65,12 @@ private class Games.CollectionBox : Gtk.Box {
var icon_name = Config.APPLICATION_ID + "-symbolic";
viewstack.child_set (collection_view, "icon-name", icon_name);
- collection_view.model = collection;
- platform_view.model = collection;
+ collection_view.game_model = game_model;
+ platform_view.game_model = game_model;
}
- public CollectionBox (ListModel collection) {
- Object (collection: collection);
+ public CollectionBox (GameModel game_model) {
+ Object (game_model: game_model);
}
public void show_error (string error_message) {
@@ -128,11 +128,13 @@ private class Games.CollectionBox : Gtk.Box {
}
public bool found_games () {
- for (int i = 0; i < collection.get_n_items (); i++) {
- var game = collection.get_item (i) as Game;
+ for (int i = 0; i < game_model.get_n_items (); i++) {
+ var game = game_model.get_item (i) as Game;
+
if (game.matches_search_terms (filtering_terms))
return true;
}
+
return false;
}
diff --git a/src/ui/collection-icon-view.vala b/src/ui/collection-icon-view.vala
index 7f4248e6..222af0f1 100644
--- a/src/ui/collection-icon-view.vala
+++ b/src/ui/collection-icon-view.vala
@@ -12,26 +12,14 @@ private class Games.CollectionIconView : Gtk.Bin {
this.game_filter = game_filter;
}
- private ulong model_changed_id;
- private ListModel _model;
- public ListModel model {
- get { return _model; }
+ private GameModel _game_model;
+ public GameModel game_model {
+ get { return _game_model; }
set {
- if (model != null)
- model.disconnect (model_changed_id);
+ _game_model = value;
+ flow_box.bind_model (game_model, add_game);
- _model = value;
- clear_content ();
- if (model == null)
- return;
-
- for (int i = 0; i < model.get_n_items (); i++) {
- var game = model.get_item (i) as Game;
- add_game (game);
- }
- model_changed_id = model.items_changed.connect (on_items_changed);
-
- flow_box.invalidate_sort ();
+ game_model.items_changed.connect (apply_filter);
}
}
@@ -64,8 +52,6 @@ private class Games.CollectionIconView : Gtk.Bin {
construct {
flow_box.max_children_per_line = uint.MAX;
- flow_box.set_filter_func (filter_box);
- flow_box.set_sort_func (sort_boxes);
}
[GtkCallback]
@@ -109,7 +95,7 @@ private class Games.CollectionIconView : Gtk.Bin {
public void set_filter (string[] filtering_terms) {
this.filtering_terms = filtering_terms;
- flow_box.invalidate_filter ();
+ apply_filter ();
}
public void reset_scroll_position () {
@@ -144,10 +130,6 @@ private class Games.CollectionIconView : Gtk.Bin {
flow_box.unselect_all ();
}
- public void invalidate_flow_box_filter () {
- flow_box.invalidate_filter ();
- }
-
[GtkCallback]
private bool on_gamepad_browse (Gtk.DirectionType direction) {
if (!has_game_selected ())
@@ -177,49 +159,27 @@ private class Games.CollectionIconView : Gtk.Bin {
[GtkCallback]
private void on_child_activated (Gtk.FlowBoxChild child) {
- if (child.get_child () is GameIconView)
- on_game_view_activated (child.get_child () as GameIconView);
- }
+ var game_view = child.get_child () as GameIconView;
- private void on_game_view_activated (GameIconView game_view) {
game_activated (game_view.game);
}
- private void on_items_changed (uint position, uint removed, uint added) {
- // FIXME: currently games are never removed, update this function if
- // necessary.
- assert (removed == 0);
-
- for (uint i = position; i < position + added; i++) {
- var game = model.get_item (i) as Game;
- add_game (game);
- }
- }
+ private Gtk.Widget add_game (Object item) {
+ var game = item as Game;
- private void add_game (Game game) {
var game_view = new GameIconView (game);
- var child = new Gtk.FlowBoxChild ();
-
- game_view.visible = true;
- child.visible = true;
+ game_view.show ();
- child.add (game_view);
- flow_box.add (child);
+ return game_view;
}
- private void clear_content () {
- flow_box.forall ((child) => { flow_box.remove (child); });
- }
-
- private bool filter_box (Gtk.FlowBoxChild child) {
- var game_view = child.get_child () as GameIconView;
- if (game_view == null)
- return false;
-
- if (game_view.game == null)
- return false;
+ public void apply_filter () {
+ flow_box.foreach (widget => {
+ var child = widget as Gtk.FlowBoxChild;
+ var game_view = child.get_child () as GameIconView;
- return filter_game (game_view.game);
+ widget.visible = filter_game (game_view.game);
+ });
}
private bool filter_game (Game game) {
@@ -229,20 +189,6 @@ private class Games.CollectionIconView : Gtk.Bin {
return game.matches_search_terms (filtering_terms);
}
- private int sort_boxes (Gtk.FlowBoxChild child1, Gtk.FlowBoxChild child2) {
- var game_view1 = child1.get_child () as GameIconView;
- var game_view2 = child2.get_child () as GameIconView;
-
- assert (game_view1 != null);
- assert (game_view2 != null);
-
- return sort_games (game_view1.game, game_view2.game);
- }
-
- private int sort_games (Game game1, Game game2) {
- return game1.name.collate (game2.name);
- }
-
[GtkCallback]
private void on_size_allocate (Gtk.Allocation allocation) {
// If the window's width is less than half the width of a 1920×1080
diff --git a/src/ui/collection-view.vala b/src/ui/collection-view.vala
index 23fe5643..259f0121 100644
--- a/src/ui/collection-view.vala
+++ b/src/ui/collection-view.vala
@@ -33,7 +33,7 @@ private class Games.CollectionView : Object, UiView {
}
public Gtk.Window window { get; construct; }
- public ListModel collection { get; construct; }
+ public GameModel game_model { get; construct; }
public bool loading_notification { get; set; }
public bool search_mode { get; set; }
@@ -47,16 +47,16 @@ private class Games.CollectionView : Object, UiView {
private KonamiCode konami_code;
construct {
- box = new CollectionBox (collection);
+ box = new CollectionBox (game_model);
header_bar = new CollectionHeaderBar ();
box.game_activated.connect (game => {
game_activated (game);
});
- collection.items_changed.connect (() => {
- is_collection_empty = collection.get_n_items () == 0;
+ game_model.items_changed.connect (() => {
+ is_collection_empty = game_model.get_n_items () == 0;
});
- is_collection_empty = collection.get_n_items () == 0;
+ is_collection_empty = game_model.get_n_items () == 0;
header_bar.viewstack = box.viewstack;
is_collection_empty = true;
@@ -98,8 +98,8 @@ private class Games.CollectionView : Object, UiView {
konami_code.code_performed.connect (on_konami_code_performed);
}
- public CollectionView (Gtk.Window window, ListModel collection) {
- Object (window: window, collection: collection);
+ public CollectionView (Gtk.Window window, GameModel game_model) {
+ Object (window: window, game_model: game_model);
}
public void show_error (string error_message) {
diff --git a/src/ui/platform-list-item.vala b/src/ui/platform-list-item.vala
index 3fd6c13e..653910d9 100644
--- a/src/ui/platform-list-item.vala
+++ b/src/ui/platform-list-item.vala
@@ -14,8 +14,4 @@ private class Games.PlatformListItem : Gtk.ListBoxRow {
public PlatformListItem (Platform platform) {
Object (platform: platform);
}
-
- public static int compare (PlatformListItem a, PlatformListItem b) {
- return a.platform.get_name ().collate (b.platform.get_name ());
- }
}
diff --git a/src/ui/platforms-view.vala b/src/ui/platforms-view.vala
index db774942..755a4077 100644
--- a/src/ui/platforms-view.vala
+++ b/src/ui/platforms-view.vala
@@ -15,28 +15,22 @@ private class Games.PlatformsView : Gtk.Bin {
[GtkChild]
private GamepadBrowse gamepad_browse;
- private ulong model_items_changed_id;
-
- private GenericSet<Platform> platforms;
private Platform selected_platform;
private bool has_used_gamepad;
private string[] filtering_terms;
- private ListModel _model;
- public ListModel model {
- get { return _model; }
+ private GameModel _game_model;
+ public GameModel game_model {
+ get { return _game_model; }
set {
- if (model_items_changed_id != 0) {
- _model.disconnect (model_items_changed_id);
- model_items_changed_id = 0;
- }
+ _game_model = value;
+ collection_view.game_model = value;
- _model = value;
- collection_view.model = _model;
+ var platform_model = new PlatformModel (value);
+ list_box.bind_model (platform_model, add_platform);
- if (model != null)
- model_items_changed_id = model.items_changed.connect (on_model_changed);
+ platform_model.items_changed.connect (apply_filter);
}
}
@@ -60,18 +54,37 @@ private class Games.PlatformsView : Gtk.Bin {
public string subview_title { get; set; }
construct {
- platforms = new GenericSet<Platform> (Platform.hash, Platform.equal);
+ collection_view.set_game_filter (filter_game);
+ }
- list_box.set_sort_func (sort_rows);
+ private void apply_filter () {
+ list_box.foreach (widget => {
+ var row = widget as PlatformListItem;
- collection_view.set_game_filter (filter_game);
+ if (row == null)
+ return;
+
+ widget.set_visible (filter_list (row));
+ });
}
- private int sort_rows (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) {
- var item1 = row1 as PlatformListItem;
- var item2 = row2 as PlatformListItem;
+ private bool filter_list (PlatformListItem item) {
+ if (item.platform == null)
+ return false;
+
+ Game[] visible_games = {};
+ for (int i = 0; i < game_model.get_n_items (); i++) {
+ var game = game_model.get_item (i) as Game;
- return PlatformListItem.compare (item1, item2);
+ if (game.matches_search_terms (filtering_terms))
+ visible_games += game;
+ }
+
+ foreach (var game in visible_games)
+ if (game.get_platform () == item.platform)
+ return true;
+
+ return false;
}
private bool filter_game (Game game) {
@@ -103,7 +116,9 @@ private class Games.PlatformsView : Gtk.Bin {
public void set_filter (string[] filtering_terms) {
this.filtering_terms = filtering_terms;
collection_view.set_filter (filtering_terms);
- hide_empty_sidebar_items ();
+
+ apply_filter ();
+ select_first_visible_row ();
}
public bool gamepad_button_press_event (Manette.Event event) {
@@ -204,29 +219,11 @@ private class Games.PlatformsView : Gtk.Bin {
selected_platform = row.platform;
subview_title = selected_platform.get_name ();
- collection_view.invalidate_flow_box_filter ();
+ collection_view.apply_filter ();
collection_view.reset_scroll_position ();
}
- private void on_model_changed (uint position, uint removed, uint added) {
- // FIXME: currently games are never removed, update this function if
- // necessary.
- assert (removed == 0);
-
- for (uint i = position; i < position + added; i++) {
- var game = model.get_item (i) as Game;
- var platform = game.get_platform ();
-
- if (!platforms.contains (platform)) {
- platforms.add (platform);
-
- var platform_list_item = new PlatformListItem (platform);
- list_box.add (platform_list_item);
- }
- }
- }
-
- public void select_first_visible_row () {
+ private void select_first_visible_row () {
foreach (var child in list_box.get_children ()) {
var row = child as Gtk.ListBoxRow;
@@ -253,37 +250,13 @@ private class Games.PlatformsView : Gtk.Bin {
}
}
- private void hide_empty_sidebar_items () {
- // Create an array of all the games which fit the search text entered
- // in the top search bar
- Game[] visible_games = {};
-
- for (int i = 0; i < model.get_n_items (); i++) {
- var game = model.get_item (i) as Game;
-
- if (game.matches_search_terms (filtering_terms))
- visible_games += game;
- }
+ private Gtk.Widget add_platform (Object object) {
+ var platform = object as Platform;
- foreach (var row in list_box.get_children ()) {
- var platform_item = row as PlatformListItem;
- var platform = platform_item.platform;
- // Assume row doesn't have any games to show
- var is_row_visible = false;
+ var item = new PlatformListItem (platform);
+ item.show ();
- foreach (var game in visible_games) {
- var game_platform = game.get_platform ().get_name ();
-
- if (game_platform == platform.get_name ()) {
- is_row_visible = true;
- break;
- }
- }
-
- row.visible = is_row_visible;
- }
-
- select_first_visible_row ();
+ return item;
}
[GtkCallback]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]