diff --git a/demos/gtk-demo/main.c b/demos/gtk-demo/main.c
index 8b3979fc42..11e7f0f1b6 100644
--- a/demos/gtk-demo/main.c
+++ b/demos/gtk-demo/main.c
@@ -18,6 +18,7 @@ static gchar *current_file = NULL;
static GtkWidget *notebook;
static GtkSingleSelection *selection;
static GtkWidget *toplevel;
+static char **search_needle;
typedef struct _GtkDemo GtkDemo;
struct _GtkDemo
@@ -945,7 +946,18 @@ selection_cb (GtkSingleSelection *sel,
gpointer user_data)
{
GtkTreeListRow *row = gtk_single_selection_get_selected_item (sel);
- GtkDemo *demo = gtk_tree_list_row_get_item (row);
+ GtkDemo *demo;
+
+ gtk_widget_set_sensitive (GTK_WIDGET (notebook), !!row);
+
+ if (!row)
+ {
+ gtk_window_set_title (GTK_WINDOW (toplevel), "No match");
+
+ return;
+ }
+
+ demo = gtk_tree_list_row_get_item (row);
if (demo->filename)
load_file (demo->name, demo->filename);
@@ -953,6 +965,57 @@ selection_cb (GtkSingleSelection *sel,
gtk_window_set_title (GTK_WINDOW (toplevel), demo->title);
}
+static gboolean
+demo_filter_by_name (GtkTreeListRow *row,
+ GtkFilterListModel *model)
+{
+ GtkDemo *demo;
+ guint i;
+
+ /* Show all items if search is empty */
+ if (!search_needle || !search_needle[0] || !*search_needle[0])
+ return TRUE;
+
+ g_assert (GTK_IS_TREE_LIST_ROW (row));
+ g_assert (GTK_IS_FILTER_LIST_MODEL (model));
+
+ demo = gtk_tree_list_row_get_item (row);
+ g_assert (GTK_IS_DEMO (demo));
+
+ /* Show only if the name maches every needle */
+ for (i = 0; search_needle[i]; i++)
+ {
+ if (!demo->title)
+ return FALSE;
+
+ if (g_str_match_string (search_needle[i], demo->title, TRUE))
+ continue;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+demo_search_changed_cb (GtkSearchEntry *entry,
+ GtkFilter *filter)
+{
+ const char *text;
+
+ g_assert (GTK_IS_SEARCH_ENTRY (entry));
+ g_assert (GTK_IS_FILTER (filter));
+
+ text = gtk_editable_get_text (GTK_EDITABLE (entry));
+
+ g_clear_pointer (&search_needle, g_strfreev);
+
+ if (text && *text)
+ search_needle = g_strsplit (text, " ", 0);
+
+ gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
+}
+
static GListModel *
create_demo_model (void)
{
@@ -1013,7 +1076,9 @@ activate (GApplication *app)
GtkBuilder *builder;
GListModel *listmodel;
GtkTreeListModel *treemodel;
- GtkWidget *window, *listview;
+ GtkWidget *window, *listview, *search_entry;
+ GtkFilterListModel *filter_model;
+ GtkFilter *filter;
static GActionEntry win_entries[] = {
{ "run", activate_run, NULL, NULL, NULL }
@@ -1042,7 +1107,13 @@ activate (GApplication *app)
get_child_model,
NULL,
NULL);
- selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
+ filter_model = gtk_filter_list_model_new (G_LIST_MODEL (treemodel), NULL);
+ filter = gtk_custom_filter_new ((GtkCustomFilterFunc)demo_filter_by_name, filter_model, NULL);
+ gtk_filter_list_model_set_filter (filter_model, filter);
+ search_entry = GTK_WIDGET (gtk_builder_get_object (builder, "search-entry"));
+ g_signal_connect (search_entry, "search-changed", G_CALLBACK (demo_search_changed_cb), filter);
+
+ selection = gtk_single_selection_new (G_LIST_MODEL (filter_model));
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
diff --git a/demos/gtk-demo/main.ui b/demos/gtk-demo/main.ui
index 4c8b80806f..3d18e18bf3 100644
--- a/demos/gtk-demo/main.ui
+++ b/demos/gtk-demo/main.ui
@@ -55,12 +55,29 @@
never
150
-
+
+
+
+
+
+ /ui/main-listitem.ui
+
+
+
+
+