]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderertextpixbuf.c
It's pixbuf_pos, not pixbufpos.
[~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 static void gtk_cell_renderer_text_pixbuf_set_property  (GObject                        *object,
40                                                          guint                           param_id,
41                                                          const GValue                   *value,
42                                                          GParamSpec                     *pspec);
43 static void gtk_cell_renderer_text_pixbuf_init       (GtkCellRendererTextPixbuf      *celltextpixbuf);
44 static void gtk_cell_renderer_text_pixbuf_class_init (GtkCellRendererTextPixbufClass *class);
45 static void gtk_cell_renderer_text_pixbuf_get_size   (GtkCellRenderer                *cell,
46                                                       GtkWidget                      *view,
47                                                       GdkRectangle                   *cell_area,
48                                                       gint                           *x_offset,
49                                                       gint                           *y_offset,
50                                                       gint                           *width,
51                                                       gint                           *height);
52 static void gtk_cell_renderer_text_pixbuf_render     (GtkCellRenderer                *cell,
53                                                       GdkWindow                      *window,
54                                                       GtkWidget                      *view,
55                                                       GdkRectangle                   *background_area,
56                                                       GdkRectangle                   *cell_area,
57                                                       GdkRectangle                   *expose_area,
58                                                       guint                           flags);
59
60
61 static GtkCellRendererTextClass *parent_class = NULL;
62
63
64 GtkType
65 gtk_cell_renderer_text_pixbuf_get_type (void)
66 {
67   static GtkType cell_text_pixbuf_type = 0;
68
69   if (!cell_text_pixbuf_type)
70     {
71       static const GTypeInfo cell_text_pixbuf_info =
72       {
73         sizeof (GtkCellRendererTextPixbufClass),
74         NULL,           /* base_init */
75         NULL,           /* base_finalize */
76         (GClassInitFunc) gtk_cell_renderer_text_pixbuf_class_init,
77         NULL,           /* class_finalize */
78         NULL,           /* class_data */
79         sizeof (GtkCellRendererTextPixbuf),
80         0,              /* n_preallocs */
81         (GInstanceInitFunc) gtk_cell_renderer_text_pixbuf_init,
82       };
83
84       cell_text_pixbuf_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, "GtkCellRendererTextPixbuf", &cell_text_pixbuf_info, 0);
85     }
86
87   return cell_text_pixbuf_type;
88 }
89
90 static void
91 gtk_cell_renderer_text_pixbuf_init (GtkCellRendererTextPixbuf *celltextpixbuf)
92 {
93   celltextpixbuf->pixbuf = GTK_CELL_RENDERER_PIXBUF (gtk_cell_renderer_pixbuf_new ());
94   celltextpixbuf->pixbuf_pos = GTK_POS_LEFT;
95 }
96
97 static void
98 gtk_cell_renderer_text_pixbuf_class_init (GtkCellRendererTextPixbufClass *class)
99 {
100   GObjectClass *object_class = G_OBJECT_CLASS (class);
101   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
102
103   parent_class = g_type_class_peek_parent (class);
104
105   object_class->get_property = gtk_cell_renderer_text_pixbuf_get_property;
106   object_class->set_property = gtk_cell_renderer_text_pixbuf_set_property;
107
108   cell_class->get_size = gtk_cell_renderer_text_pixbuf_get_size;
109   cell_class->render = gtk_cell_renderer_text_pixbuf_render;
110   
111   g_object_class_install_property (object_class,
112                                    PROP_PIXBUF_POS,
113                                    g_param_spec_int ("pixbuf_pos",
114                                                      _("Pixbuf location"),
115                                                      _("The relative location of the pixbuf to the text."),
116                                                      GTK_POS_LEFT,
117                                                      GTK_POS_BOTTOM,
118                                                      GTK_POS_LEFT,
119                                                      G_PARAM_READABLE |
120                                                      G_PARAM_WRITABLE));
121   
122   g_object_class_install_property (object_class,
123                                    PROP_PIXBUF,
124                                    g_param_spec_object ("pixbuf",
125                                                         _("Pixbuf Object"),
126                                                         _("The pixbuf to render."),
127                                                         GDK_TYPE_PIXBUF,
128                                                         G_PARAM_READABLE |
129                                                         G_PARAM_WRITABLE));
130   
131   g_object_class_install_property (object_class,
132                                    PROP_PIXBUF_XALIGN,
133                                    g_param_spec_float ("pixbuf_xalign",
134                                                        _("pixbuf xalign"),
135                                                        _("The x-align of the pixbuf."),
136                                                        0.0,
137                                                        1.0,
138                                                        0.0,
139                                                        G_PARAM_READABLE |
140                                                        G_PARAM_WRITABLE));
141   
142   g_object_class_install_property (object_class,
143                                    PROP_PIXBUF_YALIGN,
144                                    g_param_spec_float ("pixbuf_yalign",
145                                                        _("pixbuf yalign"),
146                                                        _("The y-align of the pixbuf."),
147                                                        0.0,
148                                                        1.0,
149                                                        0.5,
150                                                        G_PARAM_READABLE |
151                                                        G_PARAM_WRITABLE));
152   
153   g_object_class_install_property (object_class,
154                                    PROP_PIXBUF_XPAD,
155                                    g_param_spec_uint ("pixbuf_xpad",
156                                                       _("pixbuf xpad"),
157                                                       _("The xpad of the pixbuf."),
158                                                       0,
159                                                       100,
160                                                       2,
161                                                       G_PARAM_READABLE |
162                                                       G_PARAM_WRITABLE));
163   
164   g_object_class_install_property (object_class,
165                                    PROP_PIXBUF_YPAD,
166                                    g_param_spec_uint ("pixbuf_ypad",
167                                                       _("pixbuf ypad"),
168                                                       _("The ypad of the pixbuf."),
169                                                       0,
170                                                       100,
171                                                       2,
172                                                       G_PARAM_READABLE |
173                                                       G_PARAM_WRITABLE));
174 }
175
176 static void
177 gtk_cell_renderer_text_pixbuf_get_property (GObject     *object,
178                                             guint        param_id,
179                                             GValue      *value,
180                                             GParamSpec  *pspec)
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 {
226   GtkCellRendererTextPixbuf *celltextpixbuf = GTK_CELL_RENDERER_TEXT_PIXBUF (object);
227   
228   switch (param_id)
229     {
230     case PROP_PIXBUF:
231       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
232                              "pixbuf",
233                              value);
234       g_object_notify (G_OBJECT(object), "pixbuf");
235       break;
236     case PROP_PIXBUF_POS:
237       celltextpixbuf->pixbuf_pos = g_value_get_int (value);
238       g_object_notify (G_OBJECT(object), "pixbuf_pos");
239       break;
240     case PROP_PIXBUF_XALIGN:
241       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
242                              "xalign",
243                              value);
244       g_object_notify (G_OBJECT(object), "pixbuf_xalign");
245       break;
246     case PROP_PIXBUF_YALIGN:
247       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
248                              "yalign",
249                              value);
250       g_object_notify (G_OBJECT(object), "pixbuf_yalign");
251       break;
252     case PROP_PIXBUF_XPAD:
253       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
254                              "xpad",
255                              value);
256       g_object_notify (G_OBJECT(object), "pixbuf_xpad");
257       break;
258     case PROP_PIXBUF_YPAD:
259       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
260                              "ypad",
261                              value);
262       g_object_notify (G_OBJECT(object), "pixbuf_ypad");
263       break;
264     default:
265       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
266       break;
267     }
268 }
269
270 /**
271  * gtk_cell_renderer_text_pixbuf_new:
272  * 
273  * Creates a new #GtkCellRendererTextPixbuf. Adjust rendering
274  * parameters using object properties. Object properties can be set
275  * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you
276  * can bind a property to a value in a #GtkTreeModel. For example, you
277  * can bind the "text" property on the cell renderer to a string value
278  * in the model, thus rendering a different string in each row of the
279  * #GtkTreeView
280  * 
281  * Return value: the new cell renderer
282  **/
283 GtkCellRenderer *
284 gtk_cell_renderer_text_pixbuf_new (void)
285 {
286   return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_text_pixbuf_get_type ()));
287 }
288
289 typedef void (* CellSizeFunc) (GtkCellRenderer    *cell,
290                                GtkWidget          *widget,
291                                GdkRectangle       *rectangle,
292                                gint               *x_offset,
293                                gint               *y_offset,
294                                gint               *width,
295                                gint               *height);
296 typedef void (* CellRenderFunc) (GtkCellRenderer *cell,
297                                  GdkWindow       *window,
298                                  GtkWidget       *widget,
299                                  GdkRectangle    *background_area,
300                                  GdkRectangle    *cell_area,
301                                  GdkRectangle    *expose_area,
302                                  guint            flags);
303
304 static void
305 gtk_cell_renderer_text_pixbuf_get_size (GtkCellRenderer *cell,
306                                         GtkWidget       *widget,
307                                         GdkRectangle    *cell_area,
308                                         gint            *x_offset,
309                                         gint            *y_offset,
310                                         gint            *width,
311                                         gint            *height)
312 {
313   GtkCellRendererTextPixbuf *celltextpixbuf = (GtkCellRendererTextPixbuf *)cell;
314   gint pixbuf_width;
315   gint pixbuf_height;
316   gint text_width;
317   gint text_height;
318   gint calc_width;
319   gint calc_height;
320   
321   (* GTK_CELL_RENDERER_CLASS (parent_class)->get_size) (cell, widget, NULL, NULL, NULL, &text_width, &text_height);
322   (* GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size) (GTK_CELL_RENDERER (celltextpixbuf->pixbuf),
323                                                                                        widget,
324                                                                                        NULL, NULL, NULL,
325                                                                                        &pixbuf_width,
326                                                                                        &pixbuf_height);
327   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
328       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
329     {
330       calc_width = pixbuf_width + text_width;
331       calc_height = MAX (pixbuf_height, text_height);
332     }
333   else
334     {
335       calc_width = MAX (pixbuf_width, text_width);
336       calc_height = pixbuf_height + text_height;
337     }
338
339   if (width)
340     *width = calc_width;
341   if (height)
342     *height = calc_height;
343
344   if (cell_area)
345     {
346       if (x_offset)
347         {
348           *x_offset = cell->xalign * (cell_area->width - calc_width - (2 * cell->xpad));
349           *x_offset = MAX (*x_offset, 0) + cell->xpad;
350         }
351       if (y_offset)
352         {
353           *y_offset = cell->yalign * (cell_area->height - calc_height - (2 * cell->ypad));
354           *y_offset = MAX (*y_offset, 0) + cell->ypad;
355         }
356     }
357 }
358
359 static void
360 gtk_cell_renderer_text_pixbuf_render (GtkCellRenderer *cell,
361                                       GdkWindow       *window,
362                                       GtkWidget       *widget,
363                                       GdkRectangle    *background_area,
364                                       GdkRectangle    *cell_area,
365                                       GdkRectangle    *expose_area,
366                                       guint            flags)
367
368 {
369   GtkCellRendererTextPixbuf *celltextpixbuf = (GtkCellRendererTextPixbuf *) cell;
370   CellSizeFunc size_func1, size_func2;
371   CellRenderFunc render_func1, render_func2;
372   GtkCellRenderer *cell1, *cell2;
373   gint tmp_width;
374   gint tmp_height;
375   GdkRectangle real_cell_area;
376
377   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
378       celltextpixbuf->pixbuf_pos == GTK_POS_TOP)
379     {
380       size_func1 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size;
381       render_func1 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->render;
382       cell1 = GTK_CELL_RENDERER (celltextpixbuf->pixbuf);
383
384       size_func2 = GTK_CELL_RENDERER_CLASS (parent_class)->get_size;
385       render_func2 = GTK_CELL_RENDERER_CLASS (parent_class)->render;
386       cell2 = cell;
387     }
388   else
389     {
390       size_func1 = GTK_CELL_RENDERER_CLASS (parent_class)->get_size;
391       render_func1 = GTK_CELL_RENDERER_CLASS (parent_class)->render;
392       cell1 = cell;
393
394       size_func2 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size;
395       render_func2 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->render;
396       cell2 = GTK_CELL_RENDERER (celltextpixbuf->pixbuf);
397     }
398
399   (size_func1) (cell1, widget, NULL, NULL, NULL, &tmp_width, &tmp_height);
400
401   real_cell_area.x = cell_area->x;
402   real_cell_area.y = cell_area->y;
403
404   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
405       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
406     {
407       real_cell_area.width = MIN (tmp_width, cell_area->width);
408       real_cell_area.height = cell_area->height;
409     }
410   else
411     {
412       real_cell_area.height = MIN (tmp_height, cell_area->height);
413       real_cell_area.width = cell_area->width;
414     }
415
416   (render_func1) (cell1,
417                   window,
418                   widget,
419                   background_area,
420                   &real_cell_area,
421                   expose_area,
422                   flags);
423
424   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
425       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
426     {
427       real_cell_area.x = real_cell_area.x + real_cell_area.width;
428       real_cell_area.width = cell_area->width - real_cell_area.width;
429     }
430   else
431     {
432       real_cell_area.y = real_cell_area.y + real_cell_area.height;
433       real_cell_area.height = cell_area->height - real_cell_area.height;
434     }
435
436   (render_func2 ) (cell2,
437                    window,
438                    widget,
439                    background_area,
440                    &real_cell_area,
441                    expose_area,
442                    flags);
443 }