Commit 9c4eb3d4 authored by Tristan Van Berkom's avatar Tristan Van Berkom

Changed GtkCellArea margin-left/right... for cell-margin-left/right...

The rationale here is that every cell in an area needs to have space
reserved around it, requests have to be fully margin inclusive...
cells need to have the full size fed as the "background area" and
the "cell area" has margins removed... This will be used by GtkTreeViewColumn
to set the focus line width so that cells can paint a background on the
full background, then render themselves into the cell area... and parents
can go ahead and draw focus and other indicators on the background area
but outside of the cell area.
parent 163c3c88
......@@ -122,7 +122,7 @@ struct _GtkCellAreaPrivate
{
GHashTable *cell_info;
GtkBorder border;
GtkBorder cell_border;
};
/* Keep the paramspec pool internal, no need to deliver notifications
......@@ -134,10 +134,10 @@ static GParamSpecPool *cell_property_pool = NULL;
enum {
PROP_0,
PROP_MARGIN_LEFT,
PROP_MARGIN_RIGHT,
PROP_MARGIN_TOP,
PROP_MARGIN_BOTTOM
PROP_CELL_MARGIN_LEFT,
PROP_CELL_MARGIN_RIGHT,
PROP_CELL_MARGIN_TOP,
PROP_CELL_MARGIN_BOTTOM
};
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkCellArea, gtk_cell_area, G_TYPE_INITIALLY_UNOWNED,
......@@ -159,10 +159,10 @@ gtk_cell_area_init (GtkCellArea *area)
NULL,
(GDestroyNotify)cell_info_free);
priv->border.left = 0;
priv->border.right = 0;
priv->border.top = 0;
priv->border.bottom = 0;
priv->cell_border.left = 0;
priv->cell_border.right = 0;
priv->cell_border.top = 0;
priv->cell_border.bottom = 0;
}
static void
......@@ -193,44 +193,48 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
/* Properties */
g_object_class_install_property (object_class,
PROP_MARGIN_LEFT,
g_param_spec_int ("margin-left",
P_("Margin on Left"),
P_("Pixels of extra space on the left side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
PROP_CELL_MARGIN_LEFT,
g_param_spec_int
("cell-margin-left",
P_("Margin on Left"),
P_("Pixels of extra space on the left side of each cell"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_MARGIN_RIGHT,
g_param_spec_int ("margin-right",
P_("Margin on Right"),
P_("Pixels of extra space on the right side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
PROP_CELL_MARGIN_RIGHT,
g_param_spec_int
("cell-margin-right",
P_("Margin on Right"),
P_("Pixels of extra space on the right side of each cell"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_MARGIN_TOP,
g_param_spec_int ("margin-top",
P_("Margin on Top"),
P_("Pixels of extra space on the top side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
PROP_CELL_MARGIN_TOP,
g_param_spec_int
("cell-margin-top",
P_("Margin on Top"),
P_("Pixels of extra space on the top side of each cell"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_MARGIN_BOTTOM,
g_param_spec_int ("margin-bottom",
P_("Margin on Bottom"),
P_("Pixels of extra space on the bottom side"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
PROP_CELL_MARGIN_BOTTOM,
g_param_spec_int
("cell-margin-bottom",
P_("Margin on Bottom"),
P_("Pixels of extra space on the bottom side of each cell"),
0,
G_MAXINT16,
0,
GTK_PARAM_READWRITE));
/* Pool for Cell Properties */
if (!cell_property_pool)
......@@ -349,17 +353,17 @@ gtk_cell_area_set_property (GObject *object,
switch (prop_id)
{
case PROP_MARGIN_LEFT:
gtk_cell_area_set_margin_left (area, g_value_get_int (value));
case PROP_CELL_MARGIN_LEFT:
gtk_cell_area_set_cell_margin_left (area, g_value_get_int (value));
break;
case PROP_MARGIN_RIGHT:
gtk_cell_area_set_margin_right (area, g_value_get_int (value));
case PROP_CELL_MARGIN_RIGHT:
gtk_cell_area_set_cell_margin_right (area, g_value_get_int (value));
break;
case PROP_MARGIN_TOP:
gtk_cell_area_set_margin_top (area, g_value_get_int (value));
case PROP_CELL_MARGIN_TOP:
gtk_cell_area_set_cell_margin_top (area, g_value_get_int (value));
break;
case PROP_MARGIN_BOTTOM:
gtk_cell_area_set_margin_bottom (area, g_value_get_int (value));
case PROP_CELL_MARGIN_BOTTOM:
gtk_cell_area_set_cell_margin_bottom (area, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -378,17 +382,17 @@ gtk_cell_area_get_property (GObject *object,
switch (prop_id)
{
case PROP_MARGIN_LEFT:
g_value_set_int (value, priv->border.left);
case PROP_CELL_MARGIN_LEFT:
g_value_set_int (value, priv->cell_border.left);
break;
case PROP_MARGIN_RIGHT:
g_value_set_int (value, priv->border.right);
case PROP_CELL_MARGIN_RIGHT:
g_value_set_int (value, priv->cell_border.right);
break;
case PROP_MARGIN_TOP:
g_value_set_int (value, priv->border.top);
case PROP_CELL_MARGIN_TOP:
g_value_set_int (value, priv->cell_border.top);
break;
case PROP_MARGIN_BOTTOM:
g_value_set_int (value, priv->border.bottom);
case PROP_CELL_MARGIN_BOTTOM:
g_value_set_int (value, priv->cell_border.bottom);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -1268,16 +1272,16 @@ gtk_cell_area_cell_get_property (GtkCellArea *area,
/* Margins */
gint
gtk_cell_area_get_margin_left (GtkCellArea *area)
gtk_cell_area_get_cell_margin_left (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
return area->priv->border.left;
return area->priv->cell_border.left;
}
void
gtk_cell_area_set_margin_left (GtkCellArea *area,
gint margin)
gtk_cell_area_set_cell_margin_left (GtkCellArea *area,
gint margin)
{
GtkCellAreaPrivate *priv;
......@@ -1285,25 +1289,25 @@ gtk_cell_area_set_margin_left (GtkCellArea *area,
priv = area->priv;
if (priv->border.left != margin)
if (priv->cell_border.left != margin)
{
priv->border.left = margin;
priv->cell_border.left = margin;
g_object_notify (G_OBJECT (area), "margin-left");
}
}
gint
gtk_cell_area_get_margin_right (GtkCellArea *area)
gtk_cell_area_get_cell_margin_right (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
return area->priv->border.right;
return area->priv->cell_border.right;
}
void
gtk_cell_area_set_margin_right (GtkCellArea *area,
gint margin)
gtk_cell_area_set_cell_margin_right (GtkCellArea *area,
gint margin)
{
GtkCellAreaPrivate *priv;
......@@ -1311,25 +1315,25 @@ gtk_cell_area_set_margin_right (GtkCellArea *area,
priv = area->priv;
if (priv->border.right != margin)
if (priv->cell_border.right != margin)
{
priv->border.right = margin;
priv->cell_border.right = margin;
g_object_notify (G_OBJECT (area), "margin-right");
}
}
gint
gtk_cell_area_get_margin_top (GtkCellArea *area)
gtk_cell_area_get_cell_margin_top (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
return area->priv->border.top;
return area->priv->cell_border.top;
}
void
gtk_cell_area_set_margin_top (GtkCellArea *area,
gint margin)
gtk_cell_area_set_cell_margin_top (GtkCellArea *area,
gint margin)
{
GtkCellAreaPrivate *priv;
......@@ -1337,25 +1341,25 @@ gtk_cell_area_set_margin_top (GtkCellArea *area,
priv = area->priv;
if (priv->border.top != margin)
if (priv->cell_border.top != margin)
{
priv->border.top = margin;
priv->cell_border.top = margin;
g_object_notify (G_OBJECT (area), "margin-top");
}
}
gint
gtk_cell_area_get_margin_bottom (GtkCellArea *area)
gtk_cell_area_get_cell_margin_bottom (GtkCellArea *area)
{
g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
return area->priv->border.bottom;
return area->priv->cell_border.bottom;
}
void
gtk_cell_area_set_margin_bottom (GtkCellArea *area,
gint margin)
gtk_cell_area_set_cell_margin_bottom (GtkCellArea *area,
gint margin)
{
GtkCellAreaPrivate *priv;
......@@ -1363,9 +1367,9 @@ gtk_cell_area_set_margin_bottom (GtkCellArea *area,
priv = area->priv;
if (priv->border.bottom != margin)
if (priv->cell_border.bottom != margin)
{
priv->border.bottom = margin;
priv->cell_border.bottom = margin;
g_object_notify (G_OBJECT (area), "margin-bottom");
}
......@@ -1373,9 +1377,9 @@ gtk_cell_area_set_margin_bottom (GtkCellArea *area,
/* For convenience in area implementations */
void
gtk_cell_area_inner_area (GtkCellArea *area,
GdkRectangle *background_area,
GdkRectangle *cell_area)
gtk_cell_area_inner_cell_area (GtkCellArea *area,
GdkRectangle *background_area,
GdkRectangle *cell_area)
{
GtkCellAreaPrivate *priv;
......@@ -1387,8 +1391,59 @@ gtk_cell_area_inner_area (GtkCellArea *area,
*cell_area = *background_area;
cell_area->x += priv->border.left;
cell_area->width -= (priv->border.left + priv->border.right);
cell_area->y += priv->border.top;
cell_area->height -= (priv->border.top + priv->border.bottom);
cell_area->x += priv->cell_border.left;
cell_area->width -= (priv->cell_border.left + priv->cell_border.right);
cell_area->y += priv->cell_border.top;
cell_area->height -= (priv->cell_border.top + priv->cell_border.bottom);
}
void
gtk_cell_area_request_renderer (GtkCellArea *area,
GtkCellRenderer *renderer,
GtkOrientation orientation,
GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size)
{
GtkCellAreaPrivate *priv;
g_return_if_fail (GTK_IS_CELL_AREA (area));
g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (minimum_size != NULL);
g_return_if_fail (natural_size != NULL);
priv = area->priv;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (for_size < 0)
gtk_cell_renderer_get_preferred_width (renderer, widget, minimum_size, natural_size);
else
{
for_size = MAX (0, for_size - (priv->cell_border.top + priv->cell_border.bottom));
gtk_cell_renderer_get_preferred_width_for_height (renderer, widget, for_size,
minimum_size, natural_size);
}
*minimum_size += (priv->cell_border.left + priv->cell_border.right);
*natural_size += (priv->cell_border.left + priv->cell_border.right);
}
else /* GTK_ORIENTATION_VERTICAL */
{
if (for_size < 0)
gtk_cell_renderer_get_preferred_height (renderer, widget, minimum_size, natural_size);
else
{
for_size = MAX (0, for_size - (priv->cell_border.left + priv->cell_border.right));
gtk_cell_renderer_get_preferred_height_for_width (renderer, widget, for_size,
minimum_size, natural_size);
}
*minimum_size += (priv->cell_border.top + priv->cell_border.bottom);
*natural_size += (priv->cell_border.top + priv->cell_border.bottom);
}
}
......@@ -239,23 +239,34 @@ void gtk_cell_area_cell_get_property (GtkCellArea
G_OBJECT_WARN_INVALID_PSPEC ((object), "cell property id", (property_id), (pspec))
/* Margins */
gint gtk_cell_area_get_margin_left (GtkCellArea *area);
void gtk_cell_area_set_margin_left (GtkCellArea *area,
gint gtk_cell_area_get_cell_margin_left (GtkCellArea *area);
void gtk_cell_area_set_cell_margin_left (GtkCellArea *area,
gint margin);
gint gtk_cell_area_get_margin_right (GtkCellArea *area);
void gtk_cell_area_set_margin_right (GtkCellArea *area,
gint gtk_cell_area_get_cell_margin_right (GtkCellArea *area);
void gtk_cell_area_set_cell_margin_right (GtkCellArea *area,
gint margin);
gint gtk_cell_area_get_margin_top (GtkCellArea *area);
void gtk_cell_area_set_margin_top (GtkCellArea *area,
gint gtk_cell_area_get_cell_margin_top (GtkCellArea *area);
void gtk_cell_area_set_cell_margin_top (GtkCellArea *area,
gint margin);
gint gtk_cell_area_get_margin_bottom (GtkCellArea *area);
void gtk_cell_area_set_margin_bottom (GtkCellArea *area,
gint gtk_cell_area_get_cell_margin_bottom (GtkCellArea *area);
void gtk_cell_area_set_cell_margin_bottom (GtkCellArea *area,
gint margin);
/* For convenience in area implementations */
void gtk_cell_area_inner_area (GtkCellArea *area,
GdkRectangle *background_area,
GdkRectangle *cell_area);
/* Functions for area implementations */
/* Distinguish the inner cell area from the whole requested area including margins */
void gtk_cell_area_inner_cell_area (GtkCellArea *area,
GdkRectangle *cell_area,
GdkRectangle *inner_cell_area);
/* Request the size of a cell while respecting the cell margins (requests are margin inclusive) */
void gtk_cell_area_request_renderer (GtkCellArea *area,
GtkCellRenderer *renderer,
GtkOrientation orientation,
GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size);
G_END_DECLS
......
......@@ -156,12 +156,6 @@ static void flush_iters (GtkCellAreaBox *box);
static void init_iter_groups (GtkCellAreaBox *box);
static void init_iter_group (GtkCellAreaBox *box,
GtkCellAreaBoxIter *iter);
static void get_renderer_size (GtkCellRenderer *renderer,
GtkOrientation orientation,
GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size);
static GSList *get_allocated_cells (GtkCellAreaBox *box,
GtkCellAreaBoxIter *iter,
GtkWidget *widget);
......@@ -534,6 +528,7 @@ get_allocated_cells (GtkCellAreaBox *box,
GtkWidget *widget)
{
const GtkCellAreaBoxAllocation *group_allocs;
GtkCellArea *area = GTK_CELL_AREA (box);
GtkCellAreaBoxPrivate *priv = box->priv;
GList *group_list, *cell_list;
GSList *allocated_cells = NULL;
......@@ -572,11 +567,11 @@ get_allocated_cells (GtkCellAreaBox *box,
{
CellInfo *info = cell_list->data;
get_renderer_size (info->renderer,
priv->orientation,
widget, -1,
&sizes[j].minimum_size,
&sizes[j].natural_size);
gtk_cell_area_request_renderer (area, info->renderer,
priv->orientation,
widget, -1,
&sizes[j].minimum_size,
&sizes[j].natural_size);
avail_size -= sizes[j].minimum_size;
}
......@@ -775,8 +770,12 @@ gtk_cell_area_box_render (GtkCellArea *area,
const GdkRectangle *cell_area)
{
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
GtkCellAreaBoxPrivate *priv = box->priv;
GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
GSList *allocated_cells, *l;
GdkRectangle background_area, inner_area;
background_area = *cell_area;
/* Get a list of cells with allocation sizes decided regardless
* of alignments and pack order etc. */
......@@ -786,6 +785,24 @@ gtk_cell_area_box_render (GtkCellArea *area,
{
AllocatedCell *cell = l->data;
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
background_area.x = cell_area->x + cell->position;
background_area.width = cell->size;
}
else
{
background_area.y = cell_area->y + cell->position;
background_area.height = cell->size;
}
/* Remove margins from the background area to produce the cell area
*/
gtk_cell_area_inner_cell_area (area, &background_area, &inner_area);
gtk_cell_renderer_render (cell->renderer, cr, widget,
&background_area, &inner_area,
/* flags */0);
}
......@@ -937,32 +954,6 @@ gtk_cell_area_box_get_request_mode (GtkCellArea *area)
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
}
static void
get_renderer_size (GtkCellRenderer *renderer,
GtkOrientation orientation,
GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (for_size < 0)
gtk_cell_renderer_get_preferred_width (renderer, widget, minimum_size, natural_size);
else
gtk_cell_renderer_get_preferred_width_for_height (renderer, widget, for_size,
minimum_size, natural_size);
}
else /* GTK_ORIENTATION_VERTICAL */
{
if (for_size < 0)
gtk_cell_renderer_get_preferred_height (renderer, widget, minimum_size, natural_size);
else
gtk_cell_renderer_get_preferred_height_for_width (renderer, widget, for_size,
minimum_size, natural_size);
}
}
static void
compute_size (GtkCellAreaBox *box,
GtkOrientation orientation,
......@@ -973,6 +964,7 @@ compute_size (GtkCellAreaBox *box,
gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
GtkCellArea *area = GTK_CELL_AREA (box);
CellGroup *group;
CellInfo *info;
GList *cell_list, *group_list;
......@@ -992,8 +984,8 @@ compute_size (GtkCellAreaBox *box,
info = cell_list->data;
get_renderer_size (info->renderer, orientation, widget, for_size,
&renderer_min_size, &renderer_nat_size);
gtk_cell_area_request_renderer (area, info->renderer, orientation, widget, for_size,
&renderer_min_size, &renderer_nat_size);
if (orientation == priv->orientation)
{
......@@ -1046,7 +1038,8 @@ compute_size (GtkCellAreaBox *box,
}
GtkRequestedSize *
get_group_sizes (CellGroup *group,
get_group_sizes (GtkCellArea *area,
CellGroup *group,
GtkOrientation orientation,
GtkWidget *widget,
gint *n_sizes)
......@@ -1064,10 +1057,10 @@ get_group_sizes (CellGroup *group,
sizes[i].data = info;
get_renderer_size (info->renderer,
orientation, widget, -1,
&sizes[i].minimum_size,
&sizes[i].natural_size);
gtk_cell_area_request_renderer (area, info->renderer,
orientation, widget, -1,
&sizes[i].minimum_size,
&sizes[i].natural_size);
}
return sizes;
......@@ -1082,15 +1075,16 @@ compute_group_size_for_opposing_orientation (GtkCellAreaBox *box,
gint *natural_size)
{
GtkCellAreaBoxPrivate *priv = box->priv;
GtkCellArea *area = GTK_CELL_AREA (box);
/* Exception for single cell groups */
if (group->n_cells == 1)
{
CellInfo *info = group->cells->data;
get_renderer_size (info->renderer,
OPPOSITE_ORIENTATION (priv->orientation),
widget, for_size, minimum_size, natural_size);
gtk_cell_area_request_renderer (area, info->renderer,
OPPOSITE_ORIENTATION (priv->orientation),
widget, for_size, minimum_size, natural_size);
}
else
{
......@@ -1101,7 +1095,7 @@ compute_group_size_for_opposing_orientation (GtkCellAreaBox *box,
gint extra_size, extra_extra;
gint min_size = 0, nat_size = 0;
orientation_sizes = get_group_sizes (group, priv->orientation, widget, &n_sizes);
orientation_sizes = get_group_sizes (area, group, priv->orientation, widget, &n_sizes);
/* First naturally allocate the cells in the group into the for_size */
avail_size -= (n_sizes - 1) * priv->spacing;
......@@ -1135,11 +1129,11 @@ compute_group_size_for_opposing_orientation (GtkCellAreaBox *box,
}
}
get_renderer_size (info->renderer,
OPPOSITE_ORIENTATION (priv->orientation),
widget,
orientation_sizes[i].minimum_size,
&cell_min, &cell_nat);
gtk_cell_area_request_renderer (area, info->renderer,
OPPOSITE_ORIENTATION (priv->orientation),
widget,
orientation_sizes[i].minimum_size,
&cell_min, &cell_nat);
min_size = MAX (min_size, cell_min);
nat_size = MAX (nat_size, cell_nat);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment