Initial import of ephy (rev# 7126) from svn
[ephy-soc.git] / lib / widgets / .svn / text-base / ephy-icon-entry.c.svn-base
bloba84c40a45eb5d8c31f334d03986eb068de78e5e7
1 /*
2  *  Copyright © 2003, 2004, 2005  Christian Persch
3  *
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.
8  *
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.
13  *
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.
18  *
19  *  Adapted and modified from gtk+ code:
20  *
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/. 
26  *
27  *  $Id$
28  */
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)
79         {
80                 *xborder += focus_width;
81                 *yborder += focus_width;
82         }
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)
102         {
103                 x += focus_width;
104                 y += focus_width;
105                 width -= 2 * focus_width;
106                 height -= 2 * focus_width;
107         }
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);
114      
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)
121         {
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);
132         }
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.
156          */
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))
211         {
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;
217         }
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))
238         {
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);
249         }
250   
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)
265         {
266                 ephy_icon_entry_paint (widget, event);
267         }
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))
294         {
295                 const GTypeInfo our_info =
296                 {
297                         sizeof (EphyIconEntryClass),
298                         NULL,
299                         NULL,
300                         (GClassInitFunc) ephy_icon_entry_class_init,
301                         NULL,
302                         NULL,
303                         sizeof (EphyIconEntry),
304                         0,
305                         (GInstanceInitFunc) ephy_icon_entry_init
306                 };
308                 type = g_type_register_static (GTK_TYPE_BIN,
309                                                "EphyIconEntry",
310                                                &our_info, 0);
311         }
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)
336         {
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);
339         }
340         else
341         {
342                 gtk_box_pack_end (GTK_BOX (priv->hbox), widget, FALSE, FALSE, /* FIXME */ 2);
343         }
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;