summaryrefslogtreecommitdiff
path: root/gtk/gtkcellview.c
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.van.berkom@gmail.com>2010-11-18 13:53:55 +0900
committerTristan Van Berkom <tristan.van.berkom@gmail.com>2011-01-04 23:37:05 +0900
commitb70589b6a401efa84982333e71e489a36d02a070 (patch)
tree65e250c499ae5080003d6062af39b87fb9de1499 /gtk/gtkcellview.c
parent58cdd6d38eb6b976c2792ca435c2731f16f8924b (diff)
downloadgtk+-b70589b6a401efa84982333e71e489a36d02a070.tar.gz
Reimplemented GtkCellView using an internal GtkCellArea.
Added construct GtkCellArea and GtkCellAreaContext properties, the context property allows putting multiple cellviews into the same size request context.
Diffstat (limited to 'gtk/gtkcellview.c')
-rw-r--r--gtk/gtkcellview.c632
1 files changed, 189 insertions, 443 deletions
diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c
index c5a65236d3..203665afce 100644
--- a/gtk/gtkcellview.c
+++ b/gtk/gtkcellview.c
@@ -21,6 +21,8 @@
#include <string.h>
#include "gtkcellview.h"
#include "gtkcelllayout.h"
+#include "gtkcellareacontext.h"
+#include "gtkcellareabox.h"
#include "gtkintl.h"
#include "gtkcellrenderertext.h"
#include "gtkcellrendererpixbuf.h"
@@ -41,39 +43,23 @@
* and drag and drop.
*/
-
-
-typedef struct _GtkCellViewCellInfo GtkCellViewCellInfo;
-struct _GtkCellViewCellInfo
-{
- GtkCellRenderer *cell;
-
- gint requested_width;
- gint natural_width;
- gint real_width;
- guint expand : 1;
- guint pack : 1;
-
- GSList *attributes;
-
- GtkCellLayoutDataFunc func;
- gpointer func_data;
- GDestroyNotify destroy;
-};
-
struct _GtkCellViewPrivate
{
- GtkTreeModel *model;
+ GtkTreeModel *model;
GtkTreeRowReference *displayed_row;
- GList *cell_list;
- gint spacing;
- GdkRGBA background;
- gboolean background_set;
+ GtkCellArea *cell_area;
+ GtkCellAreaContext *cell_area_context;
+
+ GdkRGBA background;
+ gboolean background_set;
};
static void gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface);
+static GObject *gtk_cell_view_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties);
static void gtk_cell_view_get_property (GObject *object,
guint param_id,
GValue *value,
@@ -83,6 +69,7 @@ static void gtk_cell_view_set_property (GObject *obj
const GValue *value,
GParamSpec *pspec);
static void gtk_cell_view_finalize (GObject *object);
+static void gtk_cell_view_dispose (GObject *object);
static void gtk_cell_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean gtk_cell_view_draw (GtkWidget *widget,
@@ -91,8 +78,6 @@ static void gtk_cell_view_set_value (GtkCellView *cell
GtkCellRenderer *renderer,
gchar *property,
GValue *value);
-static GtkCellViewCellInfo *gtk_cell_view_get_cell_info (GtkCellView *cellview,
- GtkCellRenderer *renderer);
static void gtk_cell_view_set_cell_data (GtkCellView *cell_view);
@@ -118,6 +103,7 @@ static void gtk_cell_view_cell_layout_reorder (GtkCellLayout
GtkCellRenderer *cell,
gint position);
static GList * gtk_cell_view_cell_layout_get_cells (GtkCellLayout *layout);
+static GtkCellArea *gtk_cell_view_cell_layout_get_area (GtkCellLayout *layout);
/* buildable */
static void gtk_cell_view_buildable_init (GtkBuildableIface *iface);
@@ -150,7 +136,6 @@ static void gtk_cell_view_get_preferred_height_for_width (GtkWidget
static GtkBuildableIface *parent_buildable_iface;
-
enum
{
PROP_0,
@@ -158,7 +143,9 @@ enum
PROP_BACKGROUND_GDK,
PROP_BACKGROUND_RGBA,
PROP_BACKGROUND_SET,
- PROP_MODEL
+ PROP_MODEL,
+ PROP_CELL_AREA,
+ PROP_CELL_AREA_CONTEXT
};
G_DEFINE_TYPE_WITH_CODE (GtkCellView, gtk_cell_view, GTK_TYPE_WIDGET,
@@ -174,9 +161,11 @@ gtk_cell_view_class_init (GtkCellViewClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ gobject_class->constructor = gtk_cell_view_constructor;
gobject_class->get_property = gtk_cell_view_get_property;
gobject_class->set_property = gtk_cell_view_set_property;
gobject_class->finalize = gtk_cell_view_finalize;
+ gobject_class->dispose = gtk_cell_view_dispose;
widget_class->draw = gtk_cell_view_draw;
widget_class->size_allocate = gtk_cell_view_size_allocate;
@@ -229,6 +218,39 @@ gtk_cell_view_class_init (GtkCellViewClass *klass)
P_("The model for cell view"),
GTK_TYPE_TREE_MODEL,
GTK_PARAM_READWRITE));
+
+
+ /**
+ * GtkCellView:cell-area
+ *
+ * The #GtkCellArea rendering cells
+ *
+ * since 3.0
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CELL_AREA,
+ g_param_spec_object ("cell-area",
+ P_("Cell Area"),
+ P_("The GtkCellArea used to layout cells"),
+ GTK_TYPE_CELL_AREA,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * GtkCellView:cell-area-context
+ *
+ * The #GtkCellAreaContext used to compute the geometry of the cell view.
+ *
+ * since 3.0
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CELL_AREA,
+ g_param_spec_object ("cell-area-context",
+ P_("Cell Area Context"),
+ P_("The GtkCellAreaContext used to "
+ "compute the geometry of the cell view"),
+ GTK_TYPE_CELL_AREA_CONTEXT,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
#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))
@@ -259,6 +281,35 @@ gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface)
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;
+ iface->get_area = gtk_cell_view_cell_layout_get_area;
+}
+
+static GObject *
+gtk_cell_view_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *object;
+ GtkCellView *view;
+ GtkCellViewPrivate *priv;
+
+ object = G_OBJECT_CLASS (gtk_cell_view_parent_class)->constructor
+ (type, n_construct_properties, construct_properties);
+
+ view = GTK_CELL_VIEW (object);
+ priv = view->priv;
+
+ if (!priv->cell_area)
+ {
+ GtkCellArea *area = gtk_cell_area_box_new ();
+
+ priv->cell_area = g_object_ref_sink (area);
+ }
+
+ if (!priv->cell_area_context)
+ priv->cell_area_context = gtk_cell_area_create_context (priv->cell_area);
+
+ return object;
}
static void
@@ -292,6 +343,12 @@ gtk_cell_view_get_property (GObject *object,
case PROP_MODEL:
g_value_set_object (value, view->priv->model);
break;
+ case PROP_CELL_AREA:
+ g_value_set_object (value, view->priv->cell_area);
+ break;
+ case PROP_CELL_AREA_CONTEXT:
+ g_value_set_object (value, view->priv->cell_area_context);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -305,6 +362,8 @@ gtk_cell_view_set_property (GObject *object,
GParamSpec *pspec)
{
GtkCellView *view = GTK_CELL_VIEW (object);
+ GtkCellArea *area;
+ GtkCellAreaContext *context;
switch (param_id)
{
@@ -334,6 +393,21 @@ gtk_cell_view_set_property (GObject *object,
case PROP_MODEL:
gtk_cell_view_set_model (view, g_value_get_object (value));
break;
+ case PROP_CELL_AREA:
+ /* Construct-only, can only be assigned once */
+ area = g_value_get_object (value);
+
+ if (area)
+ view->priv->cell_area = g_object_ref_sink (area);
+ break;
+ case PROP_CELL_AREA_CONTEXT:
+ /* Construct-only, can only be assigned once */
+ context = g_value_get_object (value);
+
+ if (context)
+ view->priv->cell_area_context = g_object_ref (context);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -358,11 +432,6 @@ gtk_cell_view_finalize (GObject *object)
{
GtkCellView *cellview = GTK_CELL_VIEW (object);
- gtk_cell_view_cell_layout_clear (GTK_CELL_LAYOUT (cellview));
-
- if (cellview->priv->model)
- g_object_unref (cellview->priv->model);
-
if (cellview->priv->displayed_row)
gtk_tree_row_reference_free (cellview->priv->displayed_row);
@@ -370,116 +439,70 @@ gtk_cell_view_finalize (GObject *object)
}
static void
-gtk_cell_view_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
+gtk_cell_view_dispose (GObject *object)
{
- 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;
-
- gtk_widget_set_allocation (widget, allocation);
-
- cellview = GTK_CELL_VIEW (widget);
+ GtkCellView *cellview = GTK_CELL_VIEW (object);
- avail_width = allocation->width;
+ gtk_cell_view_cell_layout_clear (GTK_CELL_LAYOUT (cellview));
- /* Count visible/expand children */
- for (n_visible_cells = 0, n_expand_cells = 0, list = cellview->priv->cell_list;
- list; list = list->next)
+ if (cellview->priv->model)
{
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
-
- n_visible_cells++;
-
- if (info->expand)
- n_expand_cells++;
+ g_object_unref (cellview->priv->model);
+ cellview->priv->model = NULL;
}
- sizes = g_new0 (GtkRequestedSize, n_visible_cells);
-
- /* checking how much extra space we have */
- for (i = 0, list = cellview->priv->cell_list; list; list = list->next)
+ if (cellview->priv->cell_area)
{
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
-
- if (!gtk_cell_renderer_get_visible (info->cell))
- continue;
-
- sizes[i].data = info;
- sizes[i].minimum_size = info->requested_width;
- sizes[i].natural_size = info->natural_width;
-
- if (!first_cell)
- avail_width -= cellview->priv->spacing;
-
- avail_width -= sizes[i].minimum_size;
-
- first_cell = FALSE;
-
- i++;
+ g_object_unref (cellview->priv->cell_area);
+ cellview->priv->cell_area = NULL;
}
- avail_width = gtk_distribute_natural_allocation (MAX (0, avail_width), n_visible_cells, sizes);
-
- /* Deal with any expand space... */
- if (n_expand_cells > 0)
+ if (cellview->priv->cell_area_context)
{
- extra_per_cell = avail_width / n_expand_cells;
- extra_extra = avail_width % n_expand_cells;
+ g_object_unref (cellview->priv->cell_area_context);
+ cellview->priv->cell_area_context = NULL;
}
- else
- /* Everything just left-aligned if no cells expand */
- extra_per_cell = extra_extra = 0;
- for (i = 0, list = cellview->priv->cell_list; list; list = list->next)
- {
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
+ G_OBJECT_CLASS (gtk_cell_view_parent_class)->dispose (object);
+}
- if (!gtk_cell_renderer_get_visible (info->cell))
- continue;
+static void
+gtk_cell_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkCellView *cellview = GTK_CELL_VIEW (widget);
+ GtkCellViewPrivate *priv = cellview->priv;
+ gint alloc_width, alloc_height;
- info->real_width = sizes[i].minimum_size;
+ gtk_widget_set_allocation (widget, allocation);
- if (info->expand)
- {
- info->real_width += extra_per_cell;
-
- if (extra_extra)
- {
- info->real_width++;
- extra_extra--;
- }
- }
-
- /* increment index into sizes for visible children */
- i++;
- }
+ gtk_cell_area_context_get_allocation (priv->cell_area_context, &alloc_width, &alloc_height);
- g_free (sizes);
+ /* Only allocate the GtkCellAreaContext if it has not been done for us by
+ * another widget (i.e. GtkTreeMenu)... in this case we assume that
+ * we own our GtkCellArea and GtkCellAreaContext and they are not shared with
+ * other cell views. */
+ if (alloc_width <= 0 && alloc_height <= 0)
+ {
+ gtk_cell_area_context_allocate_width (priv->cell_area_context, allocation->width);
+ gtk_cell_area_context_allocate_height (priv->cell_area_context, allocation->height);
+ }
}
static gboolean
gtk_cell_view_draw (GtkWidget *widget,
cairo_t *cr)
{
- 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);
/* render cells */
area.x = 0;
area.y = 0;
- area.width = width = gtk_widget_get_allocated_width (widget);
+ area.width = gtk_widget_get_allocated_width (widget);
area.height = gtk_widget_get_allocated_height (widget);
/* "blank" background */
@@ -503,70 +526,16 @@ gtk_cell_view_draw (GtkWidget *widget,
else
state = 0;
- for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
- {
- if (packing == GTK_PACK_START)
- area.x = rtl ? width : 0;
- else
- area.x = rtl ? 0 : 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;
- }
- }
+ /* Render the cells */
+ gtk_cell_area_render (cellview->priv->cell_area, cellview->priv->cell_area_context,
+ widget, cr, &area, &area, state, FALSE);
return FALSE;
}
-static GtkCellViewCellInfo *
-gtk_cell_view_get_cell_info (GtkCellView *cellview,
- GtkCellRenderer *renderer)
-{
- GList *i;
-
- for (i = cellview->priv->cell_list; i; i = i->next)
- {
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
-
- if (info->cell == renderer)
- return info;
- }
-
- return NULL;
-}
-
static void
gtk_cell_view_set_cell_data (GtkCellView *cell_view)
{
- GList *i;
GtkTreeIter iter;
GtkTreePath *path;
@@ -579,35 +548,9 @@ gtk_cell_view_set_cell_data (GtkCellView *cell_view)
gtk_tree_model_get_iter (cell_view->priv->model, &iter, path);
gtk_tree_path_free (path);
- for (i = cell_view->priv->cell_list; i; i = i->next)
- {
- GSList *j;
- GtkCellViewCellInfo *info = i->data;
-
- g_object_freeze_notify (G_OBJECT (info->cell));
-
- for (j = info->attributes; j && j->next; j = j->next->next)
- {
- gchar *property = j->data;
- gint column = GPOINTER_TO_INT (j->next->data);
- GValue value = {0, };
-
- gtk_tree_model_get_value (cell_view->priv->model, &iter,
- column, &value);
- g_object_set_property (G_OBJECT (info->cell),
- property, &value);
- g_value_unset (&value);
- }
-
- if (info->func)
- (* info->func) (GTK_CELL_LAYOUT (cell_view),
- info->cell,
- cell_view->priv->model,
- &iter,
- info->func_data);
-
- g_object_thaw_notify (G_OBJECT (info->cell));
- }
+ gtk_cell_area_apply_attributes (cell_view->priv->cell_area,
+ cell_view->priv->model,
+ &iter, FALSE, FALSE);
}
/* GtkCellLayout implementation */
@@ -616,19 +559,9 @@ gtk_cell_view_cell_layout_pack_start (GtkCellLayout *layout,
GtkCellRenderer *renderer,
gboolean expand)
{
- GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer));
-
- g_object_ref_sink (renderer);
-
- 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_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview->priv->cell_area), renderer, expand);
gtk_widget_queue_resize (GTK_WIDGET (cellview));
}
@@ -638,19 +571,9 @@ gtk_cell_view_cell_layout_pack_end (GtkCellLayout *layout,
GtkCellRenderer *renderer,
gboolean expand)
{
- GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer));
-
- g_object_ref_sink (renderer);
-
- 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_cell_layout_pack_end (GTK_CELL_LAYOUT (cellview->priv->cell_area), renderer, expand);
gtk_widget_queue_resize (GTK_WIDGET (cellview));
}
@@ -661,16 +584,10 @@ gtk_cell_view_cell_layout_add_attribute (GtkCellLayout *layout,
const gchar *attribute,
gint column)
{
- GtkCellViewCellInfo *info;
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- info = gtk_cell_view_get_cell_info (cellview, renderer);
- g_return_if_fail (info != NULL);
-
- info->attributes = g_slist_prepend (info->attributes,
- GINT_TO_POINTER (column));
- info->attributes = g_slist_prepend (info->attributes,
- g_strdup (attribute));
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (cellview->priv->cell_area), renderer,
+ attribute, column);
}
static void
@@ -678,16 +595,8 @@ gtk_cell_view_cell_layout_clear (GtkCellLayout *layout)
{
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- 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_slice_free (GtkCellViewCellInfo, info);
- cellview->priv->cell_list = g_list_delete_link (cellview->priv->cell_list,
- cellview->priv->cell_list);
- }
+ if (cellview->priv->cell_area)
+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (cellview->priv->cell_area));
}
static void
@@ -698,22 +607,9 @@ gtk_cell_view_cell_layout_set_cell_data_func (GtkCellLayout *layout,
GDestroyNotify destroy)
{
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- GtkCellViewCellInfo *info;
-
- info = gtk_cell_view_get_cell_info (cellview, cell);
- g_return_if_fail (info != NULL);
-
- if (info->destroy)
- {
- GDestroyNotify d = info->destroy;
-
- info->destroy = NULL;
- d (info->func_data);
- }
- info->func = func;
- info->func_data = func_data;
- info->destroy = destroy;
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (cellview->priv->cell_area),
+ cell, func, func_data, destroy);
}
static void
@@ -721,22 +617,8 @@ gtk_cell_view_cell_layout_clear_attributes (GtkCellLayout *layout,
GtkCellRenderer *renderer)
{
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- GtkCellViewCellInfo *info;
- GSList *list;
- info = gtk_cell_view_get_cell_info (cellview, renderer);
- if (info != NULL)
- {
- list = info->attributes;
- while (list && list->next)
- {
- g_free (list->data);
- list = list->next->next;
- }
-
- g_slist_free (info->attributes);
- info->attributes = NULL;
- }
+ gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (cellview->priv->cell_area), renderer);
}
static void
@@ -745,24 +627,25 @@ gtk_cell_view_cell_layout_reorder (GtkCellLayout *layout,
gint position)
{
GtkCellView *cellview = GTK_CELL_VIEW (layout);
- GtkCellViewCellInfo *info;
- GList *link;
- info = gtk_cell_view_get_cell_info (cellview, cell);
+ gtk_cell_layout_reorder (GTK_CELL_LAYOUT (cellview->priv->cell_area), cell, position);
+}
- g_return_if_fail (info != NULL);
- g_return_if_fail (position >= 0);
- link = g_list_find (cellview->priv->cell_list, info);
+static GList *
+gtk_cell_view_cell_layout_get_cells (GtkCellLayout *layout)
+{
+ GtkCellView *cellview = GTK_CELL_VIEW (layout);
- g_return_if_fail (link != NULL);
+ return gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cellview->priv->cell_area));
+}
- 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);
+static GtkCellArea *
+gtk_cell_view_cell_layout_get_area (GtkCellLayout *layout)
+{
+ GtkCellView *cellview = GTK_CELL_VIEW (layout);
- gtk_widget_queue_draw (GTK_WIDGET (cellview));
+ return cellview->priv->cell_area;
}
/**
@@ -1213,26 +1096,6 @@ gtk_cell_view_set_background_rgba (GtkCellView *cell_view,
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);
-
- gtk_cell_view_set_cell_data (cell_view);
-
- for (list = cell_view->priv->cell_list; list; list = list->next)
- {
- GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
-
- retval = g_list_prepend (retval, info->cell);
- }
-
- return g_list_reverse (retval);
-}
-
static gboolean
gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
@@ -1270,48 +1133,15 @@ 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;
+ GtkCellView *cellview = GTK_CELL_VIEW (widget);
+ GtkCellViewPrivate *priv = cellview->priv;
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;
+ gtk_cell_area_get_preferred_width (priv->cell_area, priv->cell_area_context, widget, NULL, NULL);
+ gtk_cell_area_context_sum_preferred_width (priv->cell_area_context);
+ gtk_cell_area_context_get_preferred_width (priv->cell_area_context, minimum_size, natural_size);
}
static void
@@ -1319,12 +1149,15 @@ gtk_cell_view_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- gint minimum_width;
+ GtkCellView *cellview = GTK_CELL_VIEW (widget);
+ GtkCellViewPrivate *priv = cellview->priv;
+
+ if (cellview->priv->displayed_row)
+ gtk_cell_view_set_cell_data (cellview);
- /* 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);
+ gtk_cell_area_get_preferred_height (priv->cell_area, priv->cell_area_context, widget, NULL, NULL);
+ gtk_cell_area_context_sum_preferred_height (priv->cell_area_context);
+ gtk_cell_area_context_get_preferred_height (priv->cell_area_context, minimum_size, natural_size);
}
static void
@@ -1333,9 +1166,14 @@ gtk_cell_view_get_preferred_width_for_height (GtkWidget *widget,
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);
+ GtkCellView *cellview = GTK_CELL_VIEW (widget);
+ GtkCellViewPrivate *priv = cellview->priv;
+
+ if (cellview->priv->displayed_row)
+ gtk_cell_view_set_cell_data (cellview);
+
+ gtk_cell_area_get_preferred_width_for_height (priv->cell_area, priv->cell_area_context, widget,
+ for_size, minimum_size, natural_size);
}
static void
@@ -1344,104 +1182,12 @@ gtk_cell_view_get_preferred_height_for_width (GtkWidget *widget,
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));
+ GtkCellView *cellview = GTK_CELL_VIEW (widget);
+ GtkCellViewPrivate *priv = cellview->priv;
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;
+ gtk_cell_area_get_preferred_height_for_width (priv->cell_area, priv->cell_area_context, widget,
+ for_size, minimum_size, natural_size);
}