]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderertextpixbuf.c
CVS is doing its broken pipe thing, this is more of the previous commit
[~andy/gtk] / gtk / gtkcellrenderertextpixbuf.c
1 /* gtkcellrenderertextpixbuf.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <stdlib.h>
21 #include "gtkcellrenderertextpixbuf.h"
22 #include "gtkintl.h"
23
24 enum {
25   PROP_ZERO,
26   PROP_PIXBUF_POS,
27   PROP_PIXBUF,
28   PROP_PIXBUF_XALIGN,
29   PROP_PIXBUF_YALIGN,
30   PROP_PIXBUF_XPAD,
31   PROP_PIXBUF_YPAD
32 };
33
34
35 static void gtk_cell_renderer_text_pixbuf_get_property  (GObject                        *object,
36                                                          guint                           param_id,
37                                                          GValue                         *value,
38                                                          GParamSpec                     *pspec,
39                                                          const gchar                    *trailer);
40 static void gtk_cell_renderer_text_pixbuf_set_property  (GObject                        *object,
41                                                          guint                           param_id,
42                                                          const GValue                   *value,
43                                                          GParamSpec                     *pspec,
44                                                          const gchar                    *trailer);
45 static void gtk_cell_renderer_text_pixbuf_init       (GtkCellRendererTextPixbuf      *celltextpixbuf);
46 static void gtk_cell_renderer_text_pixbuf_class_init (GtkCellRendererTextPixbufClass *class);
47 static void gtk_cell_renderer_text_pixbuf_get_size   (GtkCellRenderer                *cell,
48                                                       GtkWidget                      *view,
49                                                       gint                           *width,
50                                                       gint                           *height);
51 static void gtk_cell_renderer_text_pixbuf_render     (GtkCellRenderer                *cell,
52                                                       GdkWindow                      *window,
53                                                       GtkWidget                      *view,
54                                                       GdkRectangle                   *background_area,
55                                                       GdkRectangle                   *cell_area,
56                                                       GdkRectangle                   *expose_area,
57                                                       guint                           flags);
58
59
60 static GtkCellRendererTextClass *parent_class = NULL;
61
62
63 GtkType
64 gtk_cell_renderer_text_pixbuf_get_type (void)
65 {
66   static GtkType cell_text_pixbuf_type = 0;
67
68   if (!cell_text_pixbuf_type)
69     {
70       static const GTypeInfo cell_text_pixbuf_info =
71       {
72         sizeof (GtkCellRendererTextPixbufClass),
73         NULL,           /* base_init */
74         NULL,           /* base_finalize */
75         (GClassInitFunc) gtk_cell_renderer_text_pixbuf_class_init,
76         NULL,           /* class_finalize */
77         NULL,           /* class_data */
78         sizeof (GtkCellRendererTextPixbuf),
79         0,              /* n_preallocs */
80         (GInstanceInitFunc) gtk_cell_renderer_text_pixbuf_init,
81       };
82
83       cell_text_pixbuf_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, "GtkCellRendererTextPixbuf", &cell_text_pixbuf_info, 0);
84     }
85
86   return cell_text_pixbuf_type;
87 }
88
89 static void
90 gtk_cell_renderer_text_pixbuf_init (GtkCellRendererTextPixbuf *celltextpixbuf)
91 {
92   celltextpixbuf->pixbuf = GTK_CELL_RENDERER_PIXBUF (gtk_cell_renderer_pixbuf_new ());
93   celltextpixbuf->pixbuf_pos = GTK_POS_LEFT;
94 }
95
96 static void
97 gtk_cell_renderer_text_pixbuf_class_init (GtkCellRendererTextPixbufClass *class)
98 {
99   GObjectClass *object_class = G_OBJECT_CLASS (class);
100   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
101
102   parent_class = g_type_class_peek_parent (class);
103
104   object_class->get_property = gtk_cell_renderer_text_pixbuf_get_property;
105   object_class->set_property = gtk_cell_renderer_text_pixbuf_set_property;
106
107   cell_class->get_size = gtk_cell_renderer_text_pixbuf_get_size;
108   cell_class->render = gtk_cell_renderer_text_pixbuf_render;
109   
110   g_object_class_install_property (object_class,
111                                    PROP_PIXBUF_POS,
112                                    g_param_spec_int ("pixbufpos",
113                                                      _("Pixbuf location"),
114                                                      _("The relative location of the pixbuf to the text."),
115                                                      GTK_POS_LEFT,
116                                                      GTK_POS_BOTTOM,
117                                                      GTK_POS_LEFT,
118                                                      G_PARAM_READABLE |
119                                                      G_PARAM_WRITABLE));
120   
121   g_object_class_install_property (object_class,
122                                    PROP_PIXBUF,
123                                    g_param_spec_object ("pixbuf",
124                                                         _("Pixbuf Object"),
125                                                         _("The pixbuf to render."),
126                                                         GDK_TYPE_PIXBUF,
127                                                         G_PARAM_READABLE |
128                                                         G_PARAM_WRITABLE));
129   
130   g_object_class_install_property (object_class,
131                                    PROP_PIXBUF_XALIGN,
132                                    g_param_spec_float ("pixbuf_xalign",
133                                                        _("pixbuf xalign"),
134                                                        _("The x-align of the pixbuf."),
135                                                        0.0,
136                                                        1.0,
137                                                        0.0,
138                                                        G_PARAM_READABLE |
139                                                        G_PARAM_WRITABLE));
140   
141   g_object_class_install_property (object_class,
142                                    PROP_PIXBUF_YALIGN,
143                                    g_param_spec_float ("pixbuf_yalign",
144                                                        _("pixbuf yalign"),
145                                                        _("The y-align of the pixbuf."),
146                                                        0.0,
147                                                        1.0,
148                                                        0.5,
149                                                        G_PARAM_READABLE |
150                                                        G_PARAM_WRITABLE));
151   
152   g_object_class_install_property (object_class,
153                                    PROP_PIXBUF_XPAD,
154                                    g_param_spec_uint ("pixbuf_xpad",
155                                                       _("pixbuf xpad"),
156                                                       _("The xpad of the pixbuf."),
157                                                       0,
158                                                       100,
159                                                       2,
160                                                       G_PARAM_READABLE |
161                                                       G_PARAM_WRITABLE));
162   
163   g_object_class_install_property (object_class,
164                                    PROP_PIXBUF_YPAD,
165                                    g_param_spec_uint ("pixbuf_ypad",
166                                                       _("pixbuf ypad"),
167                                                       _("The ypad of the pixbuf."),
168                                                       0,
169                                                       100,
170                                                       2,
171                                                       G_PARAM_READABLE |
172                                                       G_PARAM_WRITABLE));
173 }
174
175 static void
176 gtk_cell_renderer_text_pixbuf_get_property (GObject     *object,
177                                             guint        param_id,
178                                             GValue      *value,
179                                             GParamSpec  *pspec,
180                                             const gchar *trailer)
181 {
182   GtkCellRendererTextPixbuf *celltextpixbuf = GTK_CELL_RENDERER_TEXT_PIXBUF (object);
183   
184   switch (param_id)
185     {
186     case PROP_PIXBUF_POS:
187       g_value_set_int (value, celltextpixbuf->pixbuf_pos);
188       break;
189     case PROP_PIXBUF:
190       g_object_get_property (G_OBJECT (celltextpixbuf->pixbuf),
191                              "pixbuf",
192                              value);
193       break;
194     case PROP_PIXBUF_XALIGN:
195       g_object_get_property (G_OBJECT (celltextpixbuf->pixbuf),
196                              "xalign",
197                              value);
198       break;
199     case PROP_PIXBUF_YALIGN:
200       g_object_get_property (G_OBJECT (celltextpixbuf->pixbuf),
201                              "yalign",
202                              value);
203       break;
204     case PROP_PIXBUF_XPAD:
205       g_object_get_property (G_OBJECT (celltextpixbuf->pixbuf),
206                              "xpad",
207                              value);
208       break;
209     case PROP_PIXBUF_YPAD:
210       g_object_get_property (G_OBJECT (celltextpixbuf->pixbuf),
211                              "ypad",
212                              value);
213       break;
214     default:
215       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
216       break;
217     }
218 }
219
220 static void
221 gtk_cell_renderer_text_pixbuf_set_property (GObject      *object,
222                                             guint         param_id,
223                                             const GValue *value,
224                                             GParamSpec   *pspec,
225                                             const gchar  *trailer)
226 {
227   GtkCellRendererTextPixbuf *celltextpixbuf = GTK_CELL_RENDERER_TEXT_PIXBUF (object);
228   
229   switch (param_id)
230     {
231     case PROP_PIXBUF:
232       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
233                              "pixbuf",
234                              value);
235       break;
236     case PROP_PIXBUF_POS:
237       celltextpixbuf->pixbuf_pos = g_value_get_int (value);
238       break;
239     case PROP_PIXBUF_XALIGN:
240       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
241                              "xalign",
242                              value);
243       break;
244     case PROP_PIXBUF_YALIGN:
245       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
246                              "yalign",
247                              value);
248       break;
249     case PROP_PIXBUF_XPAD:
250       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
251                              "xpad",
252                              value);
253       break;
254     case PROP_PIXBUF_YPAD:
255       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
256                              "ypad",
257                              value);
258       break;
259     default:
260       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
261       break;
262     }
263 }
264
265 /**
266  * gtk_cell_renderer_text_pixbuf_new:
267  * 
268  * Creates a new #GtkCellRendererTextPixbuf. Adjust rendering
269  * parameters using object properties. Object properties can be set
270  * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you
271  * can bind a property to a value in a #GtkTreeModel. For example, you
272  * can bind the "text" property on the cell renderer to a string value
273  * in the model, thus rendering a different string in each row of the
274  * #GtkTreeView
275  * 
276  * Return value: the new cell renderer
277  **/
278 GtkCellRenderer *
279 gtk_cell_renderer_text_pixbuf_new (void)
280 {
281   return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_text_pixbuf_get_type ()));
282 }
283
284 typedef void (* CellSizeFunc) (GtkCellRenderer    *cell,
285                                GtkWidget          *widget,
286                                gint               *width,
287                                gint               *height);
288 typedef void (* CellRenderFunc) (GtkCellRenderer *cell,
289                                  GdkWindow       *window,
290                                  GtkWidget       *widget,
291                                  GdkRectangle    *background_area,
292                                  GdkRectangle    *cell_area,
293                                  GdkRectangle    *expose_area,
294                                  guint            flags);
295
296 static void
297 gtk_cell_renderer_text_pixbuf_get_size (GtkCellRenderer *cell,
298                                         GtkWidget       *widget,
299                                         gint            *width,
300                                         gint            *height)
301 {
302   GtkCellRendererTextPixbuf *celltextpixbuf = (GtkCellRendererTextPixbuf *)cell;
303   gint pixbuf_width;
304   gint pixbuf_height;
305   gint text_width;
306   gint text_height;
307
308   (* GTK_CELL_RENDERER_CLASS (parent_class)->get_size) (cell, widget, &text_width, &text_height);
309   (* GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size) (GTK_CELL_RENDERER (celltextpixbuf->pixbuf),
310                                                                                        widget,
311                                                                                        &pixbuf_width,
312                                                                                        &pixbuf_height);
313   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
314       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
315     {
316       if (width)
317         *width = pixbuf_width + text_width;
318       if (height)
319         *height = MAX (pixbuf_height, text_height);
320     }
321   else
322     {
323       if (width)
324         *width = MAX (pixbuf_width, text_width);
325       if (height)
326         *height = pixbuf_height + text_height;
327     }
328 }
329
330 static void
331 gtk_cell_renderer_text_pixbuf_render (GtkCellRenderer *cell,
332                                       GdkWindow       *window,
333                                       GtkWidget       *widget,
334                                       GdkRectangle    *background_area,
335                                       GdkRectangle    *cell_area,
336                                       GdkRectangle    *expose_area,
337                                       guint            flags)
338
339 {
340   GtkCellRendererTextPixbuf *celltextpixbuf = (GtkCellRendererTextPixbuf *) cell;
341   CellSizeFunc size_func1, size_func2;
342   CellRenderFunc render_func1, render_func2;
343   GtkCellRenderer *cell1, *cell2;
344   gint tmp_width;
345   gint tmp_height;
346   GdkRectangle real_cell_area;
347
348   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
349       celltextpixbuf->pixbuf_pos == GTK_POS_TOP)
350     {
351       size_func1 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size;
352       render_func1 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->render;
353       cell1 = GTK_CELL_RENDERER (celltextpixbuf->pixbuf);
354
355       size_func2 = GTK_CELL_RENDERER_CLASS (parent_class)->get_size;
356       render_func2 = GTK_CELL_RENDERER_CLASS (parent_class)->render;
357       cell2 = cell;
358     }
359   else
360     {
361       size_func1 = GTK_CELL_RENDERER_CLASS (parent_class)->get_size;
362       render_func1 = GTK_CELL_RENDERER_CLASS (parent_class)->render;
363       cell1 = cell;
364
365       size_func2 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size;
366       render_func2 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->render;
367       cell2 = GTK_CELL_RENDERER (celltextpixbuf->pixbuf);
368     }
369
370   (size_func1) (cell1, widget, &tmp_width, &tmp_height);
371
372   real_cell_area.x = cell_area->x;
373   real_cell_area.y = cell_area->y;
374
375   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
376       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
377     {
378       real_cell_area.width = MIN (tmp_width, cell_area->width);
379       real_cell_area.height = cell_area->height;
380     }
381   else
382     {
383       real_cell_area.height = MIN (tmp_height, cell_area->height);
384       real_cell_area.width = cell_area->width;
385     }
386
387   (render_func1) (cell1,
388                   window,
389                   widget,
390                   background_area,
391                   &real_cell_area,
392                   expose_area,
393                   flags);
394
395   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
396       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
397     {
398       real_cell_area.x = real_cell_area.x + real_cell_area.width;
399       real_cell_area.width = cell_area->width - real_cell_area.width;
400     }
401   else
402     {
403       real_cell_area.y = real_cell_area.y + real_cell_area.height;
404       real_cell_area.height = cell_area->height - real_cell_area.height;
405     }
406
407   (render_func2 ) (cell2,
408                    window,
409                    widget,
410                    background_area,
411                    &real_cell_area,
412                    expose_area,
413                    flags);
414 }