Added "fixed-size" cell property to GtkCellAreaBox
Now a cell can either have a "fixed" size or it can have an "aligned" starting point or both. "fixed" size cells take no space when they are invisible.
This commit is contained in:
@ -83,6 +83,11 @@ static void gtk_cell_area_box_foreach_alloc (GtkCellArea
|
|||||||
const GdkRectangle *background_area,
|
const GdkRectangle *background_area,
|
||||||
GtkCellAllocCallback callback,
|
GtkCellAllocCallback callback,
|
||||||
gpointer callback_data);
|
gpointer callback_data);
|
||||||
|
static void gtk_cell_area_box_apply_attributes (GtkCellArea *area,
|
||||||
|
GtkTreeModel *tree_model,
|
||||||
|
GtkTreeIter *iter,
|
||||||
|
gboolean is_expander,
|
||||||
|
gboolean is_expanded);
|
||||||
static void gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
static void gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -145,6 +150,7 @@ typedef struct {
|
|||||||
guint expand : 1; /* Whether the cell expands */
|
guint expand : 1; /* Whether the cell expands */
|
||||||
guint pack : 1; /* Whether it is packed from the start or end */
|
guint pack : 1; /* Whether it is packed from the start or end */
|
||||||
guint align : 1; /* Whether to align its position with adjacent rows */
|
guint align : 1; /* Whether to align its position with adjacent rows */
|
||||||
|
guint fixed : 1; /* Whether to require the same size for all rows */
|
||||||
} CellInfo;
|
} CellInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -153,6 +159,8 @@ typedef struct {
|
|||||||
guint id : 8;
|
guint id : 8;
|
||||||
guint n_cells : 8;
|
guint n_cells : 8;
|
||||||
guint expand_cells : 8;
|
guint expand_cells : 8;
|
||||||
|
guint align : 1;
|
||||||
|
guint visible : 1;
|
||||||
} CellGroup;
|
} CellGroup;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -165,7 +173,8 @@ typedef struct {
|
|||||||
static CellInfo *cell_info_new (GtkCellRenderer *renderer,
|
static CellInfo *cell_info_new (GtkCellRenderer *renderer,
|
||||||
GtkPackType pack,
|
GtkPackType pack,
|
||||||
gboolean expand,
|
gboolean expand,
|
||||||
gboolean align);
|
gboolean align,
|
||||||
|
gboolean fixed);
|
||||||
static void cell_info_free (CellInfo *info);
|
static void cell_info_free (CellInfo *info);
|
||||||
static gint cell_info_find (CellInfo *info,
|
static gint cell_info_find (CellInfo *info,
|
||||||
GtkCellRenderer *renderer);
|
GtkCellRenderer *renderer);
|
||||||
@ -223,6 +232,7 @@ enum {
|
|||||||
CELL_PROP_0,
|
CELL_PROP_0,
|
||||||
CELL_PROP_EXPAND,
|
CELL_PROP_EXPAND,
|
||||||
CELL_PROP_ALIGN,
|
CELL_PROP_ALIGN,
|
||||||
|
CELL_PROP_FIXED_SIZE,
|
||||||
CELL_PROP_PACK_TYPE
|
CELL_PROP_PACK_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -277,6 +287,7 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
|
|||||||
area_class->remove = gtk_cell_area_box_remove;
|
area_class->remove = gtk_cell_area_box_remove;
|
||||||
area_class->foreach = gtk_cell_area_box_foreach;
|
area_class->foreach = gtk_cell_area_box_foreach;
|
||||||
area_class->foreach_alloc = gtk_cell_area_box_foreach_alloc;
|
area_class->foreach_alloc = gtk_cell_area_box_foreach_alloc;
|
||||||
|
area_class->apply_attributes = gtk_cell_area_box_apply_attributes;
|
||||||
area_class->set_cell_property = gtk_cell_area_box_set_cell_property;
|
area_class->set_cell_property = gtk_cell_area_box_set_cell_property;
|
||||||
area_class->get_cell_property = gtk_cell_area_box_get_cell_property;
|
area_class->get_cell_property = gtk_cell_area_box_get_cell_property;
|
||||||
|
|
||||||
@ -341,6 +352,23 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
|
|||||||
("align",
|
("align",
|
||||||
P_("Align"),
|
P_("Align"),
|
||||||
P_("Whether cell should align with adjacent rows"),
|
P_("Whether cell should align with adjacent rows"),
|
||||||
|
FALSE,
|
||||||
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkCellAreaBox:fixed-size:
|
||||||
|
*
|
||||||
|
* Whether the cell renderer should require the same size
|
||||||
|
* for all rows for which it was requested.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
gtk_cell_area_class_install_cell_property (area_class,
|
||||||
|
CELL_PROP_FIXED_SIZE,
|
||||||
|
g_param_spec_boolean
|
||||||
|
("fixed-size",
|
||||||
|
P_("Fixed Size"),
|
||||||
|
P_("Whether cells should be the same size in all rows"),
|
||||||
TRUE,
|
TRUE,
|
||||||
GTK_PARAM_READWRITE));
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
@ -373,7 +401,8 @@ static CellInfo *
|
|||||||
cell_info_new (GtkCellRenderer *renderer,
|
cell_info_new (GtkCellRenderer *renderer,
|
||||||
GtkPackType pack,
|
GtkPackType pack,
|
||||||
gboolean expand,
|
gboolean expand,
|
||||||
gboolean align)
|
gboolean align,
|
||||||
|
gboolean fixed)
|
||||||
{
|
{
|
||||||
CellInfo *info = g_slice_new (CellInfo);
|
CellInfo *info = g_slice_new (CellInfo);
|
||||||
|
|
||||||
@ -381,6 +410,7 @@ cell_info_new (GtkCellRenderer *renderer,
|
|||||||
info->pack = pack;
|
info->pack = pack;
|
||||||
info->expand = expand;
|
info->expand = expand;
|
||||||
info->align = align;
|
info->align = align;
|
||||||
|
info->fixed = fixed;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -476,6 +506,7 @@ cell_groups_rebuild (GtkCellAreaBox *box)
|
|||||||
CellGroup *group_ptr;
|
CellGroup *group_ptr;
|
||||||
GList *cells, *l;
|
GList *cells, *l;
|
||||||
guint id = 0;
|
guint id = 0;
|
||||||
|
gboolean last_cell_fixed = FALSE;
|
||||||
|
|
||||||
cell_groups_clear (box);
|
cell_groups_clear (box);
|
||||||
|
|
||||||
@ -492,8 +523,10 @@ cell_groups_rebuild (GtkCellAreaBox *box)
|
|||||||
{
|
{
|
||||||
CellInfo *info = l->data;
|
CellInfo *info = l->data;
|
||||||
|
|
||||||
/* A new group starts with any aligned cell, the first group is implied */
|
/* A new group starts with any aligned cell, or
|
||||||
if (info->align && l != cells)
|
* at the beginning and end of a fixed size cell.
|
||||||
|
* the first group is implied */
|
||||||
|
if ((info->align || info->fixed || last_cell_fixed) && l != cells)
|
||||||
{
|
{
|
||||||
memset (&group, 0x0, sizeof (CellGroup));
|
memset (&group, 0x0, sizeof (CellGroup));
|
||||||
group.id = ++id;
|
group.id = ++id;
|
||||||
@ -505,9 +538,16 @@ cell_groups_rebuild (GtkCellAreaBox *box)
|
|||||||
group_ptr->cells = g_list_prepend (group_ptr->cells, info);
|
group_ptr->cells = g_list_prepend (group_ptr->cells, info);
|
||||||
group_ptr->n_cells++;
|
group_ptr->n_cells++;
|
||||||
|
|
||||||
|
/* Not every group is aligned, some are floating
|
||||||
|
* fixed size cells */
|
||||||
|
if (info->align)
|
||||||
|
group_ptr->align = TRUE;
|
||||||
|
|
||||||
/* A group expands if it contains any expand cells */
|
/* A group expands if it contains any expand cells */
|
||||||
if (info->expand)
|
if (info->expand)
|
||||||
group_ptr->expand_cells++;
|
group_ptr->expand_cells++;
|
||||||
|
|
||||||
|
last_cell_fixed = info->fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (cells);
|
g_list_free (cells);
|
||||||
@ -582,20 +622,23 @@ init_context_group (GtkCellAreaBox *box,
|
|||||||
GtkCellAreaBoxContext *context)
|
GtkCellAreaBoxContext *context)
|
||||||
{
|
{
|
||||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||||
gint *expand_groups, i;
|
gint *expand_groups, *align_groups, i;
|
||||||
|
|
||||||
expand_groups = g_new (gboolean, priv->groups->len);
|
expand_groups = g_new (gboolean, priv->groups->len);
|
||||||
|
align_groups = g_new (gboolean, priv->groups->len);
|
||||||
|
|
||||||
for (i = 0; i < priv->groups->len; i++)
|
for (i = 0; i < priv->groups->len; i++)
|
||||||
{
|
{
|
||||||
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
||||||
|
|
||||||
expand_groups[i] = (group->expand_cells > 0);
|
expand_groups[i] = (group->expand_cells > 0);
|
||||||
|
align_groups[i] = group->align;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This call implies reseting the request info */
|
/* This call implies reseting the request info */
|
||||||
gtk_cell_area_box_init_groups (context, priv->groups->len, expand_groups);
|
gtk_cell_area_box_init_groups (context, priv->groups->len, expand_groups, align_groups);
|
||||||
g_free (expand_groups);
|
g_free (expand_groups);
|
||||||
|
g_free (align_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -782,7 +825,7 @@ get_allocated_cells (GtkCellAreaBox *box,
|
|||||||
GtkCellAreaBoxPrivate *priv = box->priv;
|
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||||
GList *cell_list;
|
GList *cell_list;
|
||||||
GSList *allocated_cells = NULL;
|
GSList *allocated_cells = NULL;
|
||||||
gint i, j, n_allocs;
|
gint i, j, n_allocs, position;
|
||||||
gint for_size, full_size;
|
gint for_size, full_size;
|
||||||
gboolean rtl;
|
gboolean rtl;
|
||||||
|
|
||||||
@ -807,7 +850,7 @@ get_allocated_cells (GtkCellAreaBox *box,
|
|||||||
rtl = (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
rtl = (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||||
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
||||||
|
|
||||||
for (i = 0; i < n_allocs; i++)
|
for (position = 0, i = 0; i < n_allocs; i++)
|
||||||
{
|
{
|
||||||
/* We dont always allocate all groups, sometimes the requested
|
/* We dont always allocate all groups, sometimes the requested
|
||||||
* group has only invisible cells for every row, hence the usage
|
* group has only invisible cells for every row, hence the usage
|
||||||
@ -820,20 +863,43 @@ get_allocated_cells (GtkCellAreaBox *box,
|
|||||||
{
|
{
|
||||||
CellInfo *info = group->cells->data;
|
CellInfo *info = group->cells->data;
|
||||||
AllocatedCell *cell;
|
AllocatedCell *cell;
|
||||||
|
gint cell_position, cell_size;
|
||||||
|
|
||||||
|
/* If were not aligned, place the cell after the last cell */
|
||||||
|
if (info->align)
|
||||||
|
position = cell_position = group_allocs[i].position;
|
||||||
|
else
|
||||||
|
cell_position = position;
|
||||||
|
|
||||||
|
/* If not a fixed size, use only the requested size for this row */
|
||||||
|
if (info->fixed)
|
||||||
|
cell_size = group_allocs[i].size;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gint dummy;
|
||||||
|
gtk_cell_area_request_renderer (area, info->renderer,
|
||||||
|
priv->orientation,
|
||||||
|
widget, for_size,
|
||||||
|
&dummy,
|
||||||
|
&cell_size);
|
||||||
|
cell_size = MIN (cell_size, group_allocs[i].size);
|
||||||
|
}
|
||||||
|
|
||||||
if (rtl)
|
if (rtl)
|
||||||
cell = allocated_cell_new (info->renderer,
|
cell = allocated_cell_new (info->renderer,
|
||||||
full_size - (group_allocs[i].position + group_allocs[i].size),
|
full_size - (cell_position + cell_size), cell_size);
|
||||||
group_allocs[i].size);
|
|
||||||
else
|
else
|
||||||
cell = allocated_cell_new (info->renderer, group_allocs[i].position, group_allocs[i].size);
|
cell = allocated_cell_new (info->renderer, cell_position, cell_size);
|
||||||
|
|
||||||
|
position += cell_size;
|
||||||
|
position += priv->spacing;
|
||||||
|
|
||||||
allocated_cells = g_slist_prepend (allocated_cells, cell);
|
allocated_cells = g_slist_prepend (allocated_cells, cell);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GtkRequestedSize *sizes;
|
GtkRequestedSize *sizes;
|
||||||
gint avail_size, position;
|
gint avail_size, cell_position;
|
||||||
gint visible_cells, expand_cells;
|
gint visible_cells, expand_cells;
|
||||||
gint extra_size, extra_extra;
|
gint extra_size, extra_extra;
|
||||||
|
|
||||||
@ -845,11 +911,19 @@ get_allocated_cells (GtkCellAreaBox *box,
|
|||||||
if (visible_cells == 0)
|
if (visible_cells == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Offset the allocation to the group position
|
/* If were not aligned, place the cell after the last cell
|
||||||
* and allocate into the group's available size
|
* and eat up the extra space
|
||||||
*/
|
*/
|
||||||
position = group_allocs[i].position;
|
if (group->align)
|
||||||
|
{
|
||||||
avail_size = group_allocs[i].size;
|
avail_size = group_allocs[i].size;
|
||||||
|
position = cell_position = group_allocs[i].position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
avail_size = group_allocs[i].size + (group_allocs[i].position - position);
|
||||||
|
cell_position = position;
|
||||||
|
}
|
||||||
|
|
||||||
sizes = g_new (GtkRequestedSize, visible_cells);
|
sizes = g_new (GtkRequestedSize, visible_cells);
|
||||||
|
|
||||||
@ -906,21 +980,25 @@ get_allocated_cells (GtkCellAreaBox *box,
|
|||||||
|
|
||||||
if (rtl)
|
if (rtl)
|
||||||
cell = allocated_cell_new (info->renderer,
|
cell = allocated_cell_new (info->renderer,
|
||||||
full_size - (position + sizes[j].minimum_size),
|
full_size - (cell_position + sizes[j].minimum_size),
|
||||||
sizes[j].minimum_size);
|
sizes[j].minimum_size);
|
||||||
else
|
else
|
||||||
cell = allocated_cell_new (info->renderer, position, sizes[j].minimum_size);
|
cell = allocated_cell_new (info->renderer, cell_position, sizes[j].minimum_size);
|
||||||
|
|
||||||
allocated_cells = g_slist_prepend (allocated_cells, cell);
|
allocated_cells = g_slist_prepend (allocated_cells, cell);
|
||||||
|
|
||||||
position += sizes[j].minimum_size;
|
cell_position += sizes[j].minimum_size;
|
||||||
position += priv->spacing;
|
cell_position += priv->spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (sizes);
|
g_free (sizes);
|
||||||
|
|
||||||
|
position = cell_position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (group_allocs);
|
||||||
|
|
||||||
/* Note it might not be important to reverse the list here at all,
|
/* Note it might not be important to reverse the list here at all,
|
||||||
* we have the correct positions, no need to allocate from left to right
|
* we have the correct positions, no need to allocate from left to right
|
||||||
*/
|
*/
|
||||||
@ -1022,7 +1100,7 @@ gtk_cell_area_box_add (GtkCellArea *area,
|
|||||||
GtkCellRenderer *renderer)
|
GtkCellRenderer *renderer)
|
||||||
{
|
{
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area),
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area),
|
||||||
renderer, FALSE, TRUE);
|
renderer, FALSE, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1221,6 +1299,40 @@ gtk_cell_area_box_foreach_alloc (GtkCellArea *area,
|
|||||||
g_slist_free (allocated_cells);
|
g_slist_free (allocated_cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_cell_area_box_apply_attributes (GtkCellArea *area,
|
||||||
|
GtkTreeModel *tree_model,
|
||||||
|
GtkTreeIter *iter,
|
||||||
|
gboolean is_expander,
|
||||||
|
gboolean is_expanded)
|
||||||
|
{
|
||||||
|
GtkCellAreaBox *box = GTK_CELL_AREA_BOX (area);
|
||||||
|
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* Call the parent class to apply the attributes */
|
||||||
|
GTK_CELL_AREA_CLASS
|
||||||
|
(gtk_cell_area_box_parent_class)->apply_attributes (area, tree_model, iter,
|
||||||
|
is_expander, is_expanded);
|
||||||
|
|
||||||
|
/* Update visible state for cell groups */
|
||||||
|
for (i = 0; i < priv->groups->len; i++)
|
||||||
|
{
|
||||||
|
CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
|
||||||
|
GList *list;
|
||||||
|
|
||||||
|
group->visible = FALSE;
|
||||||
|
|
||||||
|
for (list = group->cells; list && group->visible == FALSE; list = list->next)
|
||||||
|
{
|
||||||
|
CellInfo *info = list->data;
|
||||||
|
|
||||||
|
if (gtk_cell_renderer_get_visible (info->renderer))
|
||||||
|
group->visible = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
@ -1265,6 +1377,16 @@ gtk_cell_area_box_set_cell_property (GtkCellArea *area,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CELL_PROP_FIXED_SIZE:
|
||||||
|
val = g_value_get_boolean (value);
|
||||||
|
|
||||||
|
if (info->fixed != val)
|
||||||
|
{
|
||||||
|
info->fixed = val;
|
||||||
|
rebuild = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CELL_PROP_PACK_TYPE:
|
case CELL_PROP_PACK_TYPE:
|
||||||
pack_type = g_value_get_enum (value);
|
pack_type = g_value_get_enum (value);
|
||||||
|
|
||||||
@ -1313,6 +1435,10 @@ gtk_cell_area_box_get_cell_property (GtkCellArea *area,
|
|||||||
g_value_set_boolean (value, info->align);
|
g_value_set_boolean (value, info->align);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CELL_PROP_FIXED_SIZE:
|
||||||
|
g_value_set_boolean (value, info->fixed);
|
||||||
|
break;
|
||||||
|
|
||||||
case CELL_PROP_PACK_TYPE:
|
case CELL_PROP_PACK_TYPE:
|
||||||
g_value_set_enum (value, info->pack);
|
g_value_set_enum (value, info->pack);
|
||||||
break;
|
break;
|
||||||
@ -1935,7 +2061,7 @@ gtk_cell_area_box_layout_pack_start (GtkCellLayout *cell_layout,
|
|||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
gboolean expand)
|
gboolean expand)
|
||||||
{
|
{
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (cell_layout), renderer, expand, TRUE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (cell_layout), renderer, expand, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1943,7 +2069,7 @@ gtk_cell_area_box_layout_pack_end (GtkCellLayout *cell_layout,
|
|||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
gboolean expand)
|
gboolean expand)
|
||||||
{
|
{
|
||||||
gtk_cell_area_box_pack_end (GTK_CELL_AREA_BOX (cell_layout), renderer, expand, TRUE);
|
gtk_cell_area_box_pack_end (GTK_CELL_AREA_BOX (cell_layout), renderer, expand, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1970,6 +2096,24 @@ gtk_cell_area_box_layout_reorder (GtkCellLayout *cell_layout,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Private interaction with GtkCellAreaBoxContext *
|
||||||
|
*************************************************************/
|
||||||
|
gboolean
|
||||||
|
_gtk_cell_area_box_group_visible (GtkCellAreaBox *box,
|
||||||
|
gint group_idx)
|
||||||
|
{
|
||||||
|
GtkCellAreaBoxPrivate *priv = box->priv;
|
||||||
|
CellGroup *group;
|
||||||
|
|
||||||
|
g_assert (group_idx >= 0 && group_idx < priv->groups->len);
|
||||||
|
|
||||||
|
group = &g_array_index (priv->groups, CellGroup, group_idx);
|
||||||
|
|
||||||
|
return group->visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* API *
|
* API *
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
@ -1995,6 +2139,7 @@ gtk_cell_area_box_new (void)
|
|||||||
* @expand: whether @renderer should receive extra space when the area receives
|
* @expand: whether @renderer should receive extra space when the area receives
|
||||||
* more than its natural size
|
* more than its natural size
|
||||||
* @align: whether @renderer should be aligned in adjacent rows
|
* @align: whether @renderer should be aligned in adjacent rows
|
||||||
|
* @fixed: whether @renderer should have the same size in all rows
|
||||||
*
|
*
|
||||||
* Adds @renderer to @box, packed with reference to the start of @box.
|
* Adds @renderer to @box, packed with reference to the start of @box.
|
||||||
*
|
*
|
||||||
@ -2007,7 +2152,8 @@ void
|
|||||||
gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
|
gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
gboolean expand,
|
gboolean expand,
|
||||||
gboolean align)
|
gboolean align,
|
||||||
|
gboolean fixed)
|
||||||
{
|
{
|
||||||
GtkCellAreaBoxPrivate *priv;
|
GtkCellAreaBoxPrivate *priv;
|
||||||
CellInfo *info;
|
CellInfo *info;
|
||||||
@ -2024,7 +2170,7 @@ gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = cell_info_new (renderer, GTK_PACK_START, expand, align);
|
info = cell_info_new (renderer, GTK_PACK_START, expand, align, fixed);
|
||||||
|
|
||||||
priv->cells = g_list_append (priv->cells, info);
|
priv->cells = g_list_append (priv->cells, info);
|
||||||
|
|
||||||
@ -2038,6 +2184,7 @@ gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
|
|||||||
* @expand: whether @renderer should receive extra space when the area receives
|
* @expand: whether @renderer should receive extra space when the area receives
|
||||||
* more than its natural size
|
* more than its natural size
|
||||||
* @align: whether @renderer should be aligned in adjacent rows
|
* @align: whether @renderer should be aligned in adjacent rows
|
||||||
|
* @fixed: whether @renderer should have the same size in all rows
|
||||||
*
|
*
|
||||||
* Adds @renderer to @box, packed with reference to the end of @box.
|
* Adds @renderer to @box, packed with reference to the end of @box.
|
||||||
*
|
*
|
||||||
@ -2050,7 +2197,8 @@ void
|
|||||||
gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
|
gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
gboolean expand,
|
gboolean expand,
|
||||||
gboolean align)
|
gboolean align,
|
||||||
|
gboolean fixed)
|
||||||
{
|
{
|
||||||
GtkCellAreaBoxPrivate *priv;
|
GtkCellAreaBoxPrivate *priv;
|
||||||
CellInfo *info;
|
CellInfo *info;
|
||||||
@ -2067,7 +2215,7 @@ gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = cell_info_new (renderer, GTK_PACK_END, expand, align);
|
info = cell_info_new (renderer, GTK_PACK_END, expand, align, fixed);
|
||||||
|
|
||||||
priv->cells = g_list_append (priv->cells, info);
|
priv->cells = g_list_append (priv->cells, info);
|
||||||
|
|
||||||
|
@ -69,15 +69,20 @@ GtkCellArea *gtk_cell_area_box_new (void);
|
|||||||
void gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
|
void gtk_cell_area_box_pack_start (GtkCellAreaBox *box,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
gboolean expand,
|
gboolean expand,
|
||||||
gboolean align);
|
gboolean align,
|
||||||
|
gboolean fixed);
|
||||||
void gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
|
void gtk_cell_area_box_pack_end (GtkCellAreaBox *box,
|
||||||
GtkCellRenderer *renderer,
|
GtkCellRenderer *renderer,
|
||||||
gboolean expand,
|
gboolean expand,
|
||||||
gboolean align);
|
gboolean align,
|
||||||
|
gboolean fixed);
|
||||||
gint gtk_cell_area_box_get_spacing (GtkCellAreaBox *box);
|
gint gtk_cell_area_box_get_spacing (GtkCellAreaBox *box);
|
||||||
void gtk_cell_area_box_set_spacing (GtkCellAreaBox *box,
|
void gtk_cell_area_box_set_spacing (GtkCellAreaBox *box,
|
||||||
gint spacing);
|
gint spacing);
|
||||||
|
|
||||||
|
/* Private interaction with GtkCellAreaBoxContext */
|
||||||
|
gboolean _gtk_cell_area_box_group_visible (GtkCellAreaBox *box,
|
||||||
|
gint group_idx);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -32,9 +32,6 @@ static void gtk_cell_area_box_context_finalize (GObject
|
|||||||
|
|
||||||
/* GtkCellAreaContextClass */
|
/* GtkCellAreaContextClass */
|
||||||
static void gtk_cell_area_box_context_reset (GtkCellAreaContext *context);
|
static void gtk_cell_area_box_context_reset (GtkCellAreaContext *context);
|
||||||
static void gtk_cell_area_box_context_allocate (GtkCellAreaContext *context,
|
|
||||||
gint width,
|
|
||||||
gint height);
|
|
||||||
static void gtk_cell_area_box_context_get_preferred_height_for_width (GtkCellAreaContext *context,
|
static void gtk_cell_area_box_context_get_preferred_height_for_width (GtkCellAreaContext *context,
|
||||||
gint width,
|
gint width,
|
||||||
gint *minimum_height,
|
gint *minimum_height,
|
||||||
@ -81,11 +78,8 @@ struct _GtkCellAreaBoxContextPrivate
|
|||||||
/* Whether each group expands */
|
/* Whether each group expands */
|
||||||
gboolean *expand;
|
gboolean *expand;
|
||||||
|
|
||||||
/* Allocation info for this context if any */
|
/* Whether each group is aligned */
|
||||||
gint alloc_width;
|
gboolean *align;
|
||||||
gint alloc_height;
|
|
||||||
gint n_orientation_allocs;
|
|
||||||
GtkCellAreaBoxAllocation *orientation_allocs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GtkCellAreaBoxContext, gtk_cell_area_box_context, GTK_TYPE_CELL_AREA_CONTEXT);
|
G_DEFINE_TYPE (GtkCellAreaBoxContext, gtk_cell_area_box_context, GTK_TYPE_CELL_AREA_CONTEXT);
|
||||||
@ -187,11 +181,6 @@ gtk_cell_area_box_context_init (GtkCellAreaBoxContext *box_context)
|
|||||||
NULL, (GDestroyNotify)free_cache_array);
|
NULL, (GDestroyNotify)free_cache_array);
|
||||||
priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
priv->heights = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||||
NULL, (GDestroyNotify)free_cache_array);
|
NULL, (GDestroyNotify)free_cache_array);
|
||||||
|
|
||||||
priv->alloc_width = 0;
|
|
||||||
priv->alloc_height = 0;
|
|
||||||
priv->orientation_allocs = NULL;
|
|
||||||
priv->n_orientation_allocs = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -204,7 +193,6 @@ gtk_cell_area_box_context_class_init (GtkCellAreaBoxContextClass *class)
|
|||||||
object_class->finalize = gtk_cell_area_box_context_finalize;
|
object_class->finalize = gtk_cell_area_box_context_finalize;
|
||||||
|
|
||||||
context_class->reset = gtk_cell_area_box_context_reset;
|
context_class->reset = gtk_cell_area_box_context_reset;
|
||||||
context_class->allocate = gtk_cell_area_box_context_allocate;
|
|
||||||
context_class->get_preferred_height_for_width = gtk_cell_area_box_context_get_preferred_height_for_width;
|
context_class->get_preferred_height_for_width = gtk_cell_area_box_context_get_preferred_height_for_width;
|
||||||
context_class->get_preferred_width_for_height = gtk_cell_area_box_context_get_preferred_width_for_height;
|
context_class->get_preferred_width_for_height = gtk_cell_area_box_context_get_preferred_width_for_height;
|
||||||
|
|
||||||
@ -225,8 +213,8 @@ gtk_cell_area_box_context_finalize (GObject *object)
|
|||||||
g_hash_table_destroy (priv->widths);
|
g_hash_table_destroy (priv->widths);
|
||||||
g_hash_table_destroy (priv->heights);
|
g_hash_table_destroy (priv->heights);
|
||||||
|
|
||||||
g_free (priv->orientation_allocs);
|
|
||||||
g_free (priv->expand);
|
g_free (priv->expand);
|
||||||
|
g_free (priv->align);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gtk_cell_area_box_context_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gtk_cell_area_box_context_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -259,162 +247,10 @@ gtk_cell_area_box_context_reset (GtkCellAreaContext *context)
|
|||||||
g_hash_table_remove_all (priv->widths);
|
g_hash_table_remove_all (priv->widths);
|
||||||
g_hash_table_remove_all (priv->heights);
|
g_hash_table_remove_all (priv->heights);
|
||||||
|
|
||||||
/* Clear the allocation */
|
|
||||||
g_free (priv->orientation_allocs);
|
|
||||||
priv->orientation_allocs = NULL;
|
|
||||||
priv->n_orientation_allocs = 0;
|
|
||||||
|
|
||||||
GTK_CELL_AREA_CONTEXT_CLASS
|
GTK_CELL_AREA_CONTEXT_CLASS
|
||||||
(gtk_cell_area_box_context_parent_class)->reset (context);
|
(gtk_cell_area_box_context_parent_class)->reset (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkRequestedSize *
|
|
||||||
gtk_cell_area_box_context_get_requests (GtkCellAreaBoxContext *box_context,
|
|
||||||
GtkOrientation orientation,
|
|
||||||
gint for_size,
|
|
||||||
gint *n_requests)
|
|
||||||
{
|
|
||||||
GtkCellAreaBoxContextPrivate *priv;
|
|
||||||
GtkRequestedSize *requests;
|
|
||||||
GArray *array;
|
|
||||||
CachedSize *size;
|
|
||||||
gint visible_groups = 0;
|
|
||||||
gint i, j;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context), NULL);
|
|
||||||
|
|
||||||
priv = box_context->priv;
|
|
||||||
array = get_array (box_context, orientation, for_size);
|
|
||||||
|
|
||||||
for (i = 0; i < array->len; i++)
|
|
||||||
{
|
|
||||||
size = &g_array_index (array, CachedSize, i);
|
|
||||||
|
|
||||||
if (size->nat_size > 0)
|
|
||||||
visible_groups++;
|
|
||||||
}
|
|
||||||
|
|
||||||
requests = g_new (GtkRequestedSize, visible_groups);
|
|
||||||
|
|
||||||
for (j = 0, i = 0; i < array->len; i++)
|
|
||||||
{
|
|
||||||
size = &g_array_index (array, CachedSize, i);
|
|
||||||
|
|
||||||
if (size->nat_size > 0)
|
|
||||||
{
|
|
||||||
requests[j].data = GINT_TO_POINTER (i);
|
|
||||||
requests[j].minimum_size = size->min_size;
|
|
||||||
requests[j].natural_size = size->nat_size;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_requests)
|
|
||||||
*n_requests = visible_groups;
|
|
||||||
|
|
||||||
return requests;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GtkCellAreaBoxAllocation *
|
|
||||||
allocate_for_orientation (GtkCellAreaBoxContext *context,
|
|
||||||
GtkOrientation orientation,
|
|
||||||
gint spacing,
|
|
||||||
gint size,
|
|
||||||
gint for_size,
|
|
||||||
gint *n_allocs)
|
|
||||||
{
|
|
||||||
GtkCellAreaBoxAllocation *allocs;
|
|
||||||
GtkRequestedSize *sizes;
|
|
||||||
GArray *array;
|
|
||||||
gint n_expand_groups = 0;
|
|
||||||
gint i, n_groups, position;
|
|
||||||
gint extra_size, extra_extra;
|
|
||||||
gint avail_size = size;
|
|
||||||
|
|
||||||
sizes = gtk_cell_area_box_context_get_requests (context, orientation, for_size, &n_groups);
|
|
||||||
array = get_array (context, orientation, for_size);
|
|
||||||
n_expand_groups = count_expand_groups (context);
|
|
||||||
|
|
||||||
/* First start by naturally allocating space among groups */
|
|
||||||
avail_size -= (n_groups - 1) * spacing;
|
|
||||||
for (i = 0; i < n_groups; i++)
|
|
||||||
avail_size -= sizes[i].minimum_size;
|
|
||||||
|
|
||||||
if (avail_size > 0)
|
|
||||||
avail_size = gtk_distribute_natural_allocation (avail_size, n_groups, sizes);
|
|
||||||
else
|
|
||||||
avail_size = 0;
|
|
||||||
|
|
||||||
/* Calculate/distribute expand for groups */
|
|
||||||
if (n_expand_groups > 0)
|
|
||||||
{
|
|
||||||
extra_size = avail_size / n_expand_groups;
|
|
||||||
extra_extra = avail_size % n_expand_groups;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
extra_size = extra_extra = 0;
|
|
||||||
|
|
||||||
allocs = g_new (GtkCellAreaBoxAllocation, n_groups);
|
|
||||||
|
|
||||||
for (position = 0, i = 0; i < n_groups; i++)
|
|
||||||
{
|
|
||||||
allocs[i].group_idx = GPOINTER_TO_INT (sizes[i].data);
|
|
||||||
allocs[i].position = position;
|
|
||||||
allocs[i].size = sizes[i].minimum_size;
|
|
||||||
|
|
||||||
if (group_expands (context, allocs[i].group_idx))
|
|
||||||
{
|
|
||||||
allocs[i].size += extra_size;
|
|
||||||
if (extra_extra)
|
|
||||||
{
|
|
||||||
allocs[i].size++;
|
|
||||||
extra_extra--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
position += allocs[i].size;
|
|
||||||
position += spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_allocs)
|
|
||||||
*n_allocs = n_groups;
|
|
||||||
|
|
||||||
g_free (sizes);
|
|
||||||
|
|
||||||
return allocs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_cell_area_box_context_allocate (GtkCellAreaContext *context,
|
|
||||||
gint width,
|
|
||||||
gint height)
|
|
||||||
{
|
|
||||||
GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
|
|
||||||
GtkCellAreaBoxContextPrivate *priv = box_context->priv;
|
|
||||||
GtkCellArea *area;
|
|
||||||
GtkOrientation orientation;
|
|
||||||
gint spacing;
|
|
||||||
|
|
||||||
area = gtk_cell_area_context_get_area (context);
|
|
||||||
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
|
|
||||||
spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
|
|
||||||
|
|
||||||
g_free (priv->orientation_allocs);
|
|
||||||
priv->orientation_allocs = NULL;
|
|
||||||
priv->n_orientation_allocs = 0;
|
|
||||||
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL && width > 0)
|
|
||||||
priv->orientation_allocs = allocate_for_orientation (box_context, orientation,
|
|
||||||
spacing, width, height,
|
|
||||||
&priv->n_orientation_allocs);
|
|
||||||
else if (orientation == GTK_ORIENTATION_VERTICAL && height > 0)
|
|
||||||
priv->orientation_allocs = allocate_for_orientation (box_context, orientation,
|
|
||||||
spacing, height, width,
|
|
||||||
&priv->n_orientation_allocs);
|
|
||||||
|
|
||||||
GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate (context, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
|
gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
|
||||||
GtkOrientation orientation,
|
GtkOrientation orientation,
|
||||||
@ -422,23 +258,38 @@ gtk_cell_area_box_context_sum (GtkCellAreaBoxContext *context,
|
|||||||
gint *minimum_size,
|
gint *minimum_size,
|
||||||
gint *natural_size)
|
gint *natural_size)
|
||||||
{
|
{
|
||||||
GtkCellArea *area;
|
GtkCellAreaBoxContextPrivate *priv = context->priv;
|
||||||
|
GtkCellAreaBox *area;
|
||||||
GtkOrientation box_orientation;
|
GtkOrientation box_orientation;
|
||||||
GArray *array;
|
GArray *array;
|
||||||
gint spacing, i;
|
gint spacing, i, last_aligned_group_idx;
|
||||||
gint min_size = 0, nat_size = 0;
|
gint min_size = 0, nat_size = 0;
|
||||||
|
|
||||||
area = gtk_cell_area_context_get_area (GTK_CELL_AREA_CONTEXT (context));
|
area = (GtkCellAreaBox *)gtk_cell_area_context_get_area (GTK_CELL_AREA_CONTEXT (context));
|
||||||
spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
|
spacing = gtk_cell_area_box_get_spacing (area);
|
||||||
box_orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
|
box_orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
|
||||||
array = get_array (context, orientation, for_size);
|
array = get_array (context, orientation, for_size);
|
||||||
|
|
||||||
|
/* Get the last visible aligned group
|
||||||
|
* (we need to get space at least up till this group) */
|
||||||
|
for (i = array->len - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (priv->align[i] &&
|
||||||
|
_gtk_cell_area_box_group_visible (area, i))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last_aligned_group_idx = i >= 0 ? i : 0;
|
||||||
|
|
||||||
for (i = 0; i < array->len; i++)
|
for (i = 0; i < array->len; i++)
|
||||||
{
|
{
|
||||||
CachedSize *size = &g_array_index (array, CachedSize, i);
|
CachedSize *size = &g_array_index (array, CachedSize, i);
|
||||||
|
|
||||||
if (box_orientation == orientation)
|
if (box_orientation == orientation)
|
||||||
{
|
{
|
||||||
|
if (i > last_aligned_group_idx &&
|
||||||
|
!_gtk_cell_area_box_group_visible (area, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Dont add spacing for 0 size groups, they can be 0 size because
|
/* Dont add spacing for 0 size groups, they can be 0 size because
|
||||||
* they contain only invisible cells for this round of requests
|
* they contain only invisible cells for this round of requests
|
||||||
*/
|
*/
|
||||||
@ -536,7 +387,8 @@ gtk_cell_area_box_context_copy (GtkCellAreaBox *box,
|
|||||||
|
|
||||||
gtk_cell_area_box_init_groups (copy,
|
gtk_cell_area_box_init_groups (copy,
|
||||||
context->priv->base_widths->len,
|
context->priv->base_widths->len,
|
||||||
context->priv->expand);
|
context->priv->expand,
|
||||||
|
context->priv->align);
|
||||||
|
|
||||||
/* Copy the base arrays */
|
/* Copy the base arrays */
|
||||||
copy_size_array (context->priv->base_widths,
|
copy_size_array (context->priv->base_widths,
|
||||||
@ -550,14 +402,6 @@ gtk_cell_area_box_context_copy (GtkCellAreaBox *box,
|
|||||||
g_hash_table_foreach (context->priv->widths,
|
g_hash_table_foreach (context->priv->widths,
|
||||||
(GHFunc)for_size_copy, copy->priv->widths);
|
(GHFunc)for_size_copy, copy->priv->widths);
|
||||||
|
|
||||||
/* Copy any active allocation */
|
|
||||||
copy->priv->n_orientation_allocs =
|
|
||||||
context->priv->n_orientation_allocs;
|
|
||||||
|
|
||||||
if (copy->priv->n_orientation_allocs)
|
|
||||||
copy->priv->orientation_allocs =
|
|
||||||
g_memdup (context->priv->orientation_allocs,
|
|
||||||
copy->priv->n_orientation_allocs * sizeof (GtkCellAreaBoxAllocation));
|
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
@ -565,7 +409,8 @@ gtk_cell_area_box_context_copy (GtkCellAreaBox *box,
|
|||||||
void
|
void
|
||||||
gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
|
gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
|
||||||
guint n_groups,
|
guint n_groups,
|
||||||
gboolean *expand_groups)
|
gboolean *expand_groups,
|
||||||
|
gboolean *align_groups)
|
||||||
{
|
{
|
||||||
GtkCellAreaBoxContextPrivate *priv;
|
GtkCellAreaBoxContextPrivate *priv;
|
||||||
|
|
||||||
@ -583,6 +428,9 @@ gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
|
|||||||
|
|
||||||
g_free (priv->expand);
|
g_free (priv->expand);
|
||||||
priv->expand = g_memdup (expand_groups, n_groups * sizeof (gboolean));
|
priv->expand = g_memdup (expand_groups, n_groups * sizeof (gboolean));
|
||||||
|
|
||||||
|
g_free (priv->align);
|
||||||
|
priv->align = g_memdup (align_groups, n_groups * sizeof (gboolean));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -823,31 +671,192 @@ gtk_cell_area_box_context_get_group_width_for_height (GtkCellAreaBoxContext *box
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GtkRequestedSize *
|
||||||
|
gtk_cell_area_box_context_get_requests (GtkCellAreaBoxContext *box_context,
|
||||||
|
GtkCellAreaBox *area,
|
||||||
|
GtkOrientation orientation,
|
||||||
|
gint for_size,
|
||||||
|
gint *n_requests)
|
||||||
|
{
|
||||||
|
GtkCellAreaBoxContextPrivate *priv = box_context->priv;
|
||||||
|
GtkRequestedSize *requests;
|
||||||
|
GArray *array;
|
||||||
|
CachedSize *size;
|
||||||
|
gint visible_groups = 0;
|
||||||
|
gint last_aligned_group_idx = 0;
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
/* Get the last visible aligned group
|
||||||
|
* (we need to get space at least up till this group) */
|
||||||
|
for (i = priv->base_widths->len - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (priv->align[i] &&
|
||||||
|
_gtk_cell_area_box_group_visible (area, i))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last_aligned_group_idx = i >= 0 ? i : 0;
|
||||||
|
|
||||||
|
priv = box_context->priv;
|
||||||
|
array = get_array (box_context, orientation, for_size);
|
||||||
|
|
||||||
|
for (i = 0; i < array->len; i++)
|
||||||
|
{
|
||||||
|
size = &g_array_index (array, CachedSize, i);
|
||||||
|
|
||||||
|
if (size->nat_size > 0 &&
|
||||||
|
(i <= last_aligned_group_idx ||
|
||||||
|
_gtk_cell_area_box_group_visible (area, i)))
|
||||||
|
visible_groups++;
|
||||||
|
}
|
||||||
|
|
||||||
|
requests = g_new (GtkRequestedSize, visible_groups);
|
||||||
|
|
||||||
|
for (j = 0, i = 0; i < array->len; i++)
|
||||||
|
{
|
||||||
|
size = &g_array_index (array, CachedSize, i);
|
||||||
|
|
||||||
|
if (size->nat_size > 0 &&
|
||||||
|
(i <= last_aligned_group_idx ||
|
||||||
|
_gtk_cell_area_box_group_visible (area, i)))
|
||||||
|
{
|
||||||
|
requests[j].data = GINT_TO_POINTER (i);
|
||||||
|
requests[j].minimum_size = size->min_size;
|
||||||
|
requests[j].natural_size = size->nat_size;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_requests)
|
||||||
|
*n_requests = visible_groups;
|
||||||
|
|
||||||
|
return requests;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkCellAreaBoxAllocation *
|
||||||
|
allocate_for_orientation (GtkCellAreaBoxContext *context,
|
||||||
|
GtkCellAreaBox *area,
|
||||||
|
GtkOrientation orientation,
|
||||||
|
gint spacing,
|
||||||
|
gint size,
|
||||||
|
gint for_size,
|
||||||
|
gint *n_allocs)
|
||||||
|
{
|
||||||
|
GtkCellAreaBoxContextPrivate *priv = context->priv;
|
||||||
|
GtkCellAreaBoxAllocation *allocs;
|
||||||
|
GtkRequestedSize *sizes;
|
||||||
|
GArray *array;
|
||||||
|
gint n_expand_groups = 0;
|
||||||
|
gint i, n_groups, position, vis_position;
|
||||||
|
gint extra_size, extra_extra;
|
||||||
|
gint avail_size = size;
|
||||||
|
|
||||||
|
sizes = gtk_cell_area_box_context_get_requests (context, area, orientation, for_size, &n_groups);
|
||||||
|
array = get_array (context, orientation, for_size);
|
||||||
|
n_expand_groups = count_expand_groups (context);
|
||||||
|
|
||||||
|
/* First start by naturally allocating space among groups */
|
||||||
|
avail_size -= (n_groups - 1) * spacing;
|
||||||
|
for (i = 0; i < n_groups; i++)
|
||||||
|
avail_size -= sizes[i].minimum_size;
|
||||||
|
|
||||||
|
if (avail_size > 0)
|
||||||
|
avail_size = gtk_distribute_natural_allocation (avail_size, n_groups, sizes);
|
||||||
|
else
|
||||||
|
avail_size = 0;
|
||||||
|
|
||||||
|
/* Calculate/distribute expand for groups */
|
||||||
|
if (n_expand_groups > 0)
|
||||||
|
{
|
||||||
|
extra_size = avail_size / n_expand_groups;
|
||||||
|
extra_extra = avail_size % n_expand_groups;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
extra_size = extra_extra = 0;
|
||||||
|
|
||||||
|
allocs = g_new (GtkCellAreaBoxAllocation, n_groups);
|
||||||
|
|
||||||
|
for (vis_position = 0, position = 0, i = 0; i < n_groups; i++)
|
||||||
|
{
|
||||||
|
allocs[i].group_idx = GPOINTER_TO_INT (sizes[i].data);
|
||||||
|
|
||||||
|
if (priv->align[allocs[i].group_idx])
|
||||||
|
vis_position = position;
|
||||||
|
|
||||||
|
allocs[i].position = vis_position;
|
||||||
|
allocs[i].size = sizes[i].minimum_size;
|
||||||
|
|
||||||
|
if (group_expands (context, allocs[i].group_idx))
|
||||||
|
{
|
||||||
|
allocs[i].size += extra_size;
|
||||||
|
if (extra_extra)
|
||||||
|
{
|
||||||
|
allocs[i].size++;
|
||||||
|
extra_extra--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
position += allocs[i].size;
|
||||||
|
position += spacing;
|
||||||
|
|
||||||
|
if (_gtk_cell_area_box_group_visible (area, allocs[i].group_idx))
|
||||||
|
{
|
||||||
|
vis_position += allocs[i].size;
|
||||||
|
vis_position += spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_allocs)
|
||||||
|
*n_allocs = n_groups;
|
||||||
|
|
||||||
|
g_free (sizes);
|
||||||
|
|
||||||
|
return allocs;
|
||||||
|
}
|
||||||
|
|
||||||
GtkRequestedSize *
|
GtkRequestedSize *
|
||||||
gtk_cell_area_box_context_get_widths (GtkCellAreaBoxContext *box_context,
|
gtk_cell_area_box_context_get_widths (GtkCellAreaBoxContext *box_context,
|
||||||
gint *n_widths)
|
gint *n_widths)
|
||||||
{
|
{
|
||||||
return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_HORIZONTAL, -1, n_widths);
|
GtkCellAreaBox *area = (GtkCellAreaBox *)gtk_cell_area_context_get_area (GTK_CELL_AREA_CONTEXT (box_context));
|
||||||
|
|
||||||
|
return gtk_cell_area_box_context_get_requests (box_context, area, GTK_ORIENTATION_HORIZONTAL, -1, n_widths);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkRequestedSize *
|
GtkRequestedSize *
|
||||||
gtk_cell_area_box_context_get_heights (GtkCellAreaBoxContext *box_context,
|
gtk_cell_area_box_context_get_heights (GtkCellAreaBoxContext *box_context,
|
||||||
gint *n_heights)
|
gint *n_heights)
|
||||||
{
|
{
|
||||||
return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_VERTICAL, -1, n_heights);
|
GtkCellAreaBox *area = (GtkCellAreaBox *)gtk_cell_area_context_get_area (GTK_CELL_AREA_CONTEXT (box_context));
|
||||||
|
|
||||||
|
return gtk_cell_area_box_context_get_requests (box_context, area, GTK_ORIENTATION_VERTICAL, -1, n_heights);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkCellAreaBoxAllocation *
|
GtkCellAreaBoxAllocation *
|
||||||
gtk_cell_area_box_context_get_orientation_allocs (GtkCellAreaBoxContext *context,
|
gtk_cell_area_box_context_get_orientation_allocs (GtkCellAreaBoxContext *context,
|
||||||
gint *n_allocs)
|
gint *n_allocs)
|
||||||
{
|
{
|
||||||
GtkCellAreaBoxContextPrivate *priv;
|
GtkCellAreaContext *ctx = GTK_CELL_AREA_CONTEXT (context);
|
||||||
|
GtkCellAreaBox *area;
|
||||||
|
GtkOrientation orientation;
|
||||||
|
gint spacing, width, height, alloc_count = 0;
|
||||||
|
GtkCellAreaBoxAllocation *allocs = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (context), NULL);
|
area = (GtkCellAreaBox *)gtk_cell_area_context_get_area (ctx);
|
||||||
|
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
|
||||||
|
spacing = gtk_cell_area_box_get_spacing (area);
|
||||||
|
|
||||||
priv = context->priv;
|
gtk_cell_area_context_get_allocation (ctx, &width, &height);
|
||||||
|
|
||||||
*n_allocs = priv->n_orientation_allocs;
|
if (orientation == GTK_ORIENTATION_HORIZONTAL && width > 0)
|
||||||
|
allocs = allocate_for_orientation (context, area, orientation,
|
||||||
|
spacing, width, height,
|
||||||
|
&alloc_count);
|
||||||
|
else if (orientation == GTK_ORIENTATION_VERTICAL && height > 0)
|
||||||
|
allocs = allocate_for_orientation (context, area, orientation,
|
||||||
|
spacing, height, width,
|
||||||
|
&alloc_count);
|
||||||
|
|
||||||
return priv->orientation_allocs;
|
*n_allocs = alloc_count;
|
||||||
|
|
||||||
|
return allocs;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,8 @@ GtkCellAreaBoxContext *gtk_cell_area_box_context_copy (GtkCellAreaBox
|
|||||||
/* Initialize group array dimensions */
|
/* Initialize group array dimensions */
|
||||||
void gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
|
void gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
|
||||||
guint n_groups,
|
guint n_groups,
|
||||||
gboolean *expand_groups);
|
gboolean *expand_groups,
|
||||||
|
gboolean *align_groups);
|
||||||
|
|
||||||
/* Update cell-group sizes */
|
/* Update cell-group sizes */
|
||||||
void gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context,
|
void gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context,
|
||||||
|
@ -96,12 +96,12 @@ simple_scaffold (void)
|
|||||||
area = cell_area_scaffold_get_area (CELL_AREA_SCAFFOLD (scaffold));
|
area = cell_area_scaffold_get_area (CELL_AREA_SCAFFOLD (scaffold));
|
||||||
|
|
||||||
cell_1 = renderer = gtk_cell_renderer_text_new ();
|
cell_1 = renderer = gtk_cell_renderer_text_new ();
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, FALSE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, FALSE, FALSE);
|
||||||
gtk_cell_area_attribute_connect (area, renderer, "text", SIMPLE_COLUMN_NAME);
|
gtk_cell_area_attribute_connect (area, renderer, "text", SIMPLE_COLUMN_NAME);
|
||||||
|
|
||||||
cell_2 = renderer = gtk_cell_renderer_pixbuf_new ();
|
cell_2 = renderer = gtk_cell_renderer_pixbuf_new ();
|
||||||
g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL);
|
g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL);
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, TRUE, FALSE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, TRUE, FALSE, FALSE);
|
||||||
gtk_cell_area_attribute_connect (area, renderer, "stock-id", SIMPLE_COLUMN_ICON);
|
gtk_cell_area_attribute_connect (area, renderer, "stock-id", SIMPLE_COLUMN_ICON);
|
||||||
|
|
||||||
cell_3 = renderer = gtk_cell_renderer_text_new ();
|
cell_3 = renderer = gtk_cell_renderer_text_new ();
|
||||||
@ -109,7 +109,7 @@ simple_scaffold (void)
|
|||||||
"wrap-mode", PANGO_WRAP_WORD,
|
"wrap-mode", PANGO_WRAP_WORD,
|
||||||
"wrap-width", 215,
|
"wrap-width", 215,
|
||||||
NULL);
|
NULL);
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE, FALSE);
|
||||||
gtk_cell_area_attribute_connect (area, renderer, "text", SIMPLE_COLUMN_DESCRIPTION);
|
gtk_cell_area_attribute_connect (area, renderer, "text", SIMPLE_COLUMN_DESCRIPTION);
|
||||||
|
|
||||||
return scaffold;
|
return scaffold;
|
||||||
@ -360,7 +360,7 @@ focus_scaffold (gboolean color_bg, GtkCellRenderer **focus, GtkCellRenderer **si
|
|||||||
|
|
||||||
renderer = gtk_cell_renderer_text_new ();
|
renderer = gtk_cell_renderer_text_new ();
|
||||||
g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
|
g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, TRUE, FALSE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, TRUE, FALSE, FALSE);
|
||||||
gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_NAME);
|
gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_NAME);
|
||||||
|
|
||||||
if (color_bg)
|
if (color_bg)
|
||||||
@ -371,7 +371,7 @@ focus_scaffold (gboolean color_bg, GtkCellRenderer **focus, GtkCellRenderer **si
|
|||||||
|
|
||||||
toggle = renderer = gtk_cell_renderer_toggle_new ();
|
toggle = renderer = gtk_cell_renderer_toggle_new ();
|
||||||
g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL);
|
g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL);
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE, FALSE);
|
||||||
gtk_cell_area_attribute_connect (area, renderer, "active", FOCUS_COLUMN_CHECK);
|
gtk_cell_area_attribute_connect (area, renderer, "active", FOCUS_COLUMN_CHECK);
|
||||||
|
|
||||||
if (color_bg)
|
if (color_bg)
|
||||||
@ -395,7 +395,7 @@ focus_scaffold (gboolean color_bg, GtkCellRenderer **focus, GtkCellRenderer **si
|
|||||||
if (sibling)
|
if (sibling)
|
||||||
*sibling = renderer;
|
*sibling = renderer;
|
||||||
|
|
||||||
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE);
|
gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE, FALSE);
|
||||||
gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_STATIC_TEXT);
|
gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_STATIC_TEXT);
|
||||||
|
|
||||||
gtk_cell_area_add_focus_sibling (area, toggle, renderer);
|
gtk_cell_area_add_focus_sibling (area, toggle, renderer);
|
||||||
|
@ -156,27 +156,50 @@ expand_cell_toggled (GtkToggleButton *toggle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_control (GtkWidget *box, gint number, gboolean align, CallbackData *data)
|
fixed_cell_toggled (GtkToggleButton *toggle,
|
||||||
|
CallbackData *data)
|
||||||
|
{
|
||||||
|
gboolean active = gtk_toggle_button_get_active (toggle);
|
||||||
|
|
||||||
|
gtk_cell_area_cell_set (data->area, data->renderer, "fixed-size", active, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CNTL_EXPAND,
|
||||||
|
CNTL_ALIGN,
|
||||||
|
CNTL_FIXED
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_control (GtkWidget *box, gint number, gint cntl, CallbackData *data)
|
||||||
{
|
{
|
||||||
GtkWidget *checkbutton;
|
GtkWidget *checkbutton;
|
||||||
gchar *name;
|
GCallback callback = NULL;
|
||||||
|
gchar *name = NULL;
|
||||||
|
|
||||||
if (align)
|
switch (cntl)
|
||||||
name = g_strdup_printf ("Align Cell #%d", number);
|
{
|
||||||
else
|
case CNTL_EXPAND:
|
||||||
name = g_strdup_printf ("Expand Cell #%d", number);
|
name = g_strdup_printf ("Expand Cell #%d", number);
|
||||||
|
callback = G_CALLBACK (expand_cell_toggled);
|
||||||
|
break;
|
||||||
|
case CNTL_ALIGN:
|
||||||
|
name = g_strdup_printf ("Align Cell #%d", number);
|
||||||
|
callback = G_CALLBACK (align_cell_toggled);
|
||||||
|
break;
|
||||||
|
case CNTL_FIXED:
|
||||||
|
name = g_strdup_printf ("Fix size Cell #%d", number);
|
||||||
|
callback = G_CALLBACK (fixed_cell_toggled);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
checkbutton = gtk_check_button_new_with_label (name);
|
checkbutton = gtk_check_button_new_with_label (name);
|
||||||
gtk_widget_show (checkbutton);
|
gtk_widget_show (checkbutton);
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), align);
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), cntl == CNTL_FIXED);
|
||||||
gtk_box_pack_start (GTK_BOX (box), checkbutton, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (box), checkbutton, FALSE, FALSE, 0);
|
||||||
|
|
||||||
if (align)
|
g_signal_connect (G_OBJECT (checkbutton), "toggled", callback, data);
|
||||||
g_signal_connect (G_OBJECT (checkbutton), "toggled",
|
g_free (name);
|
||||||
G_CALLBACK (align_cell_toggled), data);
|
|
||||||
else
|
|
||||||
g_signal_connect (G_OBJECT (checkbutton), "toggled",
|
|
||||||
G_CALLBACK (expand_cell_toggled), data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gint
|
gint
|
||||||
@ -296,20 +319,30 @@ main (gint argc, gchar **argv)
|
|||||||
gtk_widget_show (cntl_vbox);
|
gtk_widget_show (cntl_vbox);
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
|
||||||
|
|
||||||
create_control (cntl_vbox, 1, TRUE, &callback[0]);
|
create_control (cntl_vbox, 1, CNTL_ALIGN, &callback[0]);
|
||||||
create_control (cntl_vbox, 2, TRUE, &callback[1]);
|
create_control (cntl_vbox, 2, CNTL_ALIGN, &callback[1]);
|
||||||
create_control (cntl_vbox, 3, TRUE, &callback[2]);
|
create_control (cntl_vbox, 3, CNTL_ALIGN, &callback[2]);
|
||||||
create_control (cntl_vbox, 4, TRUE, &callback[3]);
|
create_control (cntl_vbox, 4, CNTL_ALIGN, &callback[3]);
|
||||||
|
|
||||||
/* Expand controls */
|
/* Expand controls */
|
||||||
cntl_vbox = gtk_vbox_new (FALSE, 2);
|
cntl_vbox = gtk_vbox_new (FALSE, 2);
|
||||||
gtk_widget_show (cntl_vbox);
|
gtk_widget_show (cntl_vbox);
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
|
||||||
|
|
||||||
create_control (cntl_vbox, 1, FALSE, &callback[0]);
|
create_control (cntl_vbox, 1, CNTL_EXPAND, &callback[0]);
|
||||||
create_control (cntl_vbox, 2, FALSE, &callback[1]);
|
create_control (cntl_vbox, 2, CNTL_EXPAND, &callback[1]);
|
||||||
create_control (cntl_vbox, 3, FALSE, &callback[2]);
|
create_control (cntl_vbox, 3, CNTL_EXPAND, &callback[2]);
|
||||||
create_control (cntl_vbox, 4, FALSE, &callback[3]);
|
create_control (cntl_vbox, 4, CNTL_EXPAND, &callback[3]);
|
||||||
|
|
||||||
|
/* Fixed controls */
|
||||||
|
cntl_vbox = gtk_vbox_new (FALSE, 2);
|
||||||
|
gtk_widget_show (cntl_vbox);
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), cntl_vbox, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
create_control (cntl_vbox, 1, CNTL_FIXED, &callback[0]);
|
||||||
|
create_control (cntl_vbox, 2, CNTL_FIXED, &callback[1]);
|
||||||
|
create_control (cntl_vbox, 3, CNTL_FIXED, &callback[2]);
|
||||||
|
create_control (cntl_vbox, 4, CNTL_FIXED, &callback[3]);
|
||||||
|
|
||||||
gtk_widget_show_all (window);
|
gtk_widget_show_all (window);
|
||||||
gtk_main ();
|
gtk_main ();
|
||||||
|
Reference in New Issue
Block a user