r1996: Cope slightly better with invalid filenames in various places (reported by
[rox-filer.git] / ROX-Filer / src / wrapped.c
blob5b8aade2a05960bd0d635f30c4e96c39fcf32d32
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2002, 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 GType wrapped_label_get_type(void);
39 static void wrapped_label_size_request(GtkWidget *widget,
40 GtkRequisition *requisition);
41 static gint wrapped_label_expose(GtkWidget *widget, GdkEventExpose *event);
42 static void wrapped_label_style_set(GtkWidget *widget,
43 GtkStyle *previous_style);
46 /****************************************************************
47 * EXTERNAL INTERFACE *
48 ****************************************************************/
50 GtkWidget *wrapped_label_new(const char *text, gint width)
52 WrappedLabel *wl;
54 wl = g_object_new(wrapped_label_get_type(), NULL);
55 wl->width = width;
57 wrapped_label_set_text(wl, text);
59 return GTK_WIDGET(wl);
62 void wrapped_label_set_text(WrappedLabel *wl, const char *text)
64 GtkWidget *widget = GTK_WIDGET(wl);
66 if (!wl->layout)
68 wl->layout = gtk_widget_create_pango_layout(widget, text);
69 pango_layout_set_width(wl->layout, wl->width * PANGO_SCALE);
70 pango_layout_set_wrap(wl->layout, PANGO_WRAP_WORD);
71 pango_layout_set_alignment(wl->layout, PANGO_ALIGN_CENTER);
74 gtk_widget_queue_resize(widget);
77 /****************************************************************
78 * INTERNAL FUNCTIONS *
79 ****************************************************************/
81 static void wrapped_label_finialize(GObject *object)
83 WrappedLabel *wl = (WrappedLabel *) object;
85 if (wl->layout)
87 g_object_unref(G_OBJECT(wl->layout));
88 wl->layout = NULL;
91 G_OBJECT_CLASS(parent_class)->finalize(object);
94 static void wrapped_label_class_init(gpointer gclass, gpointer data)
96 GObjectClass *object = (GObjectClass *) gclass;
97 GtkWidgetClass *widget_class = (GtkWidgetClass *) gclass;
99 parent_class = g_type_class_peek_parent(gclass);
101 object->finalize = wrapped_label_finialize;
103 widget_class->size_request = wrapped_label_size_request;
104 widget_class->expose_event = wrapped_label_expose;
105 widget_class->style_set = wrapped_label_style_set;
108 static void wrapped_label_init(GTypeInstance *object, gpointer gclass)
110 WrappedLabel *wl = (WrappedLabel *) object;
111 GtkWidget *widget = (GtkWidget *) object;
113 GTK_WIDGET_SET_FLAGS(widget, GTK_NO_WINDOW);
115 wl->layout = NULL;
116 wl->width = -1;
119 static 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);
158 requisition->width = PANGO_PIXELS(logical_rect.width);
159 requisition->height = PANGO_PIXELS(logical_rect.height);
162 static gint wrapped_label_expose(GtkWidget *widget, GdkEventExpose *event)
164 WrappedLabel *wl = (WrappedLabel *) widget;
166 g_return_val_if_fail(event != NULL, TRUE);
167 g_return_val_if_fail(wl->layout != NULL, TRUE);
169 gtk_paint_layout(widget->style,
170 widget->window,
171 GTK_WIDGET_STATE(widget),
172 FALSE,
173 &event->area,
174 widget,
175 "label",
176 widget->allocation.x - wl->x_off,
177 widget->allocation.y - wl->y_off,
178 wl->layout);
180 return FALSE;
183 static void wrapped_label_style_set(GtkWidget *widget,
184 GtkStyle *previous_style)
186 WrappedLabel *wl = (WrappedLabel *) widget;
188 if (wl->layout)
190 const gchar *txt;
191 PangoLayout *old = wl->layout;
193 txt = pango_layout_get_text(wl->layout);
195 wl->layout = NULL;
196 wrapped_label_set_text(wl, txt);
198 g_object_unref(old);