]> Pileus Git - ~andy/gtk/blob - demos/gtk-demo/search_entry.c
Deprecate widget flag: GTK_WIDGET_VISIBLE
[~andy/gtk] / demos / gtk-demo / search_entry.c
1 /* Entry/Search Entry 
2  *
3  * GtkEntry allows to display icons and progress information. 
4  * This demo shows how to use these features in a search entry.
5  */
6
7 #include <gtk/gtk.h>
8
9 static GtkWidget *window = NULL;
10 static GtkWidget *menu = NULL;
11 static GtkWidget *notebook = NULL;
12
13 static guint search_progress_id = 0;
14 static guint finish_search_id = 0;
15
16 static void
17 show_find_button (void)
18 {
19   gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0);
20 }
21
22 static void
23 show_cancel_button (void)
24 {
25   gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1);
26 }
27
28 static gboolean
29 search_progress (gpointer data)
30 {
31   gtk_entry_progress_pulse (GTK_ENTRY (data));
32
33   return TRUE;
34 }
35
36 static void
37 search_progress_done (GtkEntry *entry)
38 {
39   gtk_entry_set_progress_fraction (entry, 0.0);
40 }
41
42 static gboolean
43 finish_search (GtkButton *button)
44 {
45   show_find_button ();
46   g_source_remove (search_progress_id);
47   search_progress_id = 0;
48   
49   return FALSE;
50 }
51
52 static gboolean
53 start_search_feedback (gpointer data)
54 {
55   search_progress_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 100, 
56                                            (GSourceFunc)search_progress, data,
57                                            (GDestroyNotify)search_progress_done);
58   return FALSE;
59 }
60
61 static void
62 start_search (GtkButton *button, 
63               GtkEntry  *entry)
64 {
65   show_cancel_button ();
66   search_progress_id = g_timeout_add_seconds (1, (GSourceFunc)start_search_feedback, entry);
67   finish_search_id = g_timeout_add_seconds (15, (GSourceFunc)finish_search, button);
68 }
69
70
71 static void
72 stop_search (GtkButton *button,
73              gpointer   data)
74 {
75   g_source_remove (finish_search_id);
76   finish_search (button);
77 }
78
79 static void
80 icon_press_cb (GtkEntry       *entry, 
81                gint            position,
82                GdkEventButton *event,
83                gpointer        data)
84 {
85   if (position == GTK_ENTRY_ICON_PRIMARY)
86     gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 
87                     event->button, event->time);
88   else 
89     gtk_entry_set_text (entry, "");
90 }
91
92 static void
93 text_changed_cb (GtkEntry   *entry,
94                  GParamSpec *pspec,
95                  GtkWidget  *button)
96 {
97   gboolean has_text;
98
99   has_text = gtk_entry_get_text_length (entry) > 0;
100   gtk_entry_set_icon_sensitive (entry, 
101                                 GTK_ENTRY_ICON_SECONDARY,
102                                 has_text);
103   gtk_widget_set_sensitive (button, has_text);
104 }
105
106 static void
107 activate_cb (GtkEntry  *entry,
108              GtkButton *button)
109 {
110   if (search_progress_id != 0)
111     return;
112
113   start_search (button, entry);
114
115 }
116
117 static void
118 search_by_name (GtkWidget *item, 
119                 GtkEntry  *entry)
120 {
121   gtk_entry_set_icon_from_stock (entry,
122                                  GTK_ENTRY_ICON_PRIMARY,
123                                  GTK_STOCK_FIND);
124   gtk_entry_set_icon_tooltip_text (entry,
125                                    GTK_ENTRY_ICON_PRIMARY,
126                                    "Search by name\n"
127                                    "Click here to change the search type");
128
129                 
130 static void
131 search_by_description (GtkWidget *item, 
132                        GtkEntry  *entry)
133 {
134   gtk_entry_set_icon_from_stock (entry,
135                                  GTK_ENTRY_ICON_PRIMARY,
136                                  GTK_STOCK_EDIT);
137   gtk_entry_set_icon_tooltip_text (entry,
138                                    GTK_ENTRY_ICON_PRIMARY,
139                                    "Search by description\n"
140                                    "Click here to change the search type");
141
142                 
143 static void
144 search_by_file (GtkWidget *item, 
145                 GtkEntry  *entry)
146 {
147   gtk_entry_set_icon_from_stock (entry,
148                                  GTK_ENTRY_ICON_PRIMARY,
149                                  GTK_STOCK_OPEN);
150   gtk_entry_set_icon_tooltip_text (entry,
151                                    GTK_ENTRY_ICON_PRIMARY,
152                                    "Search by file name\n"
153                                    "Click here to change the search type");
154
155
156 static void
157 search_entry_destroyed (GtkWidget  *widget)
158 {
159   if (finish_search_id != 0)
160     g_source_remove (finish_search_id);
161
162   if (search_progress_id != 0)
163     g_source_remove (search_progress_id);
164
165   window = NULL;
166 }
167
168                 
169 GtkWidget *
170 do_search_entry (GtkWidget *do_widget)
171 {
172   GtkWidget *vbox;
173   GtkWidget *hbox;
174   GtkWidget *label;
175   GtkWidget *entry;
176   GtkWidget *item;
177   GtkWidget *image;
178   GtkWidget *find_button;
179   GtkWidget *cancel_button;
180   
181   if (!window)
182     {
183       window = gtk_dialog_new_with_buttons ("Search Entry",
184                                             GTK_WINDOW (do_widget),
185                                             0,
186                                             GTK_STOCK_CLOSE,
187                                             GTK_RESPONSE_NONE,
188                                             NULL);
189       gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
190
191       g_signal_connect (window, "response",
192                         G_CALLBACK (gtk_widget_destroy), NULL);
193       g_signal_connect (window, "destroy",
194                         G_CALLBACK (search_entry_destroyed), &window);
195
196       vbox = gtk_vbox_new (FALSE, 5);
197       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 0);
198       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
199
200       label = gtk_label_new (NULL);
201       gtk_label_set_markup (GTK_LABEL (label), "Search entry demo");
202       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
203
204       hbox = gtk_hbox_new (FALSE, 10);
205       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
206       gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
207
208       /* Create our entry */
209       entry = gtk_entry_new ();
210       gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
211
212       /* Create the find and cancel buttons */
213       notebook = gtk_notebook_new ();
214       gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
215       gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
216       gtk_box_pack_start (GTK_BOX (hbox), notebook, FALSE, FALSE, 0);
217
218       find_button = gtk_button_new_with_label ("Find");
219       g_signal_connect (find_button, "clicked", 
220                         G_CALLBACK (start_search), entry);
221       gtk_notebook_append_page (GTK_NOTEBOOK (notebook), find_button, NULL);
222       gtk_widget_show (find_button);
223
224       cancel_button = gtk_button_new_with_label ("Cancel");
225       g_signal_connect (cancel_button, "clicked", 
226                         G_CALLBACK (stop_search), NULL);
227       gtk_notebook_append_page (GTK_NOTEBOOK (notebook), cancel_button, NULL);
228       gtk_widget_show (cancel_button);
229
230       /* Set up the search icon */
231       search_by_name (NULL, GTK_ENTRY (entry));
232       
233       /* Set up the clear icon */
234       gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), 
235                                      GTK_ENTRY_ICON_SECONDARY, 
236                                      GTK_STOCK_CLEAR);
237       text_changed_cb (GTK_ENTRY (entry), NULL, find_button);
238
239       g_signal_connect (entry, "icon-press", 
240                         G_CALLBACK (icon_press_cb), NULL);
241       g_signal_connect (entry, "notify::text", 
242                         G_CALLBACK (text_changed_cb), find_button);
243       g_signal_connect (entry, "activate", 
244                         G_CALLBACK (activate_cb), NULL);
245
246       /* Create the menu */
247       menu = gtk_menu_new ();
248       gtk_menu_attach_to_widget (GTK_MENU (menu), entry, NULL);
249
250       item = gtk_image_menu_item_new_with_label ("Search by name");
251       image = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
252       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
253       g_signal_connect (item, "activate", G_CALLBACK (search_by_name), entry);
254       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
255
256       item = gtk_image_menu_item_new_with_label ("Search by description");
257       image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
258       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
259       g_signal_connect (item, "activate", G_CALLBACK (search_by_description), entry);
260       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
261
262       item = gtk_image_menu_item_new_with_label ("Search by file name");
263       image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
264       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
265       g_signal_connect (item, "activate", G_CALLBACK (search_by_file), entry);
266       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
267
268       gtk_widget_show_all (menu);
269     }
270
271   if (!gtk_widget_get_visible (window))
272     gtk_widget_show_all (window);
273   else
274     {
275       gtk_widget_destroy (menu);
276       gtk_widget_destroy (window);
277       window = NULL;
278     }
279
280   return window;
281 }
282
283