2 * Copyright (C) 2002, 2003 Kristian Rietveld <kris@gtk.org>
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.
22 #include "gtkcellview.h"
23 #include "gtkcelllayout.h"
24 #include "gtkcellareabox.h"
26 #include "gtkcellrenderertext.h"
27 #include "gtkcellrendererpixbuf.h"
28 #include "gtkprivate.h"
29 #include "gtkorientable.h"
30 #include <gobject/gmarshal.h>
31 #include "gtkbuildable.h"
36 * @Short_description: A widget displaying a single row of a GtkTreeModel
39 * A #GtkCellView displays a single row of a #GtkTreeModel using a #GtkCellArea
40 * and #GtkCellAreaContext. A #GtkCellAreaContext can be provided to the
41 * #GtkCellView at construction time in order to keep the cellview in context
42 * of a group of cell views, this ensures that the renderers displayed will
43 * be properly aligned with eachother (like the aligned cells of #GtkTreeMenu).
45 * #GtkCellView is #GtkOrientable in order to decide in which orientation
46 * the underlying #GtkCellAreaContext should be allocated. Taking the #GtkTreeMenu
47 * as an example, cellviews should be oriented horizontally if the menus are
48 * listed top-to-bottom and thus all share the same width but may have separate
49 * individual heights (left-to-right menus should be allocated vertically since
50 * they all share the same height but may have variable widths).
53 static GObject *gtk_cell_view_constructor (GType type,
54 guint n_construct_properties,
55 GObjectConstructParam *construct_properties);
56 static void gtk_cell_view_get_property (GObject *object,
60 static void gtk_cell_view_set_property (GObject *object,
64 static void gtk_cell_view_finalize (GObject *object);
65 static void gtk_cell_view_dispose (GObject *object);
66 static void gtk_cell_view_size_allocate (GtkWidget *widget,
67 GtkAllocation *allocation);
68 static gboolean gtk_cell_view_draw (GtkWidget *widget,
70 static void gtk_cell_view_set_value (GtkCellView *cell_view,
71 GtkCellRenderer *renderer,
74 static void gtk_cell_view_set_cell_data (GtkCellView *cell_view);
77 static void gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface);
78 static GtkCellArea *gtk_cell_view_cell_layout_get_area (GtkCellLayout *layout);
82 static void gtk_cell_view_buildable_init (GtkBuildableIface *iface);
83 static gboolean gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable,
87 GMarkupParser *parser,
89 static void gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable,
95 static void gtk_cell_view_get_preferred_width (GtkWidget *widget,
98 static void gtk_cell_view_get_preferred_height (GtkWidget *widget,
101 static void gtk_cell_view_get_preferred_width_for_height (GtkWidget *widget,
105 static void gtk_cell_view_get_preferred_height_for_width (GtkWidget *widget,
110 static void context_size_changed_cb (GtkCellAreaContext *context,
113 static void row_changed_cb (GtkTreeModel *model,
119 struct _GtkCellViewPrivate
122 GtkTreeRowReference *displayed_row;
125 GtkCellAreaContext *context;
127 GtkOrientation orientation;
130 gboolean background_set;
132 gulong size_changed_id;
133 gulong row_changed_id;
135 guint32 draw_sensitive : 1;
136 guint32 fit_model : 1;
139 static GtkBuildableIface *parent_buildable_iface;
147 PROP_BACKGROUND_RGBA,
151 PROP_CELL_AREA_CONTEXT,
156 G_DEFINE_TYPE_WITH_CODE (GtkCellView, gtk_cell_view, GTK_TYPE_WIDGET,
157 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
158 gtk_cell_view_cell_layout_init)
159 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
160 gtk_cell_view_buildable_init)
161 G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
164 gtk_cell_view_class_init (GtkCellViewClass *klass)
166 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
167 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
169 gobject_class->constructor = gtk_cell_view_constructor;
170 gobject_class->get_property = gtk_cell_view_get_property;
171 gobject_class->set_property = gtk_cell_view_set_property;
172 gobject_class->finalize = gtk_cell_view_finalize;
173 gobject_class->dispose = gtk_cell_view_dispose;
175 widget_class->draw = gtk_cell_view_draw;
176 widget_class->size_allocate = gtk_cell_view_size_allocate;
177 widget_class->get_preferred_width = gtk_cell_view_get_preferred_width;
178 widget_class->get_preferred_height = gtk_cell_view_get_preferred_height;
179 widget_class->get_preferred_width_for_height = gtk_cell_view_get_preferred_width_for_height;
180 widget_class->get_preferred_height_for_width = gtk_cell_view_get_preferred_height_for_width;
183 g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation");
185 g_object_class_install_property (gobject_class,
187 g_param_spec_string ("background",
188 P_("Background color name"),
189 P_("Background color as a string"),
191 GTK_PARAM_WRITABLE));
192 g_object_class_install_property (gobject_class,
194 g_param_spec_boxed ("background-gdk",
195 P_("Background color"),
196 P_("Background color as a GdkColor"),
198 GTK_PARAM_READWRITE));
200 * GtkCellView:background-rgba
202 * The background color as a #GdkRGBA
206 g_object_class_install_property (gobject_class,
207 PROP_BACKGROUND_RGBA,
208 g_param_spec_boxed ("background-rgba",
209 P_("Background RGBA color"),
210 P_("Background color as a GdkRGBA"),
212 GTK_PARAM_READWRITE));
217 * The model for cell view
221 g_object_class_install_property (gobject_class,
223 g_param_spec_object ("model",
224 P_("CellView model"),
225 P_("The model for cell view"),
227 GTK_PARAM_READWRITE));
231 * GtkCellView:cell-area
233 * The #GtkCellArea rendering cells
237 g_object_class_install_property (gobject_class,
239 g_param_spec_object ("cell-area",
241 P_("The GtkCellArea used to layout cells"),
243 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
246 * GtkCellView:cell-area-context
248 * The #GtkCellAreaContext used to compute the geometry of the cell view.
252 g_object_class_install_property (gobject_class,
253 PROP_CELL_AREA_CONTEXT,
254 g_param_spec_object ("cell-area-context",
255 P_("Cell Area Context"),
256 P_("The GtkCellAreaContext used to "
257 "compute the geometry of the cell view"),
258 GTK_TYPE_CELL_AREA_CONTEXT,
259 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
262 * GtkCellView:draw-sensitive
264 * Whether all cells should be draw as sensitive for this view regardless
265 * of the actual cell properties (used to make menus with submenus appear
266 * sensitive when the items in submenus might be insensitive).
270 g_object_class_install_property (gobject_class,
272 g_param_spec_boolean ("draw-sensitive",
273 P_("Draw Sensitive"),
274 P_("Whether to force cells to be drawn in a "
277 GTK_PARAM_READWRITE));
280 * GtkCellView:fit-model
282 * Whether the view should request enough space to always fit
283 * the size of every row in the model (used by the combo box to
284 * ensure the combo box size doesnt change when different items
289 g_object_class_install_property (gobject_class,
291 g_param_spec_boolean ("fit-model",
293 P_("Whether to request enough space for "
294 "every row in the model"),
296 GTK_PARAM_READWRITE));
299 #define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (gobject_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, GTK_PARAM_READWRITE))
301 ADD_SET_PROP ("background-set", PROP_BACKGROUND_SET,
302 P_("Background set"),
303 P_("Whether this tag affects the background color"));
305 g_type_class_add_private (gobject_class, sizeof (GtkCellViewPrivate));
309 gtk_cell_view_buildable_init (GtkBuildableIface *iface)
311 parent_buildable_iface = g_type_interface_peek_parent (iface);
312 iface->add_child = _gtk_cell_layout_buildable_add_child;
313 iface->custom_tag_start = gtk_cell_view_buildable_custom_tag_start;
314 iface->custom_tag_end = gtk_cell_view_buildable_custom_tag_end;
318 gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface)
320 iface->get_area = gtk_cell_view_cell_layout_get_area;
324 gtk_cell_view_constructor (GType type,
325 guint n_construct_properties,
326 GObjectConstructParam *construct_properties)
330 GtkCellViewPrivate *priv;
332 object = G_OBJECT_CLASS (gtk_cell_view_parent_class)->constructor
333 (type, n_construct_properties, construct_properties);
335 view = GTK_CELL_VIEW (object);
340 GtkCellArea *area = gtk_cell_area_box_new ();
342 priv->area = g_object_ref_sink (area);
346 priv->context = gtk_cell_area_create_context (priv->area);
348 priv->size_changed_id =
349 g_signal_connect (priv->context, "notify",
350 G_CALLBACK (context_size_changed_cb), view);
356 gtk_cell_view_get_property (GObject *object,
361 GtkCellView *view = GTK_CELL_VIEW (object);
365 case PROP_ORIENTATION:
366 g_value_set_enum (value, view->priv->orientation);
368 case PROP_BACKGROUND_GDK:
372 color.red = (guint) (view->priv->background.red * 65535);
373 color.green = (guint) (view->priv->background.green * 65535);
374 color.blue = (guint) (view->priv->background.blue * 65535);
377 g_value_set_boxed (value, &color);
380 case PROP_BACKGROUND_RGBA:
381 g_value_set_boxed (value, &view->priv->background);
383 case PROP_BACKGROUND_SET:
384 g_value_set_boolean (value, view->priv->background_set);
387 g_value_set_object (value, view->priv->model);
390 g_value_set_object (value, view->priv->area);
392 case PROP_CELL_AREA_CONTEXT:
393 g_value_set_object (value, view->priv->context);
395 case PROP_DRAW_SENSITIVE:
396 g_value_set_boolean (value, view->priv->draw_sensitive);
399 g_value_set_boolean (value, view->priv->fit_model);
402 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
408 gtk_cell_view_set_property (GObject *object,
413 GtkCellView *view = GTK_CELL_VIEW (object);
415 GtkCellAreaContext *context;
419 case PROP_ORIENTATION:
420 view->priv->orientation = g_value_get_enum (value);
421 if (view->priv->context)
422 gtk_cell_area_context_reset (view->priv->context);
424 case PROP_BACKGROUND:
428 if (!g_value_get_string (value))
429 gtk_cell_view_set_background_color (view, NULL);
430 else if (gdk_color_parse (g_value_get_string (value), &color))
431 gtk_cell_view_set_background_color (view, &color);
433 g_warning ("Don't know color `%s'", g_value_get_string (value));
435 g_object_notify (object, "background-gdk");
438 case PROP_BACKGROUND_GDK:
439 gtk_cell_view_set_background_color (view, g_value_get_boxed (value));
441 case PROP_BACKGROUND_RGBA:
442 gtk_cell_view_set_background_rgba (view, g_value_get_boxed (value));
444 case PROP_BACKGROUND_SET:
445 view->priv->background_set = g_value_get_boolean (value);
448 gtk_cell_view_set_model (view, g_value_get_object (value));
451 /* Construct-only, can only be assigned once */
452 area = g_value_get_object (value);
455 view->priv->area = g_object_ref_sink (area);
457 case PROP_CELL_AREA_CONTEXT:
458 /* Construct-only, can only be assigned once */
459 context = g_value_get_object (value);
462 view->priv->context = g_object_ref (context);
465 case PROP_DRAW_SENSITIVE:
466 gtk_cell_view_set_draw_sensitive (view, g_value_get_boolean (value));
470 gtk_cell_view_set_fit_model (view, g_value_get_boolean (value));
474 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
480 gtk_cell_view_init (GtkCellView *cellview)
482 GtkCellViewPrivate *priv;
484 cellview->priv = G_TYPE_INSTANCE_GET_PRIVATE (cellview,
487 priv = cellview->priv;
489 gtk_widget_set_has_window (GTK_WIDGET (cellview), FALSE);
491 priv->orientation = GTK_ORIENTATION_HORIZONTAL;
495 gtk_cell_view_finalize (GObject *object)
497 GtkCellView *cellview = GTK_CELL_VIEW (object);
499 if (cellview->priv->displayed_row)
500 gtk_tree_row_reference_free (cellview->priv->displayed_row);
502 G_OBJECT_CLASS (gtk_cell_view_parent_class)->finalize (object);
506 gtk_cell_view_dispose (GObject *object)
508 GtkCellView *cellview = GTK_CELL_VIEW (object);
510 gtk_cell_view_set_model (cellview, NULL);
512 if (cellview->priv->area)
514 g_object_unref (cellview->priv->area);
515 cellview->priv->area = NULL;
518 if (cellview->priv->context)
520 g_signal_handler_disconnect (cellview->priv->context, cellview->priv->size_changed_id);
522 g_object_unref (cellview->priv->context);
523 cellview->priv->context = NULL;
524 cellview->priv->size_changed_id = 0;
527 G_OBJECT_CLASS (gtk_cell_view_parent_class)->dispose (object);
531 gtk_cell_view_size_allocate (GtkWidget *widget,
532 GtkAllocation *allocation)
534 GtkCellView *cellview = GTK_CELL_VIEW (widget);
535 GtkCellViewPrivate *priv = cellview->priv;
536 gint alloc_width, alloc_height;
538 gtk_widget_set_allocation (widget, allocation);
540 gtk_cell_area_context_get_allocation (priv->context, &alloc_width, &alloc_height);
542 /* The first cell view in context is responsible for allocating the context at allocate time
543 * (or the cellview has its own context and is not grouped with any other cell views)
545 * If the cellview is in "fit model" mode, we assume its not in context and needs to
546 * allocate every time.
549 gtk_cell_area_context_allocate (priv->context, allocation->width, allocation->height);
550 else if (alloc_width != allocation->width && priv->orientation == GTK_ORIENTATION_HORIZONTAL)
551 gtk_cell_area_context_allocate (priv->context, allocation->width, -1);
552 else if (alloc_height != allocation->height && priv->orientation == GTK_ORIENTATION_VERTICAL)
553 gtk_cell_area_context_allocate (priv->context, -1, allocation->height);
557 gtk_cell_view_request_model (GtkCellView *cellview,
559 GtkOrientation orientation,
564 GtkCellViewPrivate *priv = cellview->priv;
568 valid = gtk_tree_model_iter_children (priv->model, &iter, parent);
573 gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
575 if (orientation == GTK_ORIENTATION_HORIZONTAL)
578 gtk_cell_area_get_preferred_width (priv->area, priv->context,
579 GTK_WIDGET (cellview), &min, &nat);
581 gtk_cell_area_get_preferred_width_for_height (priv->area, priv->context,
582 GTK_WIDGET (cellview), for_size, &min, &nat);
587 gtk_cell_area_get_preferred_height (priv->area, priv->context,
588 GTK_WIDGET (cellview), &min, &nat);
590 gtk_cell_area_get_preferred_height_for_width (priv->area, priv->context,
591 GTK_WIDGET (cellview), for_size, &min, &nat);
594 *minimum_size = MAX (min, *minimum_size);
595 *natural_size = MAX (nat, *natural_size);
597 /* Recurse into children when they exist */
598 gtk_cell_view_request_model (cellview, &iter, orientation, for_size, minimum_size, natural_size);
600 valid = gtk_tree_model_iter_next (priv->model, &iter);
605 gtk_cell_view_get_preferred_width (GtkWidget *widget,
609 GtkCellView *cellview = GTK_CELL_VIEW (widget);
610 GtkCellViewPrivate *priv = cellview->priv;
612 g_signal_handler_block (priv->context, priv->size_changed_id);
616 gint min = 0, nat = 0;
617 gtk_cell_view_request_model (cellview, NULL, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat);
621 if (cellview->priv->displayed_row)
622 gtk_cell_view_set_cell_data (cellview);
624 gtk_cell_area_get_preferred_width (priv->area, priv->context, widget, NULL, NULL);
627 gtk_cell_area_context_get_preferred_width (priv->context, minimum_size, natural_size);
629 g_signal_handler_unblock (priv->context, priv->size_changed_id);
633 gtk_cell_view_get_preferred_height (GtkWidget *widget,
637 GtkCellView *cellview = GTK_CELL_VIEW (widget);
638 GtkCellViewPrivate *priv = cellview->priv;
640 g_signal_handler_block (priv->context, priv->size_changed_id);
644 gint min = 0, nat = 0;
645 gtk_cell_view_request_model (cellview, NULL, GTK_ORIENTATION_VERTICAL, -1, &min, &nat);
649 if (cellview->priv->displayed_row)
650 gtk_cell_view_set_cell_data (cellview);
652 gtk_cell_area_get_preferred_height (priv->area, priv->context, widget, NULL, NULL);
655 gtk_cell_area_context_get_preferred_height (priv->context, minimum_size, natural_size);
657 g_signal_handler_unblock (priv->context, priv->size_changed_id);
661 gtk_cell_view_get_preferred_width_for_height (GtkWidget *widget,
666 GtkCellView *cellview = GTK_CELL_VIEW (widget);
667 GtkCellViewPrivate *priv = cellview->priv;
671 gint min = 0, nat = 0;
672 gtk_cell_view_request_model (cellview, NULL, GTK_ORIENTATION_HORIZONTAL, for_size, &min, &nat);
679 if (cellview->priv->displayed_row)
680 gtk_cell_view_set_cell_data (cellview);
682 gtk_cell_area_get_preferred_width_for_height (priv->area, priv->context, widget,
683 for_size, minimum_size, natural_size);
688 gtk_cell_view_get_preferred_height_for_width (GtkWidget *widget,
693 GtkCellView *cellview = GTK_CELL_VIEW (widget);
694 GtkCellViewPrivate *priv = cellview->priv;
698 gint min = 0, nat = 0;
699 gtk_cell_view_request_model (cellview, NULL, GTK_ORIENTATION_VERTICAL, for_size, &min, &nat);
706 if (cellview->priv->displayed_row)
707 gtk_cell_view_set_cell_data (cellview);
709 gtk_cell_area_get_preferred_height_for_width (priv->area, priv->context, widget,
710 for_size, minimum_size, natural_size);
715 gtk_cell_view_draw (GtkWidget *widget,
718 GtkCellView *cellview;
720 GtkCellRendererState state;
722 cellview = GTK_CELL_VIEW (widget);
727 area.width = gtk_widget_get_allocated_width (widget);
728 area.height = gtk_widget_get_allocated_height (widget);
730 /* "blank" background */
731 if (cellview->priv->background_set)
733 gdk_cairo_rectangle (cr, &area);
734 gdk_cairo_set_source_rgba (cr, &cellview->priv->background);
738 /* set cell data (if available) */
739 if (cellview->priv->displayed_row)
740 gtk_cell_view_set_cell_data (cellview);
741 else if (cellview->priv->model)
744 if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_PRELIGHT)
745 state = GTK_CELL_RENDERER_PRELIT;
746 else if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_INSENSITIVE)
747 state = GTK_CELL_RENDERER_INSENSITIVE;
751 /* Render the cells */
752 gtk_cell_area_render (cellview->priv->area, cellview->priv->context,
753 widget, cr, &area, &area, state, FALSE);
759 gtk_cell_view_set_cell_data (GtkCellView *cell_view)
764 g_return_if_fail (cell_view->priv->displayed_row != NULL);
766 path = gtk_tree_row_reference_get_path (cell_view->priv->displayed_row);
770 gtk_tree_model_get_iter (cell_view->priv->model, &iter, path);
771 gtk_tree_path_free (path);
773 gtk_cell_area_apply_attributes (cell_view->priv->area,
774 cell_view->priv->model,
775 &iter, FALSE, FALSE);
777 if (cell_view->priv->draw_sensitive)
780 gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cell_view->priv->area));
782 for (l = cells; l; l = l->next)
784 GObject *renderer = l->data;
786 g_object_set (renderer, "sensitive", TRUE, NULL);
792 /* GtkCellLayout implementation */
794 gtk_cell_view_cell_layout_get_area (GtkCellLayout *layout)
796 GtkCellView *cellview = GTK_CELL_VIEW (layout);
798 return cellview->priv->area;
801 /* GtkBuildable implementation */
803 gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable,
806 const gchar *tagname,
807 GMarkupParser *parser,
810 if (parent_buildable_iface->custom_tag_start &&
811 parent_buildable_iface->custom_tag_start (buildable, builder, child,
812 tagname, parser, data))
815 return _gtk_cell_layout_buildable_custom_tag_start (buildable, builder, child,
816 tagname, parser, data);
820 gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable,
823 const gchar *tagname,
826 if (strcmp (tagname, "attributes") == 0 || strcmp (tagname, "cell-packing") == 0)
827 _gtk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname,
829 else if (parent_buildable_iface->custom_tag_end)
830 parent_buildable_iface->custom_tag_end (buildable, builder, child, tagname,
835 context_size_changed_cb (GtkCellAreaContext *context,
839 if (!strcmp (pspec->name, "minimum-width") ||
840 !strcmp (pspec->name, "natural-width") ||
841 !strcmp (pspec->name, "minimum-height") ||
842 !strcmp (pspec->name, "natural-height"))
843 gtk_widget_queue_resize (view);
847 row_changed_cb (GtkTreeModel *model,
852 GtkTreePath *row_path;
854 if (view->priv->displayed_row)
857 gtk_tree_row_reference_get_path (view->priv->displayed_row);
861 /* Resize everything in our context if our row changed */
862 if (gtk_tree_path_compare (row_path, path) == 0)
863 gtk_cell_area_context_reset (view->priv->context);
865 gtk_tree_path_free (row_path);
873 * Creates a new #GtkCellView widget.
875 * Return value: A newly created #GtkCellView widget.
880 gtk_cell_view_new (void)
882 GtkCellView *cellview;
884 cellview = g_object_new (gtk_cell_view_get_type (), NULL);
886 return GTK_WIDGET (cellview);
891 * gtk_cell_view_new_with_context:
892 * @area: the #GtkCellArea to layout cells
893 * @context: the #GtkCellAreaContext in which to calculate cell geometry
895 * Creates a new #GtkCellView widget with a specific #GtkCellArea
896 * to layout cells and a specific #GtkCellAreaContext.
898 * Specifying the same context for a handfull of cells lets
899 * the underlying area synchronize the geometry for those cells,
900 * in this way alignments with cellviews for other rows are
903 * Return value: A newly created #GtkCellView widget.
908 gtk_cell_view_new_with_context (GtkCellArea *area,
909 GtkCellAreaContext *context)
911 g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL);
912 g_return_val_if_fail (context == NULL || GTK_IS_CELL_AREA_CONTEXT (context), NULL);
914 return (GtkWidget *)g_object_new (GTK_TYPE_CELL_VIEW,
916 "cell-area-context", context,
921 * gtk_cell_view_new_with_text:
922 * @text: the text to display in the cell view
924 * Creates a new #GtkCellView widget, adds a #GtkCellRendererText
925 * to it, and makes its show @text.
927 * Return value: A newly created #GtkCellView widget.
932 gtk_cell_view_new_with_text (const gchar *text)
934 GtkCellView *cellview;
935 GtkCellRenderer *renderer;
936 GValue value = {0, };
938 cellview = GTK_CELL_VIEW (gtk_cell_view_new ());
940 renderer = gtk_cell_renderer_text_new ();
941 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview),
944 g_value_init (&value, G_TYPE_STRING);
945 g_value_set_string (&value, text);
946 gtk_cell_view_set_value (cellview, renderer, "text", &value);
947 g_value_unset (&value);
949 return GTK_WIDGET (cellview);
953 * gtk_cell_view_new_with_markup:
954 * @markup: the text to display in the cell view
956 * Creates a new #GtkCellView widget, adds a #GtkCellRendererText
957 * to it, and makes it show @markup. The text can be
958 * marked up with the <link linkend="PangoMarkupFormat">Pango text
959 * markup language</link>.
961 * Return value: A newly created #GtkCellView widget.
966 gtk_cell_view_new_with_markup (const gchar *markup)
968 GtkCellView *cellview;
969 GtkCellRenderer *renderer;
970 GValue value = {0, };
972 cellview = GTK_CELL_VIEW (gtk_cell_view_new ());
974 renderer = gtk_cell_renderer_text_new ();
975 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview),
978 g_value_init (&value, G_TYPE_STRING);
979 g_value_set_string (&value, markup);
980 gtk_cell_view_set_value (cellview, renderer, "markup", &value);
981 g_value_unset (&value);
983 return GTK_WIDGET (cellview);
987 * gtk_cell_view_new_with_pixbuf:
988 * @pixbuf: the image to display in the cell view
990 * Creates a new #GtkCellView widget, adds a #GtkCellRendererPixbuf
991 * to it, and makes its show @pixbuf.
993 * Return value: A newly created #GtkCellView widget.
998 gtk_cell_view_new_with_pixbuf (GdkPixbuf *pixbuf)
1000 GtkCellView *cellview;
1001 GtkCellRenderer *renderer;
1002 GValue value = {0, };
1004 cellview = GTK_CELL_VIEW (gtk_cell_view_new ());
1006 renderer = gtk_cell_renderer_pixbuf_new ();
1007 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview),
1010 g_value_init (&value, GDK_TYPE_PIXBUF);
1011 g_value_set_object (&value, pixbuf);
1012 gtk_cell_view_set_value (cellview, renderer, "pixbuf", &value);
1013 g_value_unset (&value);
1015 return GTK_WIDGET (cellview);
1019 * gtk_cell_view_set_value:
1020 * @cell_view: a #GtkCellView widget
1021 * @renderer: one of the renderers of @cell_view
1022 * @property: the name of the property of @renderer to set
1023 * @value: the new value to set the property to
1025 * Sets a property of a cell renderer of @cell_view, and
1026 * makes sure the display of @cell_view is updated.
1031 gtk_cell_view_set_value (GtkCellView *cell_view,
1032 GtkCellRenderer *renderer,
1036 g_object_set_property (G_OBJECT (renderer), property, value);
1038 /* force resize and redraw */
1039 gtk_widget_queue_resize (GTK_WIDGET (cell_view));
1040 gtk_widget_queue_draw (GTK_WIDGET (cell_view));
1044 * gtk_cell_view_set_model:
1045 * @cell_view: a #GtkCellView
1046 * @model: (allow-none): a #GtkTreeModel
1048 * Sets the model for @cell_view. If @cell_view already has a model
1049 * set, it will remove it before setting the new model. If @model is
1050 * %NULL, then it will unset the old model.
1055 gtk_cell_view_set_model (GtkCellView *cell_view,
1056 GtkTreeModel *model)
1058 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
1059 g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
1061 if (cell_view->priv->model)
1063 g_signal_handler_disconnect (cell_view->priv->model,
1064 cell_view->priv->row_changed_id);
1065 cell_view->priv->row_changed_id = 0;
1067 if (cell_view->priv->displayed_row)
1068 gtk_tree_row_reference_free (cell_view->priv->displayed_row);
1069 cell_view->priv->displayed_row = NULL;
1071 g_object_unref (cell_view->priv->model);
1072 cell_view->priv->model = NULL;
1075 cell_view->priv->model = model;
1077 if (cell_view->priv->model)
1079 g_object_ref (cell_view->priv->model);
1081 cell_view->priv->row_changed_id =
1082 g_signal_connect (cell_view->priv->model, "row-changed",
1083 G_CALLBACK (row_changed_cb), cell_view);
1088 * gtk_cell_view_get_model:
1089 * @cell_view: a #GtkCellView
1091 * Returns the model for @cell_view. If no model is used %NULL is
1094 * Returns: (transfer none): a #GtkTreeModel used or %NULL
1099 gtk_cell_view_get_model (GtkCellView *cell_view)
1101 g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), NULL);
1103 return cell_view->priv->model;
1107 * gtk_cell_view_set_displayed_row:
1108 * @cell_view: a #GtkCellView
1109 * @path: (allow-none): a #GtkTreePath or %NULL to unset.
1111 * Sets the row of the model that is currently displayed
1112 * by the #GtkCellView. If the path is unset, then the
1113 * contents of the cellview "stick" at their last value;
1114 * this is not normally a desired result, but may be
1115 * a needed intermediate state if say, the model for
1116 * the #GtkCellView becomes temporarily empty.
1121 gtk_cell_view_set_displayed_row (GtkCellView *cell_view,
1124 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
1125 g_return_if_fail (GTK_IS_TREE_MODEL (cell_view->priv->model));
1127 if (cell_view->priv->displayed_row)
1128 gtk_tree_row_reference_free (cell_view->priv->displayed_row);
1132 cell_view->priv->displayed_row =
1133 gtk_tree_row_reference_new (cell_view->priv->model, path);
1136 cell_view->priv->displayed_row = NULL;
1138 /* force resize and redraw */
1139 gtk_widget_queue_resize (GTK_WIDGET (cell_view));
1140 gtk_widget_queue_draw (GTK_WIDGET (cell_view));
1144 * gtk_cell_view_get_displayed_row:
1145 * @cell_view: a #GtkCellView
1147 * Returns a #GtkTreePath referring to the currently
1148 * displayed row. If no row is currently displayed,
1149 * %NULL is returned.
1151 * Returns: the currently displayed row or %NULL
1156 gtk_cell_view_get_displayed_row (GtkCellView *cell_view)
1158 g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), NULL);
1160 if (!cell_view->priv->displayed_row)
1163 return gtk_tree_row_reference_get_path (cell_view->priv->displayed_row);
1167 * gtk_cell_view_get_size_of_row:
1168 * @cell_view: a #GtkCellView
1169 * @path: a #GtkTreePath
1170 * @requisition: return location for the size
1172 * Sets @requisition to the size needed by @cell_view to display
1173 * the model row pointed to by @path.
1175 * Return value: %TRUE
1179 * Deprecated: 3.0: Combo box formerly used this to calculate the
1180 * sizes for cellviews, now you can achieve this by either using
1181 * the #GtkCellView:fit-model property or by setting the currently
1182 * displayed row of the #GtkCellView and using gtk_widget_get_preferred_size().
1185 gtk_cell_view_get_size_of_row (GtkCellView *cell_view,
1187 GtkRequisition *requisition)
1189 GtkTreeRowReference *tmp;
1192 g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE);
1193 g_return_val_if_fail (path != NULL, FALSE);
1195 tmp = cell_view->priv->displayed_row;
1196 cell_view->priv->displayed_row =
1197 gtk_tree_row_reference_new (cell_view->priv->model, path);
1199 gtk_widget_get_preferred_width (GTK_WIDGET (cell_view), &req.width, NULL);
1200 gtk_widget_get_preferred_height_for_width (GTK_WIDGET (cell_view), req.width, &req.height, NULL);
1202 gtk_tree_row_reference_free (cell_view->priv->displayed_row);
1203 cell_view->priv->displayed_row = tmp;
1212 * gtk_cell_view_set_background_color:
1213 * @cell_view: a #GtkCellView
1214 * @color: the new background color
1216 * Sets the background color of @view.
1221 gtk_cell_view_set_background_color (GtkCellView *cell_view,
1222 const GdkColor *color)
1224 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
1228 if (!cell_view->priv->background_set)
1230 cell_view->priv->background_set = TRUE;
1231 g_object_notify (G_OBJECT (cell_view), "background-set");
1234 cell_view->priv->background.red = color->red / 65535.;
1235 cell_view->priv->background.green = color->green / 65535.;
1236 cell_view->priv->background.blue = color->blue / 65535.;
1237 cell_view->priv->background.alpha = 1;
1241 if (cell_view->priv->background_set)
1243 cell_view->priv->background_set = FALSE;
1244 g_object_notify (G_OBJECT (cell_view), "background-set");
1248 gtk_widget_queue_draw (GTK_WIDGET (cell_view));
1252 * gtk_cell_view_set_background_rgba:
1253 * @cell_view: a #GtkCellView
1254 * @rgba: the new background color
1256 * Sets the background color of @cell_view.
1261 gtk_cell_view_set_background_rgba (GtkCellView *cell_view,
1262 const GdkRGBA *rgba)
1264 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
1268 if (!cell_view->priv->background_set)
1270 cell_view->priv->background_set = TRUE;
1271 g_object_notify (G_OBJECT (cell_view), "background-set");
1274 cell_view->priv->background = *rgba;
1278 if (cell_view->priv->background_set)
1280 cell_view->priv->background_set = FALSE;
1281 g_object_notify (G_OBJECT (cell_view), "background-set");
1285 gtk_widget_queue_draw (GTK_WIDGET (cell_view));
1289 * gtk_cell_view_get_draw_sensitive:
1290 * @cell_view: a #GtkCellView
1292 * Gets whether @cell_view is configured to draw all of it's
1293 * cells in a sensitive state.
1295 * Return value: whether @cell_view draws all of it's
1296 * cells in a sensitive state
1301 gtk_cell_view_get_draw_sensitive (GtkCellView *cell_view)
1303 GtkCellViewPrivate *priv;
1305 g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE);
1307 priv = cell_view->priv;
1309 return priv->draw_sensitive;
1313 * gtk_cell_view_set_draw_sensitive:
1314 * @cell_view: a #GtkCellView
1315 * @draw_sensitive: whether to draw all cells in a sensitive state.
1317 * Sets whether @cell_view should draw all of it's
1318 * cells in a sensitive state, this is used by #GtkTreeMenu
1319 * to ensure that rows with insensitive cells that contain
1320 * children appear sensitive in the parent menu item.
1325 gtk_cell_view_set_draw_sensitive (GtkCellView *cell_view,
1326 gboolean draw_sensitive)
1328 GtkCellViewPrivate *priv;
1330 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
1332 priv = cell_view->priv;
1334 if (priv->draw_sensitive != draw_sensitive)
1336 priv->draw_sensitive = draw_sensitive;
1338 g_object_notify (G_OBJECT (cell_view), "draw-sensitive");
1343 * gtk_cell_view_get_fit_model:
1344 * @cell_view: a #GtkCellView
1346 * Gets whether @cell_view is configured to request space
1347 * to fit the entire #GtkTreeModel.
1349 * Return value: whether @cell_view requests space to fit
1350 * the entire #GtkTreeModel.
1355 gtk_cell_view_get_fit_model (GtkCellView *cell_view)
1357 GtkCellViewPrivate *priv;
1359 g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE);
1361 priv = cell_view->priv;
1363 return priv->fit_model;
1367 * gtk_cell_view_set_fit_model:
1368 * @cell_view: a #GtkCellView
1369 * @fit_model: whether @cell_view should request space for the whole model.
1371 * Sets whether @cell_view should request space to fit the entire #GtkTreeModel.
1373 * This is used by #GtkComboBox to ensure that the cell view displayed on
1374 * the combo box's button always gets enough space and does not resize
1375 * when selection changes.
1380 gtk_cell_view_set_fit_model (GtkCellView *cell_view,
1383 GtkCellViewPrivate *priv;
1385 g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
1387 priv = cell_view->priv;
1389 if (priv->fit_model != fit_model)
1391 priv->fit_model = fit_model;
1393 gtk_cell_area_context_reset (cell_view->priv->context);
1395 g_object_notify (G_OBJECT (cell_view), "fit-model");