]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrendererpixbuf.c
Adapt to GtkTreeSelection changes
[~andy/gtk] / gtk / gtkcellrendererpixbuf.c
1 /* gtkcellrendererpixbuf.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 "gtkcellrendererpixbuf.h"
22 #include "gtkintl.h"
23
24 static void gtk_cell_renderer_pixbuf_get_property  (GObject                    *object,
25                                                     guint                       param_id,
26                                                     GValue                     *value,
27                                                     GParamSpec                 *pspec,
28                                                     const gchar                *trailer);
29 static void gtk_cell_renderer_pixbuf_set_property  (GObject                    *object,
30                                                     guint                       param_id,
31                                                     const GValue               *value,
32                                                     GParamSpec                 *pspec,
33                                                     const gchar                *trailer);
34 static void gtk_cell_renderer_pixbuf_init       (GtkCellRendererPixbuf      *celltext);
35 static void gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class);
36 static void gtk_cell_renderer_pixbuf_get_size   (GtkCellRenderer            *cell,
37                                                  GtkWidget                  *widget,
38                                                  gint                       *width,
39                                                  gint                       *height);
40 static void gtk_cell_renderer_pixbuf_render     (GtkCellRenderer            *cell,
41                                                  GdkWindow                  *window,
42                                                  GtkWidget                  *widget,
43                                                  GdkRectangle               *background_area,
44                                                  GdkRectangle               *cell_area,
45                                                  GdkRectangle               *expose_area,
46                                                  guint                       flags);
47
48
49 enum {
50         PROP_ZERO,
51         PROP_PIXBUF
52 };
53
54
55 GtkType
56 gtk_cell_renderer_pixbuf_get_type (void)
57 {
58         static GtkType cell_pixbuf_type = 0;
59
60         if (!cell_pixbuf_type)
61         {
62                 static const GTypeInfo cell_pixbuf_info =
63                 {
64                         sizeof (GtkCellRendererPixbufClass),
65                         NULL,           /* base_init */
66                         NULL,           /* base_finalize */
67                         (GClassInitFunc) gtk_cell_renderer_pixbuf_class_init,
68                         NULL,           /* class_finalize */
69                         NULL,           /* class_data */
70                         sizeof (GtkCellRendererPixbuf),
71                         0,              /* n_preallocs */
72                         (GInstanceInitFunc) gtk_cell_renderer_pixbuf_init,
73                 };
74
75                 cell_pixbuf_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkCellRendererPixbuf", &cell_pixbuf_info, 0);
76         }
77
78         return cell_pixbuf_type;
79 }
80
81 static void
82 gtk_cell_renderer_pixbuf_init (GtkCellRendererPixbuf *cellpixbuf)
83 {
84 }
85
86 static void
87 gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
88 {
89         GObjectClass *object_class = G_OBJECT_CLASS (class);
90         GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
91
92         object_class->get_property = gtk_cell_renderer_pixbuf_get_property;
93         object_class->set_property = gtk_cell_renderer_pixbuf_set_property;
94
95         cell_class->get_size = gtk_cell_renderer_pixbuf_get_size;
96         cell_class->render = gtk_cell_renderer_pixbuf_render;
97
98         g_object_class_install_property (object_class,
99                                          PROP_PIXBUF,
100                                          g_param_spec_object ("pixbuf",
101                                                               _("Pixbuf Object"),
102                                                               _("The pixbuf to render."),
103                                                               GDK_TYPE_PIXBUF,
104                                                               G_PARAM_READABLE |
105                                                               G_PARAM_WRITABLE));
106 }
107
108 static void
109 gtk_cell_renderer_pixbuf_get_property (GObject        *object,
110                                        guint           param_id,
111                                        GValue         *value,
112                                        GParamSpec     *pspec,
113                                        const gchar    *trailer)
114 {
115   GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
116   
117   switch (param_id)
118     {
119     case PROP_PIXBUF:
120       g_value_set_object (value, G_OBJECT (cellpixbuf->pixbuf));
121       break;
122     default:
123       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
124       break;
125     }
126 }
127
128
129 static void
130 gtk_cell_renderer_pixbuf_set_property (GObject      *object,
131                                        guint         param_id,
132                                        const GValue *value,
133                                        GParamSpec   *pspec,
134                                        const gchar  *trailer)
135 {
136   GdkPixbuf *pixbuf;
137   GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
138   
139   switch (param_id)
140     {
141     case PROP_PIXBUF:
142       pixbuf = GDK_PIXBUF (g_value_get_object (value));
143       g_object_ref (G_OBJECT (pixbuf));
144       if (cellpixbuf->pixbuf)
145         g_object_unref (G_OBJECT (cellpixbuf->pixbuf));
146       cellpixbuf->pixbuf = pixbuf;
147       break;
148     default:
149       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
150       break;
151     }
152 }
153
154 GtkCellRenderer *
155 gtk_cell_renderer_pixbuf_new (void)
156 {
157         return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_pixbuf_get_type ()));
158 }
159
160 static void
161 gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
162                                    GtkWidget       *widget,
163                                    gint            *width,
164                                    gint            *height)
165 {
166         GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
167
168         if (width)
169                 *width = (gint) GTK_CELL_RENDERER (cellpixbuf)->xpad * 2 +
170                         (cellpixbuf->pixbuf ? gdk_pixbuf_get_width (cellpixbuf->pixbuf) : 0);
171
172         if (height)
173                 *height = (gint) GTK_CELL_RENDERER (cellpixbuf)->ypad * 2 +
174                         (cellpixbuf->pixbuf ? gdk_pixbuf_get_height (cellpixbuf->pixbuf) : 0);
175 }
176
177 static void
178 gtk_cell_renderer_pixbuf_render (GtkCellRenderer    *cell,
179                                  GdkWindow          *window,
180                                  GtkWidget          *widget,
181                                  GdkRectangle       *background_area,
182                                  GdkRectangle       *cell_area,
183                                  GdkRectangle       *expose_area,
184                                  guint               flags)
185
186 {
187         GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
188         GdkPixbuf *pixbuf;
189         guchar *pixels;
190         gint rowstride;
191         gint real_xoffset;
192         gint real_yoffset;
193         GdkGC *bg_gc = NULL;
194
195         pixbuf = cellpixbuf->pixbuf;
196
197         if (!pixbuf)
198                 return;
199
200         if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
201                 bg_gc = widget->style->bg_gc [GTK_STATE_SELECTED];
202         else
203                 bg_gc = widget->style->base_gc [GTK_STATE_NORMAL];
204
205         gdk_gc_set_clip_rectangle (bg_gc, cell_area);
206
207         rowstride = gdk_pixbuf_get_rowstride (pixbuf);
208         pixels = gdk_pixbuf_get_pixels (pixbuf);
209
210         real_xoffset = GTK_CELL_RENDERER (cellpixbuf)->xalign * (cell_area->width - gdk_pixbuf_get_width (pixbuf) - (2 * GTK_CELL_RENDERER (cellpixbuf)->xpad));
211         real_xoffset = MAX (real_xoffset, 0) + GTK_CELL_RENDERER (cellpixbuf)->xpad;
212         real_yoffset = GTK_CELL_RENDERER (cellpixbuf)->yalign * (cell_area->height - gdk_pixbuf_get_height (pixbuf) - (2 * GTK_CELL_RENDERER (cellpixbuf)->ypad));
213         real_yoffset = MAX (real_yoffset, 0) + GTK_CELL_RENDERER (cellpixbuf)->ypad;
214
215         if (gdk_pixbuf_get_has_alpha (pixbuf))
216                 gdk_draw_rgb_32_image (window,
217                                        bg_gc,
218                                        cell_area->x + real_xoffset,
219                                        cell_area->y + real_yoffset,
220                                        gdk_pixbuf_get_width (pixbuf),
221                                        gdk_pixbuf_get_height (pixbuf),
222                                        GDK_RGB_DITHER_NORMAL,
223                                        pixels,
224                                        rowstride);
225         else
226                 gdk_draw_rgb_image (window,
227                                     bg_gc,
228                                     cell_area->x + real_xoffset,
229                                     cell_area->y + real_yoffset,
230                                     gdk_pixbuf_get_width (pixbuf),
231                                     gdk_pixbuf_get_height (pixbuf),
232                                     GDK_RGB_DITHER_NORMAL,
233                                     pixels,
234                                     rowstride);
235
236         gdk_gc_set_clip_rectangle (bg_gc, NULL);
237 }