[gnome-builder/wip/chergert/shortcuts: 16/24] shortcuts: implement basic search support



commit 9c972e2161c15de79b852fa2ee31b58cb85ee0dd
Author: Christian Hergert <christian hergert me>
Date:   Thu Aug 27 22:14:49 2015 -0700

    shortcuts: implement basic search support
    
    I still want this to move you to the first page with matching items,
    but we'll get there eventually.

 data/theme/shared.css                 |    5 ++
 src/keybindings/gb-shortcuts-window.c |   81 +++++++++++++++++++++++++++++++--
 2 files changed, 82 insertions(+), 4 deletions(-)
---
diff --git a/data/theme/shared.css b/data/theme/shared.css
index e00c859..84ee016 100644
--- a/data/theme/shared.css
+++ b/data/theme/shared.css
@@ -135,3 +135,8 @@ GbWorkspacePane .pane-separator {
   padding-left: 0px;
   padding-right: 0px;
 }
+
+
+.filtered {
+  opacity: .30;
+}
diff --git a/src/keybindings/gb-shortcuts-window.c b/src/keybindings/gb-shortcuts-window.c
index 77c5584..6646b3c 100644
--- a/src/keybindings/gb-shortcuts-window.c
+++ b/src/keybindings/gb-shortcuts-window.c
@@ -17,6 +17,7 @@
  */
 
 #include <glib/gi18n.h>
+#include <ide.h>
 
 #include "gb-accel-label.h"
 #include "gb-shortcuts-window.h"
@@ -64,6 +65,19 @@ gb_shortcuts_window_set_view (GbShortcutsWindow *self,
 }
 
 static void
+register_keywords (GbShortcutsWindow *self,
+                   GtkWidget         *widget,
+                   const gchar       *keywords)
+{
+  gchar *casefold;
+
+  g_assert (GB_IS_SHORTCUTS_WINDOW (self));
+
+  casefold = g_utf8_casefold (keywords, -1);
+  g_hash_table_insert (self->widget_keywords, widget, casefold);
+}
+
+static void
 adjust_page_buttons (GtkWidget *widget,
                      gpointer   data)
 {
@@ -167,10 +181,10 @@ gb_shortcuts_window_build (GbShortcutsWindow *self)
   }
 #define SHORTCUT(_accel, _desc) \
   { \
+    g_autofree gchar *keywords = NULL; \
     GtkBox *shortcut; \
     GbAccelLabel *accel; \
     GtkLabel *desc; \
-    gchar *keywords; \
     shortcut = g_object_new (GTK_TYPE_BOX, \
                              "orientation", GTK_ORIENTATION_HORIZONTAL, \
                              "spacing", 10, \
@@ -193,15 +207,15 @@ gb_shortcuts_window_build (GbShortcutsWindow *self)
                          NULL); \
     gtk_container_add (GTK_CONTAINER (shortcut), GTK_WIDGET (desc)); \
     keywords = g_strdup_printf ("%s %s", _accel, _desc); \
-    g_hash_table_insert (self->widget_keywords, shortcut, keywords); \
+    register_keywords (self, GTK_WIDGET (shortcut), keywords); \
   }
 #define GESTURE(_accel, _title, _subtitle) \
   { \
+    g_autofree gchar *keywords = NULL; \
     GtkBox *gesture; \
     GtkLabel *primary; \
     GtkLabel *subtitle; \
     GtkImage *image; \
-    gchar *keywords; \
     gesture = g_object_new (GTK_TYPE_GRID, \
                             "column-spacing", 12, \
                             "visible", TRUE, \
@@ -239,7 +253,7 @@ gb_shortcuts_window_build (GbShortcutsWindow *self)
                                        "left-attach", 1, \
                                        NULL); \
     keywords = g_strdup_printf ("%s %s %s", _accel, _title, _subtitle); \
-    g_hash_table_insert (self->widget_keywords, gesture, keywords); \
+    register_keywords (self, GTK_WIDGET (gesture), keywords); \
   }
 
 
@@ -256,6 +270,58 @@ gb_shortcuts_window_build (GbShortcutsWindow *self)
 }
 
 static void
+remove_filter_class (gpointer key,
+                     gpointer value,
+                     gpointer user_data)
+{
+  gtk_style_context_remove_class (gtk_widget_get_style_context (key), "filtered");
+}
+
+static void
+add_filter_class (gpointer key,
+                  gpointer value,
+                  gpointer user_data)
+{
+  gtk_style_context_add_class (gtk_widget_get_style_context (key), "filtered");
+}
+
+static void
+gb_shortcuts_window__search_entry__changed (GbShortcutsWindow *self,
+                                            GtkSearchEntry    *search_entry)
+{
+  g_autoptr(IdePatternSpec) spec = NULL;
+  GHashTableIter iter;
+  const gchar *text;
+  gpointer key;
+  gpointer value;
+
+  g_assert (GB_IS_SHORTCUTS_WINDOW (self));
+  g_assert (GTK_IS_SEARCH_ENTRY (search_entry));
+
+  text = gtk_entry_get_text (GTK_ENTRY (search_entry));
+
+  if (ide_str_empty0 (text))
+    {
+      g_hash_table_foreach (self->widget_keywords, remove_filter_class, NULL);
+      return;
+    }
+
+  spec = ide_pattern_spec_new (text);
+
+  g_hash_table_iter_init (&iter, self->widget_keywords);
+
+  while (g_hash_table_iter_next (&iter, &key, &value))
+    {
+      const gchar *keywords = value;
+
+      if (ide_pattern_spec_match (spec, keywords))
+        remove_filter_class (key, value, NULL);
+      else
+        add_filter_class (key, value, NULL);
+    }
+}
+
+static void
 gb_shortcuts_window_constructed (GObject *object)
 {
   GbShortcutsWindow *self = (GbShortcutsWindow *)object;
@@ -299,5 +365,12 @@ gb_shortcuts_window_init (GbShortcutsWindow *self)
   self->widget_keywords = g_hash_table_new_full (NULL, NULL, NULL, g_free);
 
   gtk_widget_init_template (GTK_WIDGET (self));
+
   gb_shortcuts_window_build (self);
+
+  g_signal_connect_object (self->search_entry,
+                           "changed",
+                           G_CALLBACK (gb_shortcuts_window__search_entry__changed),
+                           self,
+                           G_CONNECT_SWAPPED);
 }


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