Converted README to markdown
[rox-filer.git] / ROX-Filer / src / wrapped.c
blob7fa0eda79f87604be0a660d91070b806ab8fee80
1 /*
2 * ROX-Filer, filer for the ROX desktop project
3 * Copyright (C) 2006, Thomas Leonard and others (see changelog for details).
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place, Suite 330, Boston, MA 02111-1307 USA
20 /* wrapped.c - a replacement for GtkLabel that wraps sensibly */
22 #include "config.h"
24 #include <gtk/gtk.h>
26 #include "global.h"
28 #include "wrapped.h"
30 static gpointer parent_class = NULL;
32 /* Static prototypes */
33 static void wrapped_label_finialize(GObject *object);
34 static void wrapped_label_class_init(gpointer gclass, gpointer data);
35 static void wrapped_label_init(GTypeInstance *object, gpointer gclass);
36 static void wrapped_label_size_request(GtkWidget *widget,
37 GtkRequisition *requisition);
38 static gint wrapped_label_expose(GtkWidget *widget, GdkEventExpose *event);
39 static void wrapped_label_style_set(GtkWidget *widget,
40 GtkStyle *previous_style);
43 /****************************************************************
44 * EXTERNAL INTERFACE *
45 ****************************************************************/
47 GtkWidget *wrapped_label_new(const char *text, gint width)
49 WrappedLabel *wl;
51 wl = g_object_new(wrapped_label_get_type(), NULL);
52 wl->width = width;
54 wrapped_label_set_text(wl, text);
56 return GTK_WIDGET(wl);
59 void wrapped_label_set_text(WrappedLabel *wl, const char *text)
61 GtkWidget *widget = GTK_WIDGET(wl);
63 if (!wl->layout)
65 wl->layout = gtk_widget_create_pango_layout(widget, text);
66 pango_layout_set_width(wl->layout, wl->width * PANGO_SCALE);
67 pango_layout_set_wrap(wl->layout, PANGO_WRAP_WORD);
68 pango_layout_set_alignment(wl->layout, PANGO_ALIGN_CENTER);
70 else
71 pango_layout_set_text(wl->layout, text, -1);
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);