Initial import of ephy (rev# 7126) from svn
[ephy-soc.git] / lib / widgets / ephy-icon-entry.c
bloba40b6978c23ecee12a33c7df6b8ce92c59a8f154
1 /*
2 * Copyright © 2003, 2004, 2005 Christian Persch
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
19 * Adapted and modified from gtk+ code:
21 * Copyright © 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
22 * Modified by the GTK+ Team and others 1997-2005. See the AUTHORS
23 * file in the gtk+ distribution for a list of people on the GTK+ Team.
24 * See the ChangeLog in the gtk+ distribution files for a list of changes.
25 * These files are distributed with GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 * $Id: ephy-icon-entry.c 6952 2007-03-11 19:42:02Z chpe $
30 #include "config.h"
32 #include "ephy-icon-entry.h"
34 #include <gtk/gtkentry.h>
35 #include <gtk/gtkbox.h>
36 #include <gtk/gtkhbox.h>
38 #define EPHY_ICON_ENTRY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_ICON_ENTRY, EphyIconEntryPrivate))
40 struct _EphyIconEntryPrivate
42 GtkWidget *hbox;
45 static GtkWidgetClass *parent_class = NULL;
47 /* private helper functions */
49 static gboolean
50 entry_focus_change_cb (GtkWidget *widget,
51 GdkEventFocus *event,
52 GtkWidget *entry)
54 gtk_widget_queue_draw (entry);
56 return FALSE;
59 static void
60 ephy_icon_entry_get_borders (GtkWidget *widget,
61 GtkWidget *entry,
62 int *xborder,
63 int *yborder)
65 int focus_width;
66 gboolean interior_focus;
68 g_return_if_fail (entry->style != NULL);
70 gtk_widget_style_get (entry,
71 "focus-line-width", &focus_width,
72 "interior-focus", &interior_focus,
73 NULL);
75 *xborder = entry->style->xthickness;
76 *yborder = entry->style->ythickness;
78 if (!interior_focus)
80 *xborder += focus_width;
81 *yborder += focus_width;
85 static void
86 ephy_icon_entry_paint (GtkWidget *widget,
87 GdkEventExpose *event)
89 EphyIconEntry *entry = EPHY_ICON_ENTRY (widget);
90 GtkWidget *entry_widget = entry->entry;
91 int x = 0, y = 0, width, height, focus_width;
92 gboolean interior_focus;
94 gtk_widget_style_get (entry_widget,
95 "interior-focus", &interior_focus,
96 "focus-line-width", &focus_width,
97 NULL);
99 gdk_drawable_get_size (widget->window, &width, &height);
101 if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus)
103 x += focus_width;
104 y += focus_width;
105 width -= 2 * focus_width;
106 height -= 2 * focus_width;
109 gtk_paint_flat_box (entry_widget->style, widget->window,
110 GTK_WIDGET_STATE (entry_widget), GTK_SHADOW_NONE,
111 NULL, entry_widget, "entry_bg",
112 /* FIXME: was 0, 0 in gtk_entry_expose, but I think this is correct: */
113 x, y, width, height);
115 gtk_paint_shadow (entry_widget->style, widget->window,
116 GTK_STATE_NORMAL, GTK_SHADOW_IN,
117 NULL, entry_widget, "entry",
118 x, y, width, height);
120 if (GTK_WIDGET_HAS_FOCUS (entry_widget) && !interior_focus)
122 x -= focus_width;
123 y -= focus_width;
124 width += 2 * focus_width;
125 height += 2 * focus_width;
127 gtk_paint_focus (entry_widget->style, widget->window,
128 GTK_WIDGET_STATE (entry_widget),
129 NULL, entry_widget, "entry",
130 /* FIXME: was 0, 0 in gtk_entry_draw_frame, but I think this is correct: */
131 x, y, width, height);
135 /* Class implementation */
137 static void
138 ephy_icon_entry_init (EphyIconEntry *entry)
140 EphyIconEntryPrivate *priv;
141 GtkWidget *widget = (GtkWidget *) entry;
143 priv = entry->priv = EPHY_ICON_ENTRY_GET_PRIVATE (entry);
145 GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW);
147 priv->hbox = gtk_hbox_new (FALSE, /* FIXME */ 0);
148 gtk_container_add (GTK_CONTAINER (entry), priv->hbox);
150 entry->entry = gtk_entry_new ();
151 gtk_entry_set_has_frame (GTK_ENTRY (entry->entry), FALSE);
152 gtk_box_pack_start (GTK_BOX (priv->hbox), entry->entry, TRUE, TRUE, /* FIXME */ 0);
154 /* We need to queue a redraw when focus changes, to comply with themes
155 * (like Clearlooks) which draw focused and unfocused entries differently.
157 g_signal_connect_after (entry->entry, "focus-in-event",
158 G_CALLBACK (entry_focus_change_cb), entry);
159 g_signal_connect_after (entry->entry, "focus-out-event",
160 G_CALLBACK (entry_focus_change_cb), entry);
163 static void
164 ephy_icon_entry_realize (GtkWidget *widget)
166 GdkWindowAttr attributes;
167 gint attributes_mask;
168 gint border_width;
170 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
172 border_width = GTK_CONTAINER (widget)->border_width;
174 attributes.x = widget->allocation.x + border_width;
175 attributes.y = widget->allocation.y + border_width;
176 attributes.width = widget->allocation.width - 2 * border_width;
177 attributes.height = widget->allocation.height - 2 * border_width;
178 attributes.window_type = GDK_WINDOW_CHILD;
179 attributes.event_mask = gtk_widget_get_events (widget)
180 | GDK_EXPOSURE_MASK;
182 attributes.visual = gtk_widget_get_visual (widget);
183 attributes.colormap = gtk_widget_get_colormap (widget);
184 attributes.wclass = GDK_INPUT_OUTPUT;
185 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
187 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
188 &attributes, attributes_mask);
189 gdk_window_set_user_data (widget->window, widget);
191 widget->style = gtk_style_attach (widget->style, widget->window);
193 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
196 static void
197 ephy_icon_entry_size_request (GtkWidget *widget,
198 GtkRequisition *requisition)
200 EphyIconEntry *entry = EPHY_ICON_ENTRY (widget);
201 GtkContainer *container = GTK_CONTAINER (widget);
202 GtkBin *bin = GTK_BIN (widget);
203 int xborder, yborder;
205 requisition->width = requisition->height = container->border_width * 2;
207 gtk_widget_ensure_style (entry->entry);
208 ephy_icon_entry_get_borders (widget, entry->entry, &xborder, &yborder);
210 if (GTK_WIDGET_VISIBLE (bin->child))
212 GtkRequisition child_requisition;
214 gtk_widget_size_request (bin->child, &child_requisition);
215 requisition->width += child_requisition.width;
216 requisition->height += child_requisition.height;
219 requisition->width += 2 * xborder;
220 requisition->height += 2 * yborder;
223 static void
224 ephy_icon_entry_size_allocate (GtkWidget *widget,
225 GtkAllocation *allocation)
227 EphyIconEntry *entry = EPHY_ICON_ENTRY (widget);
228 GtkContainer *container = GTK_CONTAINER (widget);
229 GtkBin *bin = GTK_BIN (widget);
230 GtkAllocation child_allocation;
231 int xborder, yborder;
233 widget->allocation = *allocation;
235 ephy_icon_entry_get_borders (widget, entry->entry, &xborder, &yborder);
237 if (GTK_WIDGET_REALIZED (widget))
239 child_allocation.x = container->border_width;
240 child_allocation.y = container->border_width;
241 child_allocation.width = MAX (allocation->width - container->border_width * 2, 0);
242 child_allocation.height = MAX (allocation->height - container->border_width * 2, 0);
244 gdk_window_move_resize (widget->window,
245 allocation->x + child_allocation.x,
246 allocation->y + child_allocation.y,
247 child_allocation.width,
248 child_allocation.height);
251 child_allocation.x = container->border_width + xborder;
252 child_allocation.y = container->border_width + yborder;
253 child_allocation.width = MAX (allocation->width - (container->border_width + xborder) * 2, 0);
254 child_allocation.height = MAX (allocation->height - (container->border_width + yborder) * 2, 0);
256 gtk_widget_size_allocate (bin->child, &child_allocation);
259 static gboolean
260 ephy_icon_entry_expose (GtkWidget *widget,
261 GdkEventExpose *event)
263 if (GTK_WIDGET_DRAWABLE (widget) &&
264 event->window == widget->window)
266 ephy_icon_entry_paint (widget, event);
269 return parent_class->expose_event (widget, event);
272 static void
273 ephy_icon_entry_class_init (EphyIconEntryClass *klass)
275 GObjectClass *object_class = G_OBJECT_CLASS (klass);
276 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
278 parent_class = GTK_WIDGET_CLASS (g_type_class_peek_parent (klass));
280 widget_class->realize = ephy_icon_entry_realize;
281 widget_class->size_request = ephy_icon_entry_size_request;
282 widget_class->size_allocate = ephy_icon_entry_size_allocate;
283 widget_class->expose_event = ephy_icon_entry_expose;
285 g_type_class_add_private (object_class, sizeof (EphyIconEntryPrivate));
288 GType
289 ephy_icon_entry_get_type (void)
291 static GType type = 0;
293 if (G_UNLIKELY (type == 0))
295 const GTypeInfo our_info =
297 sizeof (EphyIconEntryClass),
298 NULL,
299 NULL,
300 (GClassInitFunc) ephy_icon_entry_class_init,
301 NULL,
302 NULL,
303 sizeof (EphyIconEntry),
305 (GInstanceInitFunc) ephy_icon_entry_init
308 type = g_type_register_static (GTK_TYPE_BIN,
309 "EphyIconEntry",
310 &our_info, 0);
313 return type;
316 /* public functions */
318 GtkWidget *
319 ephy_icon_entry_new (void)
321 return GTK_WIDGET (g_object_new (EPHY_TYPE_ICON_ENTRY, NULL));
324 void
325 ephy_icon_entry_pack_widget (EphyIconEntry *entry,
326 GtkWidget *widget,
327 gboolean start)
329 EphyIconEntryPrivate *priv;
331 g_return_if_fail (EPHY_IS_ICON_ENTRY (entry));
333 priv = entry->priv;
335 if (start)
337 gtk_box_pack_start (GTK_BOX (priv->hbox), widget, FALSE, FALSE, /* FIXME */ 2);
338 gtk_box_reorder_child (GTK_BOX (priv->hbox), widget, 0);
340 else
342 gtk_box_pack_end (GTK_BOX (priv->hbox), widget, FALSE, FALSE, /* FIXME */ 2);
346 GtkWidget *
347 ephy_icon_entry_get_entry (EphyIconEntry *entry)
349 g_return_val_if_fail (EPHY_IS_ICON_ENTRY (entry), NULL);
351 return entry->entry;