1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 * arch-tag: Implementation of search entry widget
5 * Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org>
6 * Copyright (C) 2003 Colin Walters <walters@verbum.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <glib/gi18n.h>
30 #include "libsexy/sexy-icon-entry.h"
32 #include "rb-search-entry.h"
34 static void rb_search_entry_class_init (RBSearchEntryClass
*klass
);
35 static void rb_search_entry_init (RBSearchEntry
*entry
);
36 static void rb_search_entry_finalize (GObject
*object
);
37 static gboolean
rb_search_entry_timeout_cb (RBSearchEntry
*entry
);
38 static void rb_search_entry_changed_cb (GtkEditable
*editable
,
39 RBSearchEntry
*entry
);
40 static void rb_search_entry_activate_cb (GtkEntry
*gtkentry
,
41 RBSearchEntry
*entry
);
42 static gboolean
rb_search_entry_focus_out_event_cb (GtkWidget
*widget
,
44 RBSearchEntry
*entry
);
46 struct RBSearchEntryPrivate
54 gboolean is_a11y_theme
;
57 G_DEFINE_TYPE (RBSearchEntry
, rb_search_entry
, GTK_TYPE_HBOX
)
58 #define RB_SEARCH_ENTRY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_SEARCH_ENTRY, RBSearchEntryPrivate))
67 static guint rb_search_entry_signals
[LAST_SIGNAL
] = { 0 };
70 rb_search_entry_class_init (RBSearchEntryClass
*klass
)
72 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
74 object_class
->finalize
= rb_search_entry_finalize
;
76 rb_search_entry_signals
[SEARCH
] =
77 g_signal_new ("search",
78 G_OBJECT_CLASS_TYPE (object_class
),
80 G_STRUCT_OFFSET (RBSearchEntryClass
, search
),
82 g_cclosure_marshal_VOID__STRING
,
86 rb_search_entry_signals
[ACTIVATE
] =
87 g_signal_new ("activate",
88 G_OBJECT_CLASS_TYPE (object_class
),
90 G_STRUCT_OFFSET (RBSearchEntryClass
, activate
),
92 g_cclosure_marshal_VOID__VOID
,
96 g_type_class_add_private (klass
, sizeof (RBSearchEntryPrivate
));
100 rb_search_entry_init (RBSearchEntry
*entry
)
103 GtkSettings
*settings
;
106 entry
->priv
= RB_SEARCH_ENTRY_GET_PRIVATE (entry
);
108 settings
= gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (entry
)));
109 g_object_get (settings
, "gtk-theme-name", &theme
, NULL
);
110 entry
->priv
->is_a11y_theme
= strncmp (theme
, "HighContrast", strlen ("HighContrast")) == 0 ||
111 strncmp (theme
, "LowContrast", strlen ("LowContrast")) == 0;
114 /* this string can only be so long, or there wont be a search entry :) */
115 label
= gtk_label_new_with_mnemonic (_("_Search:"));
116 gtk_label_set_justify (GTK_LABEL (label
), GTK_JUSTIFY_RIGHT
);
117 gtk_box_pack_start (GTK_BOX (entry
), label
, FALSE
, TRUE
, 0);
119 entry
->priv
->entry
= sexy_icon_entry_new ();
120 sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (entry
->priv
->entry
));
122 gtk_label_set_mnemonic_widget (GTK_LABEL (label
),
125 gtk_box_pack_start (GTK_BOX (entry
), entry
->priv
->entry
, TRUE
, TRUE
, 0);
127 g_signal_connect_object (G_OBJECT (entry
->priv
->entry
),
129 G_CALLBACK (rb_search_entry_changed_cb
),
131 g_signal_connect_object (G_OBJECT (entry
->priv
->entry
),
133 G_CALLBACK (rb_search_entry_focus_out_event_cb
),
135 g_signal_connect_object (G_OBJECT (entry
->priv
->entry
),
137 G_CALLBACK (rb_search_entry_activate_cb
),
142 rb_search_entry_finalize (GObject
*object
)
144 RBSearchEntry
*entry
;
146 g_return_if_fail (object
!= NULL
);
147 g_return_if_fail (RB_IS_SEARCH_ENTRY (object
));
149 entry
= RB_SEARCH_ENTRY (object
);
151 g_return_if_fail (entry
->priv
!= NULL
);
153 G_OBJECT_CLASS (rb_search_entry_parent_class
)->finalize (object
);
157 rb_search_entry_new (void)
159 RBSearchEntry
*entry
;
161 entry
= RB_SEARCH_ENTRY (g_object_new (RB_TYPE_SEARCH_ENTRY
,
165 g_return_val_if_fail (entry
->priv
!= NULL
, NULL
);
171 rb_search_entry_clear (RBSearchEntry
*entry
)
173 if (entry
->priv
->timeout
!= 0) {
174 g_source_remove (entry
->priv
->timeout
);
175 entry
->priv
->timeout
= 0;
178 entry
->priv
->clearing
= TRUE
;
180 gtk_entry_set_text (GTK_ENTRY (entry
->priv
->entry
), "");
182 entry
->priv
->clearing
= FALSE
;
186 rb_search_entry_set_text (RBSearchEntry
*entry
, const char *text
)
188 gtk_entry_set_text (GTK_ENTRY (entry
->priv
->entry
),
193 rb_search_entry_check_style (RBSearchEntry
*entry
)
195 /*GdkColor fg_colour;*/
197 static const GdkColor fallback_bg_colour
= { 0, 0xf7f7, 0xf7f7, 0xbebe }; /* yellow-ish */
200 if (entry
->priv
->is_a11y_theme
)
203 /*fg_colour = GTK_WIDGET(entry)->style->text[GTK_STATE_NORMAL];*/
204 bg_colour
= fallback_bg_colour
;
206 text
= gtk_entry_get_text (GTK_ENTRY (entry
->priv
->entry
));
208 /*gtk_widget_modify_text (entry->priv->entry, GTK_STATE_NORMAL, &fg_colour);*/
209 gtk_widget_modify_base (entry
->priv
->entry
, GTK_STATE_NORMAL
, &bg_colour
);
211 /*gtk_widget_modify_text (entry->priv->entry, GTK_STATE_NORMAL, NULL);*/
212 gtk_widget_modify_base (entry
->priv
->entry
, GTK_STATE_NORMAL
, NULL
);
215 gtk_widget_queue_draw (GTK_WIDGET (entry
));
219 rb_search_entry_changed_cb (GtkEditable
*editable
,
220 RBSearchEntry
*entry
)
222 rb_search_entry_check_style (entry
);
224 if (entry
->priv
->clearing
== TRUE
)
227 if (entry
->priv
->timeout
!= 0) {
228 g_source_remove (entry
->priv
->timeout
);
229 entry
->priv
->timeout
= 0;
232 /* emit it now if we're clearing the entry */
233 if (gtk_entry_get_text (GTK_ENTRY (entry
->priv
->entry
)))
234 entry
->priv
->timeout
= g_timeout_add (300, (GSourceFunc
) rb_search_entry_timeout_cb
, entry
);
236 rb_search_entry_timeout_cb (entry
);
240 rb_search_entry_timeout_cb (RBSearchEntry
*entry
)
242 gdk_threads_enter ();
244 g_signal_emit (G_OBJECT (entry
), rb_search_entry_signals
[SEARCH
], 0,
245 gtk_entry_get_text (GTK_ENTRY (entry
->priv
->entry
)));
246 entry
->priv
->timeout
= 0;
248 gdk_threads_leave ();
254 rb_search_entry_focus_out_event_cb (GtkWidget
*widget
,
255 GdkEventFocus
*event
,
256 RBSearchEntry
*entry
)
258 if (entry
->priv
->timeout
== 0)
261 g_source_remove (entry
->priv
->timeout
);
262 entry
->priv
->timeout
= 0;
264 g_signal_emit (G_OBJECT (entry
), rb_search_entry_signals
[SEARCH
], 0,
265 gtk_entry_get_text (GTK_ENTRY (entry
->priv
->entry
)));
271 rb_search_entry_searching(RBSearchEntry
*entry
)
273 return strcmp ("", gtk_entry_get_text (GTK_ENTRY (entry
->priv
->entry
))) != 0;
277 rb_search_entry_activate_cb (GtkEntry
*gtkentry
,
278 RBSearchEntry
*entry
)
280 g_signal_emit (G_OBJECT (entry
), rb_search_entry_signals
[ACTIVATE
], 0);
284 rb_search_entry_grab_focus (RBSearchEntry
*entry
)
286 gtk_widget_grab_focus (GTK_WIDGET (entry
->priv
->entry
));