* Boston, MA 02111-1307, USA.
*/
-#include <config.h>
+#include "config.h"
+#include <string.h>
#include "gtkcellview.h"
#include "gtkcelllayout.h"
#include "gtkintl.h"
-#include "gtksignal.h"
#include "gtkcellrenderertext.h"
#include "gtkcellrendererpixbuf.h"
#include "gtkprivate.h"
+#include "gtksizerequest.h"
#include <gobject/gmarshal.h>
-#include "gtkalias.h"
+#include "gtkbuildable.h"
+
typedef struct _GtkCellViewCellInfo GtkCellViewCellInfo;
struct _GtkCellViewCellInfo
GtkCellRenderer *cell;
gint requested_width;
+ gint natural_width;
gint real_width;
guint expand : 1;
guint pack : 1;
GList *cell_list;
gint spacing;
- GdkColor background;
+ GdkRGBA background;
gboolean background_set;
};
const GValue *value,
GParamSpec *pspec);
static void gtk_cell_view_finalize (GObject *object);
-static void gtk_cell_view_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
static void gtk_cell_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
-static gboolean gtk_cell_view_expose (GtkWidget *widget,
- GdkEventExpose *event);
+static gboolean gtk_cell_view_draw (GtkWidget *widget,
+ cairo_t *cr);
static void gtk_cell_view_set_value (GtkCellView *cell_view,
GtkCellRenderer *renderer,
gchar *property,
static void gtk_cell_view_cell_layout_reorder (GtkCellLayout *layout,
GtkCellRenderer *cell,
gint position);
+static GList * gtk_cell_view_cell_layout_get_cells (GtkCellLayout *layout);
+
+/* buildable */
+static void gtk_cell_view_buildable_init (GtkBuildableIface *iface);
+static gboolean gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data);
+static void gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *data);
+
+static void gtk_cell_view_get_preferred_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size);
+static void gtk_cell_view_get_preferred_height (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size);
+static void gtk_cell_view_get_preferred_width_for_height (GtkWidget *widget,
+ gint avail_size,
+ gint *minimum_size,
+ gint *natural_size);
+static void gtk_cell_view_get_preferred_height_for_width (GtkWidget *widget,
+ gint avail_size,
+ gint *minimum_size,
+ gint *natural_size);
+
+static GtkBuildableIface *parent_buildable_iface;
-#define GTK_CELL_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_VIEW, GtkCellViewPrivate))
-
enum
{
PROP_0,
PROP_BACKGROUND,
PROP_BACKGROUND_GDK,
+ PROP_BACKGROUND_RGBA,
PROP_BACKGROUND_SET,
PROP_MODEL
};
G_DEFINE_TYPE_WITH_CODE (GtkCellView, gtk_cell_view, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
- gtk_cell_view_cell_layout_init))
+ gtk_cell_view_cell_layout_init)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ gtk_cell_view_buildable_init))
+
static void
gtk_cell_view_class_init (GtkCellViewClass *klass)
gobject_class->set_property = gtk_cell_view_set_property;
gobject_class->finalize = gtk_cell_view_finalize;
- widget_class->expose_event = gtk_cell_view_expose;
- widget_class->size_allocate = gtk_cell_view_size_allocate;
- widget_class->size_request = gtk_cell_view_size_request;
+ widget_class->draw = gtk_cell_view_draw;
+ widget_class->size_allocate = gtk_cell_view_size_allocate;
+ widget_class->get_preferred_width = gtk_cell_view_get_preferred_width;
+ widget_class->get_preferred_height = gtk_cell_view_get_preferred_height;
+ widget_class->get_preferred_width_for_height = gtk_cell_view_get_preferred_width_for_height;
+ widget_class->get_preferred_height_for_width = gtk_cell_view_get_preferred_height_for_width;
/* properties */
g_object_class_install_property (gobject_class,
P_("Background color as a GdkColor"),
GDK_TYPE_COLOR,
GTK_PARAM_READWRITE));
+ /**
+ * GtkCellView:background-rgba
+ *
+ * The background color as a #GdkRGBA
+ *
+ * Since: 3.0
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_BACKGROUND_RGBA,
+ g_param_spec_boxed ("background-rgba",
+ P_("Background RGBA color"),
+ P_("Background color as a GdkRGBA"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READWRITE));
/**
* GtkCellView:model
g_type_class_add_private (gobject_class, sizeof (GtkCellViewPrivate));
}
+static void
+gtk_cell_view_buildable_init (GtkBuildableIface *iface)
+{
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+ iface->add_child = _gtk_cell_layout_buildable_add_child;
+ iface->custom_tag_start = gtk_cell_view_buildable_custom_tag_start;
+ iface->custom_tag_end = gtk_cell_view_buildable_custom_tag_end;
+}
+
static void
gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface)
{
iface->set_cell_data_func = gtk_cell_view_cell_layout_set_cell_data_func;
iface->clear_attributes = gtk_cell_view_cell_layout_clear_attributes;
iface->reorder = gtk_cell_view_cell_layout_reorder;
+ iface->get_cells = gtk_cell_view_cell_layout_get_cells;
}
static void
{
GdkColor color;
- color = view->priv->background;
+ color.red = (guint) (view->priv->background.red * 65535);
+ color.green = (guint) (view->priv->background.green * 65535);
+ color.blue = (guint) (view->priv->background.blue * 65535);
+ color.pixel = 0;
g_value_set_boxed (value, &color);
}
break;
+ case PROP_BACKGROUND_RGBA:
+ g_value_set_boxed (value, &view->priv->background);
+ break;
case PROP_BACKGROUND_SET:
g_value_set_boolean (value, view->priv->background_set);
break;
case PROP_BACKGROUND_GDK:
gtk_cell_view_set_background_color (view, g_value_get_boxed (value));
break;
+ case PROP_BACKGROUND_RGBA:
+ gtk_cell_view_set_background_rgba (view, g_value_get_boxed (value));
+ break;
case PROP_BACKGROUND_SET:
view->priv->background_set = g_value_get_boolean (value);
break;
static void
gtk_cell_view_init (GtkCellView *cellview)
{
- GTK_WIDGET_SET_FLAGS (cellview, GTK_NO_WINDOW);
+ GtkCellViewPrivate *priv;
- cellview->priv = GTK_CELL_VIEW_GET_PRIVATE (cellview);
+ cellview->priv = G_TYPE_INSTANCE_GET_PRIVATE (cellview,
+ GTK_TYPE_CELL_VIEW,
+ GtkCellViewPrivate);
+ priv = cellview->priv;
+
+ gtk_widget_set_has_window (GTK_WIDGET (cellview), FALSE);
}
static void
if (cellview->priv->displayed_row)
gtk_tree_row_reference_free (cellview->priv->displayed_row);
- (* G_OBJECT_CLASS (gtk_cell_view_parent_class)->finalize) (object);
+ G_OBJECT_CLASS (gtk_cell_view_parent_class)->finalize (object);
}
static void
-gtk_cell_view_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
+gtk_cell_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
{
- GList *i;
- gboolean first_cell = TRUE;
- GtkCellView *cellview;
+ GtkCellView *cellview;
+ GtkRequestedSize *sizes;
+ GList *list;
+ gint n_visible_cells, n_expand_cells;
+ gint avail_width = 0;
+ gint extra_per_cell, extra_extra, i;
+ gboolean first_cell = TRUE;
- cellview = GTK_CELL_VIEW (widget);
+ gtk_widget_set_allocation (widget, allocation);
- requisition->width = 0;
- requisition->height = 0;
+ cellview = GTK_CELL_VIEW (widget);
- if (cellview->priv->displayed_row)
- gtk_cell_view_set_cell_data (cellview);
+ avail_width = allocation->width;
- for (i = cellview->priv->cell_list; i; i = i->next)
+ /* Count visible/expand children */
+ for (n_visible_cells = 0, n_expand_cells = 0, list = cellview->priv->cell_list;
+ list; list = list->next)
{
- gint width, height;
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
-
- if (!info->cell->visible)
- continue;
-
- if (!first_cell)
- requisition->width += cellview->priv->spacing;
-
- gtk_cell_renderer_get_size (info->cell, widget, NULL, NULL, NULL,
- &width, &height);
+ GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
- info->requested_width = width;
- requisition->width += width;
- requisition->height = MAX (requisition->height, height);
+ n_visible_cells++;
- first_cell = FALSE;
+ if (info->expand)
+ n_expand_cells++;
}
-}
-
-static void
-gtk_cell_view_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- GList *i;
- gint expand_cell_count = 0;
- gint full_requested_width = 0;
- gint extra_space;
- GtkCellView *cellview;
- widget->allocation = *allocation;
-
- cellview = GTK_CELL_VIEW (widget);
+ sizes = g_new0 (GtkRequestedSize, n_visible_cells);
/* checking how much extra space we have */
- for (i = cellview->priv->cell_list; i; i = i->next)
+ for (i = 0, list = cellview->priv->cell_list; list; list = list->next)
{
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
+ GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
- if (!info->cell->visible)
+ if (!gtk_cell_renderer_get_visible (info->cell))
continue;
- if (info->expand)
- expand_cell_count++;
+ sizes[i].data = info;
+ sizes[i].minimum_size = info->requested_width;
+ sizes[i].natural_size = info->natural_width;
- full_requested_width += info->requested_width;
- }
+ if (!first_cell)
+ avail_width -= cellview->priv->spacing;
- extra_space = widget->allocation.width - full_requested_width;
- if (extra_space < 0)
- extra_space = 0;
- else if (extra_space > 0 && expand_cell_count > 0)
- extra_space /= expand_cell_count;
+ avail_width -= sizes[i].minimum_size;
- /* iterate list for PACK_START cells */
- for (i = cellview->priv->cell_list; i; i = i->next)
- {
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
+ first_cell = FALSE;
- if (info->pack == GTK_PACK_END)
- continue;
+ i++;
+ }
- if (!info->cell->visible)
- continue;
+ avail_width = gtk_distribute_natural_allocation (MAX (0, avail_width), n_visible_cells, sizes);
- info->real_width = info->requested_width + (info->expand?extra_space:0);
+ /* Deal with any expand space... */
+ if (n_expand_cells > 0)
+ {
+ extra_per_cell = avail_width / n_expand_cells;
+ extra_extra = avail_width % n_expand_cells;
}
+ else
+ /* Everything just left-aligned if no cells expand */
+ extra_per_cell = extra_extra = 0;
- /* iterate list for PACK_END cells */
- for (i = cellview->priv->cell_list; i; i = i->next)
+ for (i = 0, list = cellview->priv->cell_list; list; list = list->next)
{
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
+ GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
- if (info->pack == GTK_PACK_START)
+ if (!gtk_cell_renderer_get_visible (info->cell))
continue;
- if (!info->cell->visible)
- continue;
+ info->real_width = sizes[i].minimum_size;
+
+ if (info->expand)
+ {
+ info->real_width += extra_per_cell;
- info->real_width = info->requested_width + (info->expand?extra_space:0);
+ if (extra_extra)
+ {
+ info->real_width++;
+ extra_extra--;
+ }
+ }
+
+ /* increment index into sizes for visible children */
+ i++;
}
+
+ g_free (sizes);
}
static gboolean
-gtk_cell_view_expose (GtkWidget *widget,
- GdkEventExpose *event)
+gtk_cell_view_draw (GtkWidget *widget,
+ cairo_t *cr)
{
- GList *i;
+ GList *list;
GtkCellView *cellview;
GdkRectangle area;
GtkCellRendererState state;
gboolean rtl = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL);
+ GtkPackType packing;
+ int width;
cellview = GTK_CELL_VIEW (widget);
- if (! GTK_WIDGET_DRAWABLE (widget))
- return FALSE;
+ /* render cells */
+ area.x = 0;
+ area.y = 0;
+ area.width = width = gtk_widget_get_allocated_width (widget);
+ area.height = gtk_widget_get_allocated_height (widget);
/* "blank" background */
if (cellview->priv->background_set)
{
- cairo_t *cr = gdk_cairo_create (GTK_WIDGET (cellview)->window);
-
- gdk_cairo_rectangle (cr, &widget->allocation);
- cairo_set_source_rgb (cr,
- cellview->priv->background.red / 65535.,
- cellview->priv->background.green / 65535.,
- cellview->priv->background.blue / 65535.);
+ gdk_cairo_rectangle (cr, &area);
+ gdk_cairo_set_source_rgba (cr, &cellview->priv->background);
cairo_fill (cr);
-
- cairo_destroy (cr);
}
/* set cell data (if available) */
else if (cellview->priv->model)
return FALSE;
- /* render cells */
- area = widget->allocation;
-
- /* we draw on our very own window, initialize x and y to zero */
- area.x = widget->allocation.x + (rtl ? widget->allocation.width : 0);
- area.y = widget->allocation.y;
-
- if (GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT)
+ if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
state = GTK_CELL_RENDERER_PRELIT;
+ else if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE)
+ state = GTK_CELL_RENDERER_INSENSITIVE;
else
state = 0;
- /* PACK_START */
- for (i = cellview->priv->cell_list; i; i = i->next)
+ for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
{
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
-
- if (info->pack == GTK_PACK_END)
- continue;
-
- if (!info->cell->visible)
- continue;
+ if (packing == GTK_PACK_START)
+ area.x = rtl ? width : 0;
+ else
+ area.x = rtl ? 0 : width;
- area.width = info->real_width;
- if (rtl)
- area.x -= area.width;
-
- gtk_cell_renderer_render (info->cell,
- event->window,
- widget,
- /* FIXME! */
- &area, &area, &event->area, state);
-
- if (!rtl)
- area.x += info->real_width;
- }
-
- area.x = rtl ? widget->allocation.x : (widget->allocation.x + widget->allocation.width);
-
- /* PACK_END */
- for (i = cellview->priv->cell_list; i; i = i->next)
- {
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
-
- if (info->pack == GTK_PACK_START)
- continue;
-
- if (!info->cell->visible)
- continue;
-
- area.width = info->real_width;
- if (!rtl)
- area.x -= area.width;
-
- gtk_cell_renderer_render (info->cell,
- widget->window,
- widget,
- /* FIXME ! */
- &area, &area, &event->area, state);
- if (rtl)
- area.x += info->real_width;
+ for (list = cellview->priv->cell_list; list; list = list->next)
+ {
+ GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
+
+ if (info->pack != packing)
+ continue;
+
+ if (!gtk_cell_renderer_get_visible (info->cell))
+ continue;
+
+ area.width = info->real_width;
+
+ if ((packing == GTK_PACK_START && rtl) ||
+ (packing == GTK_PACK_END && !rtl))
+ area.x -= area.width;
+
+ gtk_cell_renderer_render (info->cell,
+ cr,
+ widget,
+ /* FIXME! */
+ &area, &area, state);
+
+ if ((packing == GTK_PACK_START && !rtl) ||
+ (packing == GTK_PACK_END && rtl))
+ {
+ area.x += area.width;
+ area.x += cellview->priv->spacing;
+ }
+ else
+ area.x -= cellview->priv->spacing;
+ }
}
return FALSE;
GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- g_return_if_fail (GTK_IS_CELL_VIEW (cellview));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer));
g_object_ref_sink (renderer);
- info = g_new0 (GtkCellViewCellInfo, 1);
+ info = g_slice_new0 (GtkCellViewCellInfo);
info->cell = renderer;
info->expand = expand ? TRUE : FALSE;
info->pack = GTK_PACK_START;
cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info);
+
+ gtk_widget_queue_resize (GTK_WIDGET (cellview));
}
static void
GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- g_return_if_fail (GTK_IS_CELL_VIEW (cellview));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer));
g_object_ref_sink (renderer);
- info = g_new0 (GtkCellViewCellInfo, 1);
+ info = g_slice_new0 (GtkCellViewCellInfo);
info->cell = renderer;
info->expand = expand ? TRUE : FALSE;
info->pack = GTK_PACK_END;
cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info);
+
+ gtk_widget_queue_resize (GTK_WIDGET (cellview));
}
static void
GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- g_return_if_fail (GTK_IS_CELL_VIEW (cellview));
info = gtk_cell_view_get_cell_info (cellview, renderer);
g_return_if_fail (info != NULL);
{
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- g_return_if_fail (GTK_IS_CELL_VIEW (cellview));
-
while (cellview->priv->cell_list)
{
GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)cellview->priv->cell_list->data;
gtk_cell_view_cell_layout_clear_attributes (layout, info->cell);
g_object_unref (info->cell);
- g_free (info);
+ g_slice_free (GtkCellViewCellInfo, info);
cellview->priv->cell_list = g_list_delete_link (cellview->priv->cell_list,
cellview->priv->cell_list);
}
GtkCellView *cellview = GTK_CELL_VIEW (layout);
GtkCellViewCellInfo *info;
- g_return_if_fail (GTK_IS_CELL_VIEW (cellview));
-
info = gtk_cell_view_get_cell_info (cellview, cell);
g_return_if_fail (info != NULL);
gtk_cell_view_cell_layout_clear_attributes (GtkCellLayout *layout,
GtkCellRenderer *renderer)
{
- GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
+ GtkCellViewCellInfo *info;
GSList *list;
- g_return_if_fail (GTK_IS_CELL_VIEW (cellview));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
-
info = gtk_cell_view_get_cell_info (cellview, renderer);
if (info != NULL)
{
GtkCellRenderer *cell,
gint position)
{
- GList *link;
- GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
-
- g_return_if_fail (GTK_IS_CELL_VIEW (cellview));
- g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
+ GtkCellViewCellInfo *info;
+ GList *link;
info = gtk_cell_view_get_cell_info (cellview, cell);
g_return_if_fail (link != NULL);
- cellview->priv->cell_list = g_list_remove_link (cellview->priv->cell_list,
+ cellview->priv->cell_list = g_list_delete_link (cellview->priv->cell_list,
link);
cellview->priv->cell_list = g_list_insert (cellview->priv->cell_list,
info, position);
* @markup: the text to display in the cell view
*
* Creates a new #GtkCellView widget, adds a #GtkCellRendererText
- * to it, and makes its show @markup. The text can text can be
+ * to it, and makes it show @markup. The text can be
* marked up with the <link linkend="PangoMarkupFormat">Pango text
* markup language</link>.
*
gchar *property,
GValue *value)
{
- g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
- g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
-
g_object_set_property (G_OBJECT (renderer), property, value);
/* force resize and redraw */
/**
* gtk_cell_view_set_model:
* @cell_view: a #GtkCellView
- * @model: a #GtkTreeModel
+ * @model: (allow-none): a #GtkTreeModel
*
* Sets the model for @cell_view. If @cell_view already has a model
- * set, it will remove it before setting the new model. If @model is
+ * set, it will remove it before setting the new model. If @model is
* %NULL, then it will unset the old model.
*
* Since: 2.6
g_object_ref (cell_view->priv->model);
}
+/**
+ * gtk_cell_view_get_model:
+ * @cell_view: a #GtkCellView
+ *
+ * Returns the model for @cell_view. If no model is used %NULL is
+ * returned.
+ *
+ * Returns: (transfer none): a #GtkTreeModel used or %NULL
+ *
+ * Since: 2.16
+ **/
+GtkTreeModel *
+gtk_cell_view_get_model (GtkCellView *cell_view)
+{
+ g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), NULL);
+
+ return cell_view->priv->model;
+}
+
/**
* gtk_cell_view_set_displayed_row:
* @cell_view: a #GtkCellView
- * @path: a #GtkTreePath or %NULL to unset.
- *
+ * @path: (allow-none): a #GtkTreePath or %NULL to unset.
+ *
* Sets the row of the model that is currently displayed
* by the #GtkCellView. If the path is unset, then the
* contents of the cellview "stick" at their last value;
* Return value: %TRUE
*
* Since: 2.6
+ *
+ * Deprecated: 3.0: Use gtk_cell_view_get_desired_width_of_row() and
+ * gtk_cell_view_get_desired_height_for_width_of_row() instead.
*/
gboolean
gtk_cell_view_get_size_of_row (GtkCellView *cell_view,
GtkTreePath *path,
GtkRequisition *requisition)
{
- GtkTreeRowReference *tmp;
GtkRequisition req;
g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
- g_return_val_if_fail (requisition != NULL, FALSE);
+
+ /* Return the minimum height for the minimum width */
+ gtk_cell_view_get_desired_width_of_row (cell_view, path, &req.width, NULL);
+ gtk_cell_view_get_desired_height_for_width_of_row (cell_view, path, req.width, &req.height, NULL);
+
+ if (requisition)
+ *requisition = req;
+
+ return TRUE;
+}
+
+
+/**
+ * gtk_cell_view_get_desired_width_of_row:
+ * @cell_view: a #GtkCellView
+ * @path: a #GtkTreePath
+ * @minimum_size: location to store the minimum size
+ * @natural_size: location to store the natural size
+ *
+ * Sets @minimum_size and @natural_size to the width desired by @cell_view
+ * to display the model row pointed to by @path.
+ *
+ * Since: 3.0
+ */
+void
+gtk_cell_view_get_desired_width_of_row (GtkCellView *cell_view,
+ GtkTreePath *path,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkTreeRowReference *tmp;
+
+ g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (minimum_size != NULL || natural_size != NULL);
tmp = cell_view->priv->displayed_row;
cell_view->priv->displayed_row =
gtk_tree_row_reference_new (cell_view->priv->model, path);
- gtk_cell_view_size_request (GTK_WIDGET (cell_view), requisition);
+ gtk_cell_view_get_preferred_width (GTK_WIDGET (cell_view), minimum_size, natural_size);
gtk_tree_row_reference_free (cell_view->priv->displayed_row);
cell_view->priv->displayed_row = tmp;
- /* restore actual size info */
- gtk_cell_view_size_request (GTK_WIDGET (cell_view), &req);
+ /* Restore active size (this will restore the cellrenderer info->width/requested_width's) */
+ gtk_cell_view_get_preferred_width (GTK_WIDGET (cell_view), NULL, NULL);
+}
- return TRUE;
+
+/**
+ * gtk_cell_view_get_desired_height_for_width_of_row:
+ * @cell_view: a #GtkCellView
+ * @path: a #GtkTreePath
+ * @avail_size: available width
+ * @minimum_size: location to store the minimum height
+ * @natural_size: location to store the natural height
+ *
+ * Sets @minimum_size and @natural_size to the height desired by @cell_view
+ * if it were allocated a width of @avail_size to display the model row
+ * pointed to by @path.
+ *
+ * Since: 3.0
+ */
+void
+gtk_cell_view_get_desired_height_for_width_of_row (GtkCellView *cell_view,
+ GtkTreePath *path,
+ gint avail_size,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkTreeRowReference *tmp;
+
+ g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
+ g_return_if_fail (path != NULL);
+ g_return_if_fail (minimum_size != NULL || natural_size != NULL);
+
+ tmp = cell_view->priv->displayed_row;
+ cell_view->priv->displayed_row =
+ gtk_tree_row_reference_new (cell_view->priv->model, path);
+
+ /* Then get the collective height_for_width based on the cached values */
+ gtk_cell_view_get_preferred_height_for_width (GTK_WIDGET (cell_view), avail_size, minimum_size, natural_size);
+
+ gtk_tree_row_reference_free (cell_view->priv->displayed_row);
+ cell_view->priv->displayed_row = tmp;
+
+ /* Restore active size (this will restore the cellrenderer info->width/requested_width's) */
+ gtk_cell_view_get_preferred_width (GTK_WIDGET (cell_view), NULL, NULL);
}
/**
g_object_notify (G_OBJECT (cell_view), "background-set");
}
- cell_view->priv->background = *color;
+ cell_view->priv->background.red = color->red / 65535.;
+ cell_view->priv->background.green = color->green / 65535.;
+ cell_view->priv->background.blue = color->blue / 65535.;
+ cell_view->priv->background.alpha = 1;
}
else
{
}
/**
- * gtk_cell_view_get_cell_renderers:
+ * gtk_cell_view_set_background_rgba:
* @cell_view: a #GtkCellView
- *
- * Returns the cell renderers which have been added to @cell_view.
+ * @rgba: the new background color
*
- * Return value: a list of cell renderers. The list, but not the
- * renderers has been newly allocated and should be freed with
- * g_list_free() when no longer needed.
- *
- * Since: 2.6
+ * Sets the background color of @cell_view.
+ *
+ * Since: 3.0
*/
-GList *
-gtk_cell_view_get_cell_renderers (GtkCellView *cell_view)
+void
+gtk_cell_view_set_background_rgba (GtkCellView *cell_view,
+ const GdkRGBA *rgba)
{
+ g_return_if_fail (GTK_IS_CELL_VIEW (cell_view));
+
+ if (rgba)
+ {
+ if (!cell_view->priv->background_set)
+ {
+ cell_view->priv->background_set = TRUE;
+ g_object_notify (G_OBJECT (cell_view), "background-set");
+ }
+
+ cell_view->priv->background = *rgba;
+ }
+ else
+ {
+ if (cell_view->priv->background_set)
+ {
+ cell_view->priv->background_set = FALSE;
+ g_object_notify (G_OBJECT (cell_view), "background-set");
+ }
+ }
+
+ gtk_widget_queue_draw (GTK_WIDGET (cell_view));
+}
+
+static GList *
+gtk_cell_view_cell_layout_get_cells (GtkCellLayout *layout)
+{
+ GtkCellView *cell_view = GTK_CELL_VIEW (layout);
GList *retval = NULL, *list;
g_return_val_if_fail (cell_view != NULL, NULL);
return g_list_reverse (retval);
}
-#define __GTK_CELL_VIEW_C__
-#include "gtkaliasdef.c"
+static gboolean
+gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data)
+{
+ if (parent_buildable_iface->custom_tag_start &&
+ parent_buildable_iface->custom_tag_start (buildable, builder, child,
+ tagname, parser, data))
+ return TRUE;
+
+ return _gtk_cell_layout_buildable_custom_tag_start (buildable, builder, child,
+ tagname, parser, data);
+}
+
+static void
+gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer *data)
+{
+ if (strcmp (tagname, "attributes") == 0)
+ _gtk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname,
+ data);
+ else if (parent_buildable_iface->custom_tag_end)
+ parent_buildable_iface->custom_tag_end (buildable, builder, child, tagname,
+ data);
+}
+
+static void
+gtk_cell_view_get_preferred_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GList *list;
+ gint cell_min, cell_nat;
+ gboolean first_cell = TRUE;
+ GtkCellView *cellview = GTK_CELL_VIEW (widget);
+ gint minimum, natural;
+
+ minimum = natural = 0;
+
+ if (cellview->priv->displayed_row)
+ gtk_cell_view_set_cell_data (cellview);
+
+ for (list = cellview->priv->cell_list; list; list = list->next)
+ {
+ GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
+
+ if (gtk_cell_renderer_get_visible (info->cell))
+ {
+
+ if (!first_cell)
+ {
+ minimum += cellview->priv->spacing;
+ natural += cellview->priv->spacing;
+ }
+
+ gtk_cell_renderer_get_preferred_width (info->cell,
+ GTK_WIDGET (cellview), &cell_min, &cell_nat);
+
+ info->requested_width = cell_min;
+ info->natural_width = cell_nat;
+
+ minimum += info->requested_width;
+ natural += info->natural_width;
+
+ first_cell = FALSE;
+ }
+ }
+
+ if (minimum_size)
+ *minimum_size = minimum;
+
+ if (natural_size)
+ *natural_size = natural;
+}
+
+static void
+gtk_cell_view_get_preferred_height (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ gint minimum_width;
+
+ /* CellViews only need to respond to height-for-width mode (cellview is pretty much
+ * an implementation detail of GtkComboBox) */
+ gtk_cell_view_get_preferred_width (widget, &minimum_width, NULL);
+ gtk_cell_view_get_preferred_height_for_width (widget, minimum_width, minimum_size, natural_size);
+}
+
+static void
+gtk_cell_view_get_preferred_width_for_height (GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ /* CellViews only need to respond to height-for-width mode (cellview is pretty much
+ * an implementation detail of GtkComboBox) */
+ gtk_cell_view_get_preferred_width (widget, minimum_size, natural_size);
+}
+
+static void
+gtk_cell_view_get_preferred_height_for_width (GtkWidget *widget,
+ gint for_size,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkCellView *cellview = GTK_CELL_VIEW (widget);
+ GList *list;
+ GtkRequestedSize *sizes;
+ GArray *array;
+ gint minimum, natural, avail_size;
+ gboolean first_cell = TRUE;
+ gint n_expand_cells = 0;
+ gint extra_per_cell, extra_extra, i;
+
+ minimum = natural = 0;
+ avail_size = for_size;
+
+ array = g_array_new (0, TRUE, sizeof (GtkRequestedSize));
+
+ if (cellview->priv->displayed_row)
+ gtk_cell_view_set_cell_data (cellview);
+
+ /* First allocate the right width to all cells */
+ for (list = cellview->priv->cell_list; list; list = list->next)
+ {
+ GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
+
+ if (gtk_cell_renderer_get_visible (info->cell))
+ {
+ GtkRequestedSize requested;
+
+ gtk_cell_renderer_get_preferred_width (GTK_CELL_RENDERER (info->cell),
+ GTK_WIDGET (cellview),
+ &requested.minimum_size,
+ &requested.natural_size);
+
+ requested.data = info;
+ g_array_append_val (array, requested);
+
+ avail_size -= requested.minimum_size;
+
+ if (!first_cell)
+ avail_size -= cellview->priv->spacing;
+
+ first_cell = FALSE;
+
+ if (info->expand)
+ n_expand_cells++;
+ }
+ }
+
+ sizes = (GtkRequestedSize *)array->data;
+ avail_size = gtk_distribute_natural_allocation (MAX (0, avail_size), array->len, sizes);
+
+ /* Deal with any expand space... */
+ if (n_expand_cells > 0)
+ {
+ extra_per_cell = avail_size / n_expand_cells;
+ extra_extra = avail_size % n_expand_cells;
+ }
+ else
+ /* Everything just left-aligned if no cells expand */
+ extra_per_cell = extra_extra = 0;
+
+ /* Now get the height for the real width of each cell */
+ for (i = 0, list = cellview->priv->cell_list; list; list = list->next)
+ {
+ GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
+ gint cell_minimum, cell_natural;
+
+ if (gtk_cell_renderer_get_visible (info->cell))
+ {
+ gint cell_width = sizes[i].minimum_size;
+
+ g_assert (sizes[i].data == info);
+
+ if (info->expand)
+ {
+ cell_width += extra_per_cell;
+ if (extra_extra)
+ {
+ cell_width++;
+ extra_extra--;
+ }
+ }
+
+ /* Get the height for the real width of this cell */
+ gtk_cell_renderer_get_preferred_height_for_width (GTK_CELL_RENDERER (info->cell),
+ GTK_WIDGET (widget),
+ cell_width, &cell_minimum, &cell_natural);
+
+ minimum = MAX (minimum, cell_minimum);
+ natural = MAX (natural, cell_natural);
+
+ /* increment sizes[] index for visible cells */
+ i++;
+ }
+ }
+
+ g_array_free (array, TRUE);
+
+ if (minimum_size)
+ *minimum_size = minimum;
+ if (natural_size)
+ *natural_size = natural;
+}