summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Wood <thomas.wood@intel.com>2010-01-14 15:35:15 +0000
committerThomas Wood <thomas.wood@intel.com>2010-01-14 15:35:15 +0000
commitb360a31d869e082acf12c87445778f738f3a21fc (patch)
tree6d8f900bf632059fdb8df3b2ca5f38b3eb2126a8
parentd4f3cb183d57648c79f132ce243a44ec44a9bd4c (diff)
downloadgnome-control-center-single-window-shell.tar.gz
[shell] implement search filter featuresingle-window-shell
Allow the user to filter the list by typing a search term in the search box.
-rw-r--r--shell/control-center.c124
-rw-r--r--shell/shell.ui24
2 files changed, 140 insertions, 8 deletions
diff --git a/shell/control-center.c b/shell/control-center.c
index c9bbc0e56..7fc9a81db 100644
--- a/shell/control-center.c
+++ b/shell/control-center.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009 Intel, Inc.
+ * Copyright (c) 2009, 2010 Intel, Inc.
*
* The Control Center is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
@@ -19,6 +19,8 @@
*/
#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <string.h>
#define GMENU_I_KNOW_THIS_IS_UNSTABLE
#include <gnome-menus/gmenu-tree.h>
@@ -34,6 +36,11 @@ typedef struct
GSList *icon_views;
gchar *current_title;
+
+ GtkListStore *store;
+ GtkTreeModel *filter;
+ gchar *filter_string;
+
} ShellData;
void item_activated_cb (GtkIconView *icon_view, GtkTreePath *path, ShellData *data);
@@ -92,13 +99,38 @@ selection_changed_cb (GtkIconView *view,
}
}
+gboolean
+model_filter_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ ShellData *data)
+{
+ gchar *name;
+ gchar *needle, *haystack;
+
+ gtk_tree_model_get (model, iter, 0, &name, -1);
+
+ if (!data->filter_string)
+ return FALSE;
+
+ if (!name)
+ return FALSE;
+
+ needle = g_utf8_casefold (data->filter_string, -1);
+ haystack = g_utf8_casefold (name, -1);
+
+ if (strstr (haystack, needle))
+ return TRUE;
+ else
+ return FALSE;
+}
+
void
fill_model (ShellData *data)
{
GSList *list, *l;
GMenuTreeDirectory *d;
GMenuTree *t;
- GtkWidget *vbox;
+ GtkWidget *vbox, *w;
vbox = W (data->builder, "main-vbox");
@@ -108,6 +140,27 @@ fill_model (ShellData *data)
list = gmenu_tree_directory_get_contents (d);
+ data->store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING,
+ GDK_TYPE_PIXBUF);
+ data->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (data->store),
+ NULL);
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (data->filter),
+ (GtkTreeModelFilterVisibleFunc)
+ model_filter_func,
+ data, NULL);
+ w = (GtkWidget *) gtk_builder_get_object (data->builder, "search-view");
+ gtk_icon_view_set_model (GTK_ICON_VIEW (w), GTK_TREE_MODEL (data->filter));
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (w), 2);
+ gtk_icon_view_set_text_column (GTK_ICON_VIEW (w), 0);
+ gtk_icon_view_set_item_width (GTK_ICON_VIEW (w), 120);
+ g_signal_connect (w, "item-activated",
+ G_CALLBACK (item_activated_cb), data);
+ g_signal_connect (w, "button-release-event",
+ G_CALLBACK (button_release_cb), data);
+ g_signal_connect (w, "selection-changed",
+ G_CALLBACK (selection_changed_cb), data);
+
+
for (l = list; l; l = l->next)
{
GMenuTreeItemType type;
@@ -180,6 +233,12 @@ fill_model (ShellData *data)
1, exec,
2, pixbuf,
-1);
+
+ gtk_list_store_insert_with_values (data->store, NULL, 0,
+ 0, name,
+ 1, exec,
+ 2, pixbuf,
+ -1);
}
}
}
@@ -190,7 +249,7 @@ fill_model (ShellData *data)
static gboolean
switch_after_delay (ShellData *data)
{
- gtk_notebook_set_current_page (GTK_NOTEBOOK (data->notebook), 1);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (data->notebook), 2);
gtk_widget_show (W (data->builder, "home-button"));
@@ -272,12 +331,58 @@ home_button_clicked_cb (GtkButton *button,
gtk_widget_hide (GTK_WIDGET (button));
}
+void
+search_entry_changed_cb (GtkEntry *entry,
+ ShellData *data)
+{
+ g_free (data->filter_string);
+ data->filter_string = g_strdup (gtk_entry_get_text (entry));
+
+ if (!g_strcmp0 (data->filter_string, ""))
+ {
+ home_button_clicked_cb (GTK_BUTTON (gtk_builder_get_object (data->builder,
+ "home-button")),
+ data);
+ }
+ else
+ {
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (data->filter));
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (data->notebook), 1);
+ }
+}
+
+gboolean
+search_entry_key_press_event_cb (GtkEntry *entry,
+ GdkEventKey *event,
+ ShellData *data)
+{
+ if (event->keyval == GDK_Return)
+ {
+ GtkTreePath *path;
+
+ path = gtk_tree_path_new_first ();
+ item_activated_cb ((GtkIconView *) gtk_builder_get_object (data->builder,
+ "search-view"),
+ path, data);
+ gtk_tree_path_free (path);
+ return TRUE;
+ }
+
+ if (event->keyval == GDK_Escape)
+ {
+ gtk_entry_set_text (entry, "");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
int
main (int argc, char **argv)
{
ShellData *data;
guint ret;
- GdkColor color = {0, 32767, 32767, 32767};
+ GtkWidget *widget;
gtk_init (&argc, &argv);
@@ -300,16 +405,21 @@ main (int argc, char **argv)
fill_model (data);
- gtk_widget_modify_text (W (data->builder,"search-entry"), GTK_STATE_NORMAL,
- &color);
-
g_signal_connect (gtk_builder_get_object (data->builder, "home-button"),
"clicked", G_CALLBACK (home_button_clicked_cb), data);
+ widget = (GtkWidget*) gtk_builder_get_object (data->builder, "search-entry");
+
+ g_signal_connect (widget, "changed", G_CALLBACK (search_entry_changed_cb),
+ data);
+ g_signal_connect (widget, "key-press-event",
+ G_CALLBACK (search_entry_key_press_event_cb), data);
+
gtk_widget_show_all (data->window);
gtk_main ();
+ g_free (data->filter_string);
g_free (data->current_title);
g_free (data);
diff --git a/shell/shell.ui b/shell/shell.ui
index 41f17044e..db8793f39 100644
--- a/shell/shell.ui
+++ b/shell/shell.ui
@@ -45,7 +45,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
- <property name="text" translatable="yes">Type to search your settings</property>
+ <property name="primary_icon_stock">gtk-find</property>
</object>
</child>
</object>
@@ -99,6 +99,28 @@
<child type="tab">
<placeholder/>
</child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkIconView" id="search-view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">liststore</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="position">1</property>