Implement fair extra space allocation
This commit is contained in:
committed by
Tristan Van Berkom
parent
208ba9bb50
commit
651bed57a4
145
gtk/gtkbox.c
145
gtk/gtkbox.c
@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user