diff options
author | Thomas Wood <thomas.wood@intel.com> | 2010-01-14 15:35:15 +0000 |
---|---|---|
committer | Thomas Wood <thomas.wood@intel.com> | 2010-01-14 15:35:15 +0000 |
commit | b360a31d869e082acf12c87445778f738f3a21fc (patch) | |
tree | 6d8f900bf632059fdb8df3b2ca5f38b3eb2126a8 | |
parent | d4f3cb183d57648c79f132ce243a44ec44a9bd4c (diff) | |
download | gnome-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.c | 124 | ||||
-rw-r--r-- | shell/shell.ui | 24 |
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">●</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> |