]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderertextpixbuf.c
712754fcfd5b83a12315e550253604bead5206d1
[~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
221 static void
222 gtk_cell_renderer_text_pixbuf_set_property (GObject      *object,
223                                             guint         param_id,
224                                             const GValue *value,
225                                             GParamSpec   *pspec,
226                                             const gchar  *trailer)
227 {
228   GtkCellRendererTextPixbuf *celltextpixbuf = GTK_CELL_RENDERER_TEXT_PIXBUF (object);
229   
230   switch (param_id)
231     {
232     case PROP_PIXBUF:
233       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
234                              "pixbuf",
235                              value);
236       break;
237     case PROP_PIXBUF_POS:
238       celltextpixbuf->pixbuf_pos = g_value_get_int (value);
239       break;
240     case PROP_PIXBUF_XALIGN:
241       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
242                              "xalign",
243                              value);
244       break;
245     case PROP_PIXBUF_YALIGN:
246       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
247                              "yalign",
248                              value);
249       break;
250     case PROP_PIXBUF_XPAD:
251       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
252                              "xpad",
253                              value);
254       break;
255     case PROP_PIXBUF_YPAD:
256       g_object_set_property (G_OBJECT (celltextpixbuf->pixbuf),
257                              "ypad",
258                              value);
259       break;
260     default:
261       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
262       break;
263     }
264 }
265
266 GtkCellRenderer *
267 gtk_cell_renderer_text_pixbuf_new (void)
268 {
269   return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_text_pixbuf_get_type ()));
270 }
271
272 typedef void (* CellSizeFunc) (GtkCellRenderer    *cell,
273                                GtkWidget          *widget,
274                                gint               *width,
275                                gint               *height);
276 typedef void (* CellRenderFunc) (GtkCellRenderer *cell,
277                                  GdkWindow       *window,
278                                  GtkWidget       *widget,
279                                  GdkRectangle    *background_area,
280                                  GdkRectangle    *cell_area,
281                                  GdkRectangle    *expose_area,
282                                  guint            flags);
283
284 static void
285 gtk_cell_renderer_text_pixbuf_get_size (GtkCellRenderer *cell,
286                                         GtkWidget       *widget,
287                                         gint            *width,
288                                         gint            *height)
289 {
290   GtkCellRendererTextPixbuf *celltextpixbuf = (GtkCellRendererTextPixbuf *)cell;
291   gint pixbuf_width;
292   gint pixbuf_height;
293   gint text_width;
294   gint text_height;
295
296   (* GTK_CELL_RENDERER_CLASS (parent_class)->get_size) (cell, widget, &text_width, &text_height);
297   (* GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size) (GTK_CELL_RENDERER (celltextpixbuf->pixbuf),
298                                                                                        widget,
299                                                                                        &pixbuf_width,
300                                                                                        &pixbuf_height);
301   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
302       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
303     {
304       *width = pixbuf_width + text_width;
305       *height = MAX (pixbuf_height, text_height);
306     }
307   else
308     {
309       *width = MAX (pixbuf_width, text_width);
310       *height = pixbuf_height + text_height;
311     }
312 }
313
314 static void
315 gtk_cell_renderer_text_pixbuf_render (GtkCellRenderer *cell,
316                                       GdkWindow       *window,
317                                       GtkWidget       *widget,
318                                       GdkRectangle    *background_area,
319                                       GdkRectangle    *cell_area,
320                                       GdkRectangle    *expose_area,
321                                       guint            flags)
322
323 {
324   GtkCellRendererTextPixbuf *celltextpixbuf = (GtkCellRendererTextPixbuf *) cell;
325   CellSizeFunc size_func1, size_func2;
326   CellRenderFunc render_func1, render_func2;
327   GtkCellRenderer *cell1, *cell2;
328   gint tmp_width;
329   gint tmp_height;
330   GdkRectangle real_cell_area;
331
332   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
333       celltextpixbuf->pixbuf_pos == GTK_POS_TOP)
334     {
335       size_func1 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size;
336       render_func1 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->render;
337       cell1 = GTK_CELL_RENDERER (celltextpixbuf->pixbuf);
338
339       size_func2 = GTK_CELL_RENDERER_CLASS (parent_class)->get_size;
340       render_func2 = GTK_CELL_RENDERER_CLASS (parent_class)->render;
341       cell2 = cell;
342     }
343   else
344     {
345       size_func1 = GTK_CELL_RENDERER_CLASS (parent_class)->get_size;
346       render_func1 = GTK_CELL_RENDERER_CLASS (parent_class)->render;
347       cell1 = cell;
348
349       size_func2 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->get_size;
350       render_func2 = GTK_CELL_RENDERER_CLASS (G_OBJECT_GET_CLASS (celltextpixbuf->pixbuf))->render;
351       cell2 = GTK_CELL_RENDERER (celltextpixbuf->pixbuf);
352     }
353
354   (size_func1) (cell1, widget, &tmp_width, &tmp_height);
355
356   real_cell_area.x = cell_area->x;
357   real_cell_area.y = cell_area->y;
358
359   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
360       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
361     {
362       real_cell_area.width = MIN (tmp_width, cell_area->width);
363       real_cell_area.height = cell_area->height;
364     }
365   else
366     {
367       real_cell_area.height = MIN (tmp_height, cell_area->height);
368       real_cell_area.width = cell_area->width;
369     }
370
371   (render_func1) (cell1,
372                   window,
373                   widget,
374                   background_area,
375                   &real_cell_area,
376                   expose_area,
377                   flags);
378
379   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
380       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
381     {
382       real_cell_area.x = real_cell_area.x + real_cell_area.width;
383       real_cell_area.width = cell_area->width - real_cell_area.width;
384     }
385   else
386     {
387       real_cell_area.y = real_cell_area.y + real_cell_area.height;
388       real_cell_area.height = cell_area->height - real_cell_area.height;
389     }
390
391   (render_func2 ) (cell2,
392                    window,
393                    widget,
394                    background_area,
395                    &real_cell_area,
396                    expose_area,
397                    flags);
398 }