Implement fair extra space allocation

This commit is contained in:
Tadej Borovšak
2010-08-06 22:07:42 +02:00
committed by Tristan Van Berkom
parent 208ba9bb50
commit 651bed57a4

View File

@ -407,39 +407,45 @@ gtk_box_size_allocate (GtkWidget *widget,
gint nvis_children; gint nvis_children;
gint nexpand_children; gint nexpand_children;
widget->allocation = *allocation; guint border_width;
GtkTextDirection direction;
count_expand_children (box, &nvis_children, &nexpand_children);
if (nvis_children > 0)
{
guint border_width = gtk_container_get_border_width (GTK_CONTAINER (box));
GtkTextDirection direction = gtk_widget_get_direction (widget);
GtkAllocation child_allocation; GtkAllocation child_allocation;
GtkRequestedSize *sizes = g_newa (GtkRequestedSize, nvis_children); GtkRequestedSize *sizes;
GtkPackType packing; GtkPackType packing;
gint size; gint size;
gint extra; gint extra;
gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */
gint x = 0, y = 0, i; gint x = 0, y = 0, i;
gint child_size; gint child_size;
widget->allocation = *allocation;
count_expand_children (box, &nvis_children, &nexpand_children);
/* If there is no visible child, simply return. */
if (nvis_children <= 0)
return;
border_width = gtk_container_get_border_width (GTK_CONTAINER (box));
direction = gtk_widget_get_direction (widget);
sizes = g_newa (GtkRequestedSize, nvis_children);
if (private->orientation == GTK_ORIENTATION_HORIZONTAL) if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing; size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing;
else else
size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing; size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing;
/* Retrieve desired size for visible children */ /* Retrieve desired size for visible children. */
i = 0; for (i = 0, children = private->children; children; children = children->next)
children = private->children;
while (children)
{ {
child = children->data; child = children->data;
children = children->next;
if (gtk_widget_get_visible (child->widget)) if (!gtk_widget_get_visible (child->widget))
{ continue;
if (private->orientation == GTK_ORIENTATION_HORIZONTAL) if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget), gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget),
allocation->height, allocation->height,
@ -475,14 +481,13 @@ gtk_box_size_allocate (GtkWidget *widget,
sizes[i].data = child; sizes[i].data = child;
i += 1; i++;
}
} }
if (private->homogeneous) if (private->homogeneous)
{ {
/* If were homogenous we still need to run the above loop to get the minimum sizes /* If were homogenous we still need to run the above loop to get the
* for children that are not going to fill * minimum sizes for children that are not going to fill
*/ */
if (private->orientation == GTK_ORIENTATION_HORIZONTAL) if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing; size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing;
@ -490,6 +495,7 @@ gtk_box_size_allocate (GtkWidget *widget,
size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing; size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing;
extra = size / nvis_children; extra = size / nvis_children;
n_extra_widgets = size % nvis_children;
} }
else else
{ {
@ -500,13 +506,15 @@ gtk_box_size_allocate (GtkWidget *widget,
* and is available for expanding children. * and is available for expanding children.
*/ */
if (nexpand_children > 0) if (nexpand_children > 0)
{
extra = size / nexpand_children; extra = size / nexpand_children;
n_extra_widgets = size % nexpand_children;
}
else else
extra = 0; extra = 0;
} }
/* Allocate child positions. */ /* Allocate child positions. */
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing) for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
{ {
if (private->orientation == GTK_ORIENTATION_HORIZONTAL) if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
@ -528,27 +536,28 @@ gtk_box_size_allocate (GtkWidget *widget,
y = allocation->y + allocation->height - border_width; y = allocation->y + allocation->height - border_width;
} }
i = 0; for (i = 0, children = private->children;
children = private->children; children;
while (children) children = children->next)
{ {
child = children->data; child = children->data;
children = children->next;
if (gtk_widget_get_visible (child->widget)) /* If widget is not visible or it's packing is not right for current
{ * loop, skip it.
if (child->pack == packing) */
{ if (child->pack != packing || !gtk_widget_get_visible (child->widget))
continue;
/* Assign the child's size. */ /* Assign the child's size. */
if (private->homogeneous) if (private->homogeneous)
{ {
if (nvis_children == 1)
child_size = size;
else
child_size = extra; child_size = extra;
nvis_children -= 1; if (n_extra_widgets > 0)
size -= extra; {
child_size++;
n_extra_widgets--;
}
} }
else else
{ {
@ -556,13 +565,13 @@ gtk_box_size_allocate (GtkWidget *widget,
if (child->expand) if (child->expand)
{ {
if (nexpand_children == 1)
child_size += size;
else
child_size += extra; child_size += extra;
nexpand_children -= 1; if (n_extra_widgets > 0)
size -= extra; {
child_size++;
n_extra_widgets--;
}
} }
} }
@ -620,11 +629,8 @@ gtk_box_size_allocate (GtkWidget *widget,
} }
} }
gtk_widget_size_allocate (child->widget, &child_allocation); gtk_widget_size_allocate (child->widget, &child_allocation);
}
i += 1; i++;
}
}
} }
} }
} }
@ -926,16 +932,18 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
gint nexpand_children; gint nexpand_children;
gint computed_minimum = 0, computed_natural = 0; gint computed_minimum = 0, computed_natural = 0;
guint border_width = gtk_container_get_border_width (GTK_CONTAINER (box)); guint border_width = gtk_container_get_border_width (GTK_CONTAINER (box));
GtkRequestedSize *sizes;
count_expand_children (box, &nvis_children, &nexpand_children);
if (nvis_children > 0)
{
GtkRequestedSize *sizes = g_newa (GtkRequestedSize, nvis_children);
GtkPackType packing; GtkPackType packing;
gint size, extra, i; gint size, extra, i;
gint child_size, child_minimum, child_natural; gint child_size, child_minimum, child_natural;
gint n_extra_widgets = 0;
count_expand_children (box, &nvis_children, &nexpand_children);
if (nvis_children <= 0)
return;
sizes = g_newa (GtkRequestedSize, nvis_children);
size = avail_size - border_width * 2 - (nvis_children - 1) * private->spacing; size = avail_size - border_width * 2 - (nvis_children - 1) * private->spacing;
/* Retrieve desired size for visible children */ /* Retrieve desired size for visible children */
@ -979,11 +987,12 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
if (private->homogeneous) if (private->homogeneous)
{ {
/* If were homogenous we still need to run the above loop to get the minimum sizes /* If were homogenous we still need to run the above loop to get the
* for children that are not going to fill * minimum sizes for children that are not going to fill
*/ */
size = avail_size - border_width * 2 - (nvis_children - 1) * private->spacing; size = avail_size - border_width * 2 - (nvis_children - 1) * private->spacing;
extra = size / nvis_children; extra = size / nvis_children;
n_extra_widgets = size % nvis_children;
} }
else else
{ {
@ -994,7 +1003,10 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
* and is available for expanding children. * and is available for expanding children.
*/ */
if (nexpand_children > 0) if (nexpand_children > 0)
{
extra = size / nexpand_children; extra = size / nexpand_children;
n_extra_widgets = size % nexpand_children;
}
else else
extra = 0; extra = 0;
} }
@ -1002,24 +1014,27 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
/* Allocate child positions. */ /* Allocate child positions. */
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing) for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
{ {
for (i = 0, children = private->children; children; children = children->next) for (i = 0, children = private->children;
children;
children = children->next)
{ {
child = children->data; child = children->data;
if (gtk_widget_get_visible (child->widget)) if (child->pack != packing || !gtk_widget_get_visible (child->widget))
{ continue;
if (child->pack == packing) if (child->pack == packing)
{ {
/* Assign the child's size. */ /* Assign the child's size. */
if (private->homogeneous) if (private->homogeneous)
{ {
if (nvis_children == 1)
child_size = size;
else
child_size = extra; child_size = extra;
nvis_children -= 1; if (n_extra_widgets > 0)
size -= extra; {
child_size++;
n_extra_widgets--;
}
} }
else else
{ {
@ -1027,13 +1042,13 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
if (child->expand) if (child->expand)
{ {
if (nexpand_children == 1)
child_size += size;
else
child_size += extra; child_size += extra;
nexpand_children -= 1; if (n_extra_widgets > 0)
size -= extra; {
child_size++;
n_extra_widgets--;
}
} }
} }
@ -1062,8 +1077,6 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
i += 1; i += 1;
} }
} }
}
}
computed_minimum += border_width * 2; computed_minimum += border_width * 2;
computed_natural += border_width * 2; computed_natural += border_width * 2;