1.12.42
[gnumeric.git] / src / widgets / gnm-cell-renderer-toggle.c
blobfe527987a3992911f66d9a9a010fc5aa84ee4c2d
1 /* gnm-cell-renderer-toggle.c
3 * Author:
4 * Andreas J. Guelzow <aguelzow@taliesin.ca>
6 * Copyright (C) 2002 Andreas J. Guelzow <aguelzow@taliesin.ca>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <https://www.gnu.org/licenses/>.
22 #include <gnumeric-config.h>
23 #include <widgets/gnm-cell-renderer-toggle.h>
24 #include <gsf/gsf-impl-utils.h>
25 #include <gnm-i18n.h>
27 static void gnumeric_cell_renderer_toggle_get_property (GObject *object,
28 guint param_id,
29 GValue *value,
30 GParamSpec *pspec);
31 static void gnumeric_cell_renderer_toggle_set_property (GObject *object,
32 guint param_id,
33 const GValue *value,
34 GParamSpec *pspec);
36 static void gnumeric_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
37 GtkWidget *widget,
38 GdkRectangle const *cell_area,
39 gint *x_offset,
40 gint *y_offset,
41 gint *width,
42 gint *height);
44 static void gnumeric_cell_renderer_toggle_render (GtkCellRenderer *cell,
45 cairo_t *cr,
46 GtkWidget *widget,
47 GdkRectangle const *background_area,
48 GdkRectangle const *cell_area,
49 GtkCellRendererState flags);
51 static void gnumeric_cell_renderer_toggle_class_init
52 (GnmCellRendererToggleClass *cell_toggle_class);
54 static GtkCellRendererToggleClass *parent_class = NULL;
56 enum {
57 PROP_ZERO,
58 PROP_PIXBUF
61 GType
62 gnm_cell_renderer_toggle_get_type (void)
64 static GType cell_toggle_type = 0;
66 if (!cell_toggle_type)
68 static const GTypeInfo cell_toggle_info =
70 sizeof (GnmCellRendererToggleClass),
71 NULL, /* base_init */
72 NULL, /* base_finalize */
73 (GClassInitFunc)gnumeric_cell_renderer_toggle_class_init,
74 NULL, /* class_finalize */
75 NULL, /* class_data */
76 sizeof (GnmCellRendererToggle),
77 0, /* n_preallocs */
78 (GInstanceInitFunc) NULL,
81 cell_toggle_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TOGGLE,
82 "GnmCellRendererToggle",
83 &cell_toggle_info, 0);
86 return cell_toggle_type;
89 static void
90 gnumeric_cell_renderer_toggle_dispose (GObject *obj)
92 GnmCellRendererToggle *celltoggle = GNM_CELL_RENDERER_TOGGLE (obj);
93 g_clear_object (&celltoggle->pixbuf);
94 G_OBJECT_CLASS (parent_class)->dispose (obj);
97 static void
98 gnumeric_cell_renderer_toggle_class_init (GnmCellRendererToggleClass *class)
100 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
101 GObjectClass *object_class = G_OBJECT_CLASS (class);
103 parent_class = g_type_class_peek_parent (object_class);
105 object_class->get_property = gnumeric_cell_renderer_toggle_get_property;
106 object_class->set_property = gnumeric_cell_renderer_toggle_set_property;
107 object_class->dispose = gnumeric_cell_renderer_toggle_dispose;
109 cell_class->render = gnumeric_cell_renderer_toggle_render;
110 cell_class->get_size = gnumeric_cell_renderer_toggle_get_size;
112 g_object_class_install_property
113 (object_class, PROP_PIXBUF,
114 g_param_spec_object ("pixbuf",
115 P_("Pixbuf Object"),
116 P_("The pixbuf to render."),
117 GDK_TYPE_PIXBUF,
118 GSF_PARAM_STATIC | G_PARAM_READWRITE));
122 GtkCellRenderer *
123 gnm_cell_renderer_toggle_new (void)
125 return GTK_CELL_RENDERER (g_object_new (GNM_CELL_RENDERER_TOGGLE_TYPE, NULL));
128 static void
129 gnumeric_cell_renderer_toggle_get_property (GObject *object,
130 guint param_id,
131 GValue *value,
132 GParamSpec *pspec)
134 GnmCellRendererToggle *celltoggle = GNM_CELL_RENDERER_TOGGLE (object);
136 switch (param_id) {
137 case PROP_PIXBUF:
138 g_value_set_object (value, celltoggle->pixbuf);
139 break;
140 default:
141 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
142 break;
147 static void
148 gnumeric_cell_renderer_toggle_set_property (GObject *object,
149 guint param_id,
150 const GValue *value,
151 GParamSpec *pspec)
153 GnmCellRendererToggle *celltoggle = GNM_CELL_RENDERER_TOGGLE (object);
154 GdkPixbuf *pixbuf;
156 switch (param_id) {
157 case PROP_PIXBUF:
158 pixbuf = (GdkPixbuf*) g_value_get_object (value);
159 if (pixbuf)
160 g_object_ref (pixbuf);
161 if (celltoggle->pixbuf)
162 g_object_unref (celltoggle->pixbuf);
163 celltoggle->pixbuf = pixbuf;
164 break;
165 default:
166 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
167 break;
171 static void
172 gnumeric_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
173 G_GNUC_UNUSED GtkWidget *widget,
174 GdkRectangle const *cell_area,
175 gint *x_offset,
176 gint *y_offset,
177 gint *width,
178 gint *height)
180 GnmCellRendererToggle *cellpixbuf = (GnmCellRendererToggle *) cell;
181 gint pixbuf_width = 0;
182 gint pixbuf_height = 0;
183 gint calc_width;
184 gint calc_height;
185 int xpad, ypad;
186 gfloat xalign, yalign;
188 if (cellpixbuf->pixbuf)
190 pixbuf_width = gdk_pixbuf_get_width (cellpixbuf->pixbuf);
191 pixbuf_height = gdk_pixbuf_get_height (cellpixbuf->pixbuf);
194 gtk_cell_renderer_get_padding (GTK_CELL_RENDERER (cellpixbuf),
195 &xpad, &ypad);
196 gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (cellpixbuf),
197 &xalign, &yalign);
198 calc_width = xpad * 2 + pixbuf_width;
199 calc_height = ypad * 2 + pixbuf_height;
201 if (x_offset) *x_offset = 0;
202 if (y_offset) *y_offset = 0;
204 if (cell_area && pixbuf_width > 0 && pixbuf_height > 0)
206 if (x_offset)
208 *x_offset = xalign * (cell_area->width - calc_width -
209 (2 * xpad));
210 *x_offset = MAX (*x_offset, 0) + xpad;
212 if (y_offset)
214 *y_offset = yalign * (cell_area->height - calc_height -
215 (2 * ypad));
216 *y_offset = MAX (*y_offset, 0) + ypad;
220 if (calc_width)
221 *width = calc_width;
223 if (height)
224 *height = calc_height;
228 static void
229 gnumeric_cell_renderer_toggle_render (GtkCellRenderer *cell,
230 cairo_t *cr,
231 GtkWidget *widget,
232 G_GNUC_UNUSED GdkRectangle const *background_area,
233 GdkRectangle const *cell_area,
234 G_GNUC_UNUSED GtkCellRendererState flags)
236 GnmCellRendererToggle *cellpixbuf = (GnmCellRendererToggle *) cell;
237 GdkPixbuf *pixbuf;
238 GdkRectangle pix_rect;
239 GdkRectangle draw_rect;
240 int xpad, ypad;
242 pixbuf = cellpixbuf->pixbuf;
244 if (!pixbuf)
245 return;
247 gnumeric_cell_renderer_toggle_get_size (cell, widget, cell_area,
248 &pix_rect.x,
249 &pix_rect.y,
250 &pix_rect.width,
251 &pix_rect.height);
253 gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
255 pix_rect.x += cell_area->x;
256 pix_rect.y += cell_area->y;
257 pix_rect.width -= xpad * 2;
258 pix_rect.height -= ypad * 2;
260 if (gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect)) {
261 gdk_cairo_set_source_pixbuf (cr, pixbuf,
262 draw_rect.x, draw_rect.y);
263 cairo_rectangle (cr, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height);
264 cairo_fill (cr);