2 * Copyright (C) 2000 Red Hat, Inc. Jonathan Blandford
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.
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.
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.
20 #include "gtkcellrenderer.h"
23 static void gtk_cell_renderer_init (GtkCellRenderer *cell);
24 static void gtk_cell_renderer_class_init (GtkCellRendererClass *class);
25 static void gtk_cell_renderer_get_property (GObject *object,
29 static void gtk_cell_renderer_set_property (GObject *object,
33 static void set_cell_bg_color (GtkCellRenderer *cell,
50 PROP_CELL_BACKGROUND_GDK,
51 PROP_CELL_BACKGROUND_SET
54 #define CELLINFO_KEY "gtk-cell-renderer-info"
56 typedef struct _GtkCellRendererInfo GtkCellRendererInfo;
57 struct _GtkCellRendererInfo
59 GdkColor cell_background;
63 gtk_cell_renderer_get_type (void)
65 static GtkType cell_type = 0;
69 static const GTypeInfo cell_info =
71 sizeof (GtkCellRendererClass),
73 NULL, /* base_finalize */
74 (GClassInitFunc) gtk_cell_renderer_class_init,
75 NULL, /* class_finalize */
76 NULL, /* class_data */
77 sizeof (GtkCellRenderer),
79 (GInstanceInitFunc) gtk_cell_renderer_init,
82 cell_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkCellRenderer", &cell_info, 0);
89 gtk_cell_renderer_init (GtkCellRenderer *cell)
91 GtkCellRendererInfo *cellinfo;
93 cell->mode = GTK_CELL_RENDERER_MODE_INERT;
102 cellinfo = g_new0 (GtkCellRendererInfo, 1);
103 g_object_set_data_full (G_OBJECT (cell), CELLINFO_KEY, cellinfo, g_free);
107 gtk_cell_renderer_class_init (GtkCellRendererClass *class)
109 GObjectClass *object_class = G_OBJECT_CLASS (class);
111 object_class->get_property = gtk_cell_renderer_get_property;
112 object_class->set_property = gtk_cell_renderer_set_property;
114 class->render = NULL;
115 class->get_size = NULL;
117 g_object_class_install_property (object_class,
119 g_param_spec_enum ("mode",
121 _("Editable mode of the CellRenderer"),
122 GTK_TYPE_CELL_RENDERER_MODE,
123 GTK_CELL_RENDERER_MODE_INERT,
127 g_object_class_install_property (object_class,
129 g_param_spec_boolean ("visible",
131 _("Display the cell"),
136 g_object_class_install_property (object_class,
138 g_param_spec_float ("xalign",
147 g_object_class_install_property (object_class,
149 g_param_spec_float ("yalign",
158 g_object_class_install_property (object_class,
160 g_param_spec_uint ("xpad",
169 g_object_class_install_property (object_class,
171 g_param_spec_uint ("ypad",
180 g_object_class_install_property (object_class,
182 g_param_spec_int ("width",
184 _("The fixed width."),
191 g_object_class_install_property (object_class,
193 g_param_spec_int ("height",
195 _("The fixed height."),
202 g_object_class_install_property (object_class,
204 g_param_spec_boolean ("is_expander",
206 _("Row has children."),
212 g_object_class_install_property (object_class,
214 g_param_spec_boolean ("is_expanded",
216 _("Row is an expander row, and is expanded"),
221 g_object_class_install_property (object_class,
222 PROP_CELL_BACKGROUND,
223 g_param_spec_string ("cell_background",
224 _("Cell background color name"),
225 _("Cell background color as a string"),
229 g_object_class_install_property (object_class,
230 PROP_CELL_BACKGROUND_GDK,
231 g_param_spec_boxed ("cell_background_gdk",
232 _("Cell background color"),
233 _("Cell background color as a GdkColor"),
235 G_PARAM_READABLE | G_PARAM_WRITABLE));
238 #define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (object_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE))
240 ADD_SET_PROP ("cell_background_set", PROP_CELL_BACKGROUND_SET,
241 _("Cell background set"),
242 _("Whether this tag affects the cell background color"));
246 gtk_cell_renderer_get_property (GObject *object,
251 GtkCellRenderer *cell = GTK_CELL_RENDERER (object);
252 GtkCellRendererInfo *cellinfo = g_object_get_data (object, CELLINFO_KEY);
257 g_value_set_enum (value, cell->mode);
260 g_value_set_boolean (value, cell->visible);
263 g_value_set_float (value, cell->xalign);
266 g_value_set_float (value, cell->yalign);
269 g_value_set_uint (value, cell->xpad);
272 g_value_set_uint (value, cell->ypad);
275 g_value_set_int (value, cell->width);
278 g_value_set_int (value, cell->height);
280 case PROP_IS_EXPANDER:
281 g_value_set_int (value, cell->is_expander);
283 case PROP_IS_EXPANDED:
284 g_value_set_int (value, cell->is_expanded);
286 case PROP_CELL_BACKGROUND_GDK:
290 color.red = cellinfo->cell_background.red;
291 color.green = cellinfo->cell_background.green;
292 color.blue = cellinfo->cell_background.blue;
294 g_value_set_boxed (value, &color);
297 case PROP_CELL_BACKGROUND_SET:
298 g_value_set_boolean (value, cell->cell_background_set);
300 case PROP_CELL_BACKGROUND:
302 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
309 gtk_cell_renderer_set_property (GObject *object,
314 GtkCellRenderer *cell = GTK_CELL_RENDERER (object);
319 cell->mode = g_value_get_enum (value);
322 cell->visible = g_value_get_boolean (value);
325 cell->xalign = g_value_get_float (value);
328 cell->yalign = g_value_get_float (value);
331 cell->xpad = g_value_get_uint (value);
334 cell->ypad = g_value_get_uint (value);
337 cell->width = g_value_get_int (value);
340 cell->height = g_value_get_int (value);
342 case PROP_IS_EXPANDER:
343 cell->is_expander = g_value_get_boolean (value);
345 case PROP_IS_EXPANDED:
346 cell->is_expanded = g_value_get_boolean (value);
348 case PROP_CELL_BACKGROUND:
352 if (!g_value_get_string (value))
353 set_cell_bg_color (cell, NULL);
354 else if (gdk_color_parse (g_value_get_string (value), &color))
355 set_cell_bg_color (cell, &color);
357 g_warning ("Don't know color `%s'", g_value_get_string (value));
359 g_object_notify (object, "cell_background_gdk");
362 case PROP_CELL_BACKGROUND_GDK:
363 set_cell_bg_color (cell, g_value_get_boxed (value));
365 case PROP_CELL_BACKGROUND_SET:
366 cell->cell_background_set = g_value_get_boolean (value);
369 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
375 set_cell_bg_color (GtkCellRenderer *cell,
378 GtkCellRendererInfo *cellinfo = g_object_get_data (G_OBJECT (cell), CELLINFO_KEY);
382 if (!cell->cell_background_set)
384 cell->cell_background_set = TRUE;
385 g_object_notify (G_OBJECT (cell), "cell_background_set");
388 cellinfo->cell_background.red = color->red;
389 cellinfo->cell_background.green = color->green;
390 cellinfo->cell_background.blue = color->blue;
394 if (cell->cell_background_set)
396 cell->cell_background_set = FALSE;
397 g_object_notify (G_OBJECT (cell), "cell_background_set");
403 * gtk_cell_renderer_get_size:
404 * @cell: a #GtkCellRenderer
405 * @widget: the widget the renderer is rendering to
406 * @cell_area: The area a cell will be allocated, or %NULL
407 * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
408 * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
409 * @width: location to return width needed to render a cell, or %NULL
410 * @height: location to return height needed to render a cell, or %NULL
412 * Obtains the width and height needed to render the cell. Used by view widgets
413 * to determine the appropriate size for the cell_area passed to
414 * gtk_cell_renderer_render(). If @cell_area is not %NULL, fills in the x and y
415 * offsets (if set) of the cell relative to this location. Please note that the
416 * values set in @width and @height, as well as those in @x_offset and @y_offset
417 * are inclusive of the xpad and ypad properties.
420 gtk_cell_renderer_get_size (GtkCellRenderer *cell,
422 GdkRectangle *cell_area,
428 gint *real_width = width;
429 gint *real_height = height;
431 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
432 g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
434 if (width && cell->width != -1)
437 *width = cell->width;
439 if (height && cell->height != -1)
442 *height = cell->height;
445 GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, cell_area, x_offset, y_offset, real_width, real_height);
449 * gtk_cell_renderer_render:
450 * @cell: a #GtkCellRenderer
451 * @window: a #GdkDrawable to draw to
452 * @widget: the widget owning @window
453 * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
454 * @cell_area: area normally rendered by a cell renderer
455 * @expose_area: area that actually needs updating
456 * @flags: flags that affect rendering
458 * Invokes the virtual render function of the #GtkCellRenderer. The three
459 * passed-in rectangles are areas of @window. Most renderers will draw within
460 * @cell_area; the xalign, yalign, xpad, and ypad fields of the #GtkCellRenderer
461 * should be honored with respect to @cell_area. @background_area includes the
462 * blank space around the cell, and also the area containing the tree expander;
463 * so the @background_area rectangles for all cells tile to cover the entire
464 * @window. @expose_area is a clip rectangle.
468 gtk_cell_renderer_render (GtkCellRenderer *cell,
471 GdkRectangle *background_area,
472 GdkRectangle *cell_area,
473 GdkRectangle *expose_area,
474 GtkCellRendererState flags)
476 gboolean selected = FALSE;
477 GtkCellRendererInfo *cellinfo = g_object_get_data (G_OBJECT (cell), CELLINFO_KEY);
479 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
480 g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
482 selected = (flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED;
484 if (cell->cell_background_set && !selected)
489 color.red = cellinfo->cell_background.red;
490 color.green = cellinfo->cell_background.green;
491 color.blue = cellinfo->cell_background.blue;
493 gc = gdk_gc_new (window);
494 gdk_gc_set_rgb_fg_color (gc, &color);
495 gdk_draw_rectangle (window, gc, TRUE,
496 background_area->x, background_area->y,
497 background_area->width, background_area->height);
498 g_object_unref (G_OBJECT (gc));
501 GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
511 * gtk_cell_renderer_activate:
512 * @cell: a #GtkCellRenderer
513 * @event: a #GdkEvent
514 * @widget: widget that received the event
515 * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
516 * @background_area: background area as passed to @gtk_cell_renderer_render
517 * @cell_area: cell area as passed to @gtk_cell_renderer_render
518 * @flags: render flags
520 * Passes an activate event to the cell renderer for possible processing. Some
521 * cell renderers may use events; for example, #GtkCellRendererToggle toggles
522 * when it gets a mouse click.
524 * Return value: %TRUE if the event was consumed/handled
527 gtk_cell_renderer_activate (GtkCellRenderer *cell,
531 GdkRectangle *background_area,
532 GdkRectangle *cell_area,
533 GtkCellRendererState flags)
535 g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE);
537 if (cell->mode != GTK_CELL_RENDERER_MODE_ACTIVATABLE)
540 if (GTK_CELL_RENDERER_GET_CLASS (cell)->activate == NULL)
543 return GTK_CELL_RENDERER_GET_CLASS (cell)->activate (cell,
553 * gtk_cell_renderer_start_editing:
554 * @cell: a #GtkCellRenderer
555 * @event: a #GdkEvent
556 * @widget: widget that received the event
557 * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
558 * @background_area: background area as passed to @gtk_cell_renderer_render
559 * @cell_area: cell area as passed to @gtk_cell_renderer_render
560 * @flags: render flags
562 * Passes an activate event to the cell renderer for possible processing.
564 * Return value: A new #GtkCellEditable, or %NULL
567 gtk_cell_renderer_start_editing (GtkCellRenderer *cell,
571 GdkRectangle *background_area,
572 GdkRectangle *cell_area,
573 GtkCellRendererState flags)
576 g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), NULL);
578 if (cell->mode != GTK_CELL_RENDERER_MODE_EDITABLE)
581 if (GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing == NULL)
585 return GTK_CELL_RENDERER_GET_CLASS (cell)->start_editing (cell,
595 * gtk_cell_renderer_set_fixed_size:
596 * @cell: A #GtkCellRenderer
597 * @width: the width of the cell renderer, or -1
598 * @height: the height of the cell renderer, or -1
600 * Sets the renderer size to be explicit, independent of the properties set.
603 gtk_cell_renderer_set_fixed_size (GtkCellRenderer *cell,
607 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
608 g_return_if_fail (width >= -1 && height >= -1);
610 if ((width != cell->width) || (height != cell->height))
612 g_object_freeze_notify (G_OBJECT (cell));
614 if (width != cell->width)
617 g_object_notify (G_OBJECT (cell), "width");
620 if (height != cell->height)
622 cell->height = height;
623 g_object_notify (G_OBJECT (cell), "height");
626 g_object_thaw_notify (G_OBJECT (cell));
631 * gtk_cell_renderer_get_fixed_size:
632 * @cell: A #GtkCellRenderer
633 * @width: location to fill in with the fixed width of the widget, or %NULL
634 * @height: location to fill in with the fixed height of the widget, or %NULL
636 * Fills in @width and @height with the appropriate size of @cell.
639 gtk_cell_renderer_get_fixed_size (GtkCellRenderer *cell,
643 g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
646 (* width) = cell->width;
648 (* height) = cell->height;