r2371: Fixed clipping and wrapping problems with pinboard icon text.
[rox-filer.git] / ROX-Filer / src / wrapped.c
blob5631dc3454501d54e6b70df14a97bdc6ebe20c7c
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2003, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* wrapped.c - a replacement for GtkLabel that wraps sensibly */
24 #include "config.h"
26 #include <gtk/gtk.h>
28 #include "global.h"
30 #include "wrapped.h"
32 static gpointer parent_class = NULL;
34 /* Static prototypes */
35 static void wrapped_label_finialize(GObject *object);
36 static void wrapped_label_class_init(gpointer gclass, gpointer data);
37 static void wrapped_label_init(GTypeInstance *object, gpointer gclass);
38 static void wrapped_label_size_request(GtkWidget *widget,
39 GtkRequisition *requisition);
40 static gint wrapped_label_expose(GtkWidget *widget, GdkEventExpose *event);
41 static void wrapped_label_style_set(GtkWidget *widget,
42 GtkStyle *previous_style);
45 /****************************************************************
46 * EXTERNAL INTERFACE *
47 ****************************************************************/
49 GtkWidget *wrapped_label_new(const char *text, gint width)
51 WrappedLabel *wl;
53 wl = g_object_new(wrapped_label_get_type(), NULL);
54 wl->width = width;
56 wrapped_label_set_text(wl, text);
58 return GTK_WIDGET(wl);
61 void wrapped_label_set_text(WrappedLabel *wl, const char *text)
63 GtkWidget *widget = GTK_WIDGET(wl);
65 if (!wl->layout)
67 wl->layout = gtk_widget_create_pango_layout(widget, text);
68 pango_layout_set_width(wl->layout, wl->width * PANGO_SCALE);
69 pango_layout_set_wrap(wl->layout, PANGO_WRAP_WORD);
70 pango_layout_set_alignment(wl->layout, PANGO_ALIGN_CENTER);
73 gtk_widget_queue_resize(widget);
76 /****************************************************************
77 * INTERNAL FUNCTIONS *
78 ****************************************************************/
80 static void wrapped_label_finialize(GObject *object)
82 WrappedLabel *wl = (WrappedLabel *) object;
84 if (wl->layout)
86 g_object_unref(G_OBJECT(wl->layout));
87 wl->layout = NULL;
90 G_OBJECT_CLASS(parent_class)->finalize(object);
93 static void wrapped_label_class_init(gpointer gclass, gpointer data)
95 GObjectClass *object = (GObjectClass *) gclass;
96 GtkWidgetClass *widget_class = (GtkWidgetClass *) gclass;
98 parent_class = g_type_class_peek_parent(gclass);
100 object->finalize = wrapped_label_finialize;
102 widget_class->size_request = wrapped_label_size_request;
103 widget_class->expose_event = wrapped_label_expose;
104 widget_class->style_set = wrapped_label_style_set;
107 static void wrapped_label_init(GTypeInstance *object, gpointer gclass)
109 WrappedLabel *wl = (WrappedLabel *) object;
110 GtkWidget *widget = (GtkWidget *) object;
112 GTK_WIDGET_SET_FLAGS(widget, GTK_NO_WINDOW);
114 wl->layout = NULL;
115 wl->width = -1;
116 wl->text_width = -1;
119 GType wrapped_label_get_type(void)
121 static GType type = 0;
123 if (!type)
125 static const GTypeInfo info =
127 sizeof (WrappedLabelClass),
128 NULL, /* base_init */
129 NULL, /* base_finalise */
130 wrapped_label_class_init,
131 NULL, /* class_finalise */
132 NULL, /* class_data */
133 sizeof(WrappedLabel),
134 0, /* n_preallocs */
135 wrapped_label_init
138 type = g_type_register_static(GTK_TYPE_WIDGET, "WrappedLabel",
139 &info, 0);
142 return type;
145 static void wrapped_label_size_request(GtkWidget *widget,
146 GtkRequisition *requisition)
148 PangoRectangle logical_rect;
149 WrappedLabel *wl = (WrappedLabel *) widget;
151 g_return_if_fail(wl->layout != NULL);
153 pango_layout_get_extents(wl->layout, NULL, &logical_rect);
155 wl->x_off = PANGO_PIXELS(logical_rect.x);
156 wl->y_off = PANGO_PIXELS(logical_rect.y);
157 wl->text_width = PANGO_PIXELS(logical_rect.width);
159 requisition->width = PANGO_PIXELS(logical_rect.width);
160 requisition->height = PANGO_PIXELS(logical_rect.height);
163 static gint wrapped_label_expose(GtkWidget *widget, GdkEventExpose *event)
165 WrappedLabel *wl = (WrappedLabel *) widget;
166 int x;
168 g_return_val_if_fail(event != NULL, TRUE);
169 g_return_val_if_fail(wl->layout != NULL, TRUE);
171 x = widget->allocation.x -
172 ((wl->text_width - widget->allocation.width) >> 1);
174 gtk_paint_layout(widget->style,
175 widget->window,
176 GTK_WIDGET_STATE(widget),
177 FALSE,
178 NULL, /* DON'T clip! */
179 widget,
180 "label",
181 x - wl->x_off,
182 widget->allocation.y - wl->y_off,
183 wl->layout);
185 return FALSE;
188 static void wrapped_label_style_set(GtkWidget *widget,
189 GtkStyle *previous_style)
191 WrappedLabel *wl = (WrappedLabel *) widget;
193 if (wl->layout)
195 const gchar *txt;
196 PangoLayout *old = wl->layout;
198 txt = pango_layout_get_text(wl->layout);
200 wl->layout = NULL;
201 wrapped_label_set_text(wl, txt);
203 g_object_unref(old);