[gtk: 1/2] demo: Add a search filter



commit 7583d482664134ec830a48eb42bbdb96e4f17dbf
Author: Mohammed Sadiq <sadiq sadiqpk org>
Date:   Sun Jul 12 21:09:27 2020 +0530

    demo: Add a search filter

 demos/gtk-demo/main.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--
 demos/gtk-demo/main.ui | 27 ++++++++++++++----
 2 files changed, 96 insertions(+), 8 deletions(-)
---
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 @@
             <property name="hscrollbar-policy">never</property>
             <property name="min-content-width">150</property>
             <child>
-              <object class="GtkListView" id="listview">
-                <property name="factory">
-                  <object class="GtkBuilderListItemFactory">
-                    <property name="resource">/ui/main-listitem.ui</property>
+              <object class="GtkBox">
+                <property name="width-request">220</property>
+                <property name="orientation">vertical</property>
+
+                <child>
+                  <object class="GtkSearchBar">
+                    <property name="search-mode-enabled">1</property>
+                    <child>
+                      <object class="GtkSearchEntry" id="search-entry"/>
+                    </child>
                   </object>
-                </property>
+                </child>
+
+                <child>
+                  <object class="GtkListView" id="listview">
+                    <property name="factory">
+                      <object class="GtkBuilderListItemFactory">
+                        <property name="resource">/ui/main-listitem.ui</property>
+                      </object>
+                    </property>
+                  </object>
+                </child>
+
               </object>
             </child>
           </object>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]