mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 22:41:43 +00:00
center box: implement natural size and rtl flipping
We prefer to give the center widget its natural size, and we center it as long as possible.
This commit is contained in:
parent
f8059f3040
commit
b4cb05ace9
@ -76,68 +76,44 @@ gtk_center_box_measure (GtkWidget *widget,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkCenterBox *self = GTK_CENTER_BOX (widget);
|
||||
int min, nat, min_baseline, nat_baseline;
|
||||
|
||||
*minimum = *natural = 0;
|
||||
int min_baseline, nat_baseline;
|
||||
int start_min = 0;
|
||||
int start_nat = 0;
|
||||
int center_min = 0;
|
||||
int center_nat = 0;
|
||||
int end_min = 0;
|
||||
int end_nat = 0;
|
||||
|
||||
if (self->start_widget)
|
||||
{
|
||||
gtk_widget_measure (self->start_widget,
|
||||
orientation,
|
||||
for_size,
|
||||
&min, &nat,
|
||||
&min_baseline, &nat_baseline);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = *minimum + min;
|
||||
*natural = *natural + nat;
|
||||
}
|
||||
else /* GTK_ORIENTATION_VERTICAL */
|
||||
{
|
||||
*minimum = MAX (*minimum, min);
|
||||
*natural = MAX (*minimum, nat);
|
||||
}
|
||||
}
|
||||
gtk_widget_measure (self->start_widget,
|
||||
orientation,
|
||||
for_size,
|
||||
&start_min, &start_nat,
|
||||
&min_baseline, &nat_baseline);
|
||||
|
||||
if (self->center_widget)
|
||||
{
|
||||
gtk_widget_measure (self->center_widget,
|
||||
orientation,
|
||||
for_size,
|
||||
&min, &nat,
|
||||
&min_baseline, &nat_baseline);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = *minimum + min;
|
||||
*natural = *natural + nat;
|
||||
}
|
||||
else /* GTK_ORIENTATION_VERTICAL */
|
||||
{
|
||||
*minimum = MAX (*minimum, min);
|
||||
*natural = MAX (*minimum, nat);
|
||||
}
|
||||
}
|
||||
gtk_widget_measure (self->center_widget,
|
||||
orientation,
|
||||
for_size,
|
||||
¢er_min, ¢er_nat,
|
||||
&min_baseline, &nat_baseline);
|
||||
|
||||
if (self->end_widget)
|
||||
{
|
||||
gtk_widget_measure (self->end_widget,
|
||||
orientation,
|
||||
for_size,
|
||||
&min, &nat,
|
||||
&min_baseline, &nat_baseline);
|
||||
gtk_widget_measure (self->end_widget,
|
||||
orientation,
|
||||
for_size,
|
||||
&end_min, &end_nat,
|
||||
&min_baseline, &nat_baseline);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = *minimum + min;
|
||||
*natural = *natural + nat;
|
||||
}
|
||||
else /* GTK_ORIENTATION_VERTICAL */
|
||||
{
|
||||
*minimum = MAX (*minimum, min);
|
||||
*natural = MAX (*minimum, nat);
|
||||
}
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = start_min + center_min + end_min;
|
||||
*natural = center_nat + 2 * MAX (start_nat, end_nat);
|
||||
}
|
||||
else /* GTK_ORIENTATION_VERTICAL */
|
||||
{
|
||||
*minimum = MAX (start_min, MAX (center_min, end_min));
|
||||
*natural = MAX (start_nat, MAX (center_nat, end_nat));
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,62 +125,88 @@ gtk_center_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation child_allocation;
|
||||
GtkAllocation clip = *allocation;
|
||||
GtkAllocation child_clip;
|
||||
int start_size = 0;
|
||||
int end_size = 0;
|
||||
int min, nat;
|
||||
GtkWidget *left;
|
||||
GtkWidget *right;
|
||||
int left_size = 0;
|
||||
int left_min = 0;
|
||||
int left_nat = 0;
|
||||
int center_size = 0;
|
||||
int center_min = 0;
|
||||
int center_nat = 0;
|
||||
int right_size = 0;
|
||||
int right_min = 0;
|
||||
int right_nat = 0;
|
||||
int avail;
|
||||
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
|
||||
{
|
||||
left = self->start_widget;
|
||||
right = self->end_widget;
|
||||
}
|
||||
else
|
||||
{
|
||||
right = self->start_widget;
|
||||
left = self->end_widget;
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_center_box_parent_class)->size_allocate (widget, allocation);
|
||||
|
||||
/* TODO: Allocate natural sizes if possible? */
|
||||
if (left)
|
||||
gtk_widget_measure (left, GTK_ORIENTATION_HORIZONTAL,
|
||||
allocation->height,
|
||||
&left_min, &left_nat, NULL, NULL);
|
||||
|
||||
if (right)
|
||||
gtk_widget_measure (right, GTK_ORIENTATION_HORIZONTAL,
|
||||
allocation->height,
|
||||
&right_min, &right_nat, NULL, NULL);
|
||||
|
||||
if (self->center_widget)
|
||||
gtk_widget_measure (self->center_widget, GTK_ORIENTATION_HORIZONTAL,
|
||||
allocation->height,
|
||||
¢er_min, ¢er_nat, NULL, NULL);
|
||||
|
||||
child_allocation.y = allocation->y;
|
||||
child_allocation.height = allocation->height;
|
||||
|
||||
if (self->start_widget)
|
||||
center_size = CLAMP (allocation->width - (left_min + right_min), center_min, center_nat);
|
||||
|
||||
if (left)
|
||||
{
|
||||
gtk_widget_measure (self->start_widget, GTK_ORIENTATION_HORIZONTAL,
|
||||
allocation->height,
|
||||
&min, &nat, NULL, NULL);
|
||||
avail = MIN ((allocation->width - center_size) / 2, allocation->width - (center_size + right_min));
|
||||
child_allocation.width = CLAMP (avail, left_min, left_nat);
|
||||
child_allocation.x = allocation->x;
|
||||
child_allocation.width = min;
|
||||
|
||||
gtk_widget_size_allocate (self->start_widget, &child_allocation);
|
||||
gtk_widget_get_clip (self->start_widget, &child_clip);
|
||||
gtk_widget_size_allocate (left, &child_allocation);
|
||||
gtk_widget_get_clip (left, &child_clip);
|
||||
gdk_rectangle_union (&clip, &clip, &child_clip);
|
||||
start_size = child_allocation.width;
|
||||
left_size = child_allocation.width;
|
||||
}
|
||||
|
||||
if (self->end_widget)
|
||||
if (right)
|
||||
{
|
||||
gtk_widget_measure (self->end_widget, GTK_ORIENTATION_HORIZONTAL,
|
||||
allocation->height,
|
||||
&min, &nat, NULL, NULL);
|
||||
child_allocation.x = allocation->x + allocation->width - min;
|
||||
child_allocation.width = min;
|
||||
avail = MIN ((allocation->width - center_size) / 2, allocation->width - (center_size + left_min));
|
||||
child_allocation.width = CLAMP (avail, right_min, right_nat);
|
||||
child_allocation.x = allocation->x + allocation->width - child_allocation.width;
|
||||
|
||||
gtk_widget_size_allocate (self->end_widget, &child_allocation);
|
||||
gtk_widget_get_clip (self->end_widget, &child_clip);
|
||||
gtk_widget_size_allocate (right, &child_allocation);
|
||||
gtk_widget_get_clip (right, &child_clip);
|
||||
gdk_rectangle_union (&clip, &clip, &child_clip);
|
||||
end_size = child_allocation.width;
|
||||
right_size = child_allocation.width;
|
||||
}
|
||||
|
||||
/* Center Widget */
|
||||
if (self->center_widget)
|
||||
{
|
||||
gtk_widget_measure (self->center_widget, GTK_ORIENTATION_HORIZONTAL,
|
||||
allocation->height,
|
||||
&min, &nat, NULL, NULL);
|
||||
|
||||
child_allocation.x = (allocation->width / 2) - (min / 2);
|
||||
child_allocation.width = center_size;
|
||||
child_allocation.x = (allocation->width / 2) - (child_allocation.width / 2);
|
||||
|
||||
/* Push in from start/end */
|
||||
if (start_size > child_allocation.x)
|
||||
child_allocation.x = start_size;
|
||||
else if (allocation->width - end_size < child_allocation.x + min)
|
||||
child_allocation.x = allocation->width - min - end_size;
|
||||
if (left_size > child_allocation.x)
|
||||
child_allocation.x = left_size;
|
||||
else if (allocation->width - right_size < child_allocation.x + child_allocation.width)
|
||||
child_allocation.x = allocation->width - child_allocation.width - right_size;
|
||||
|
||||
child_allocation.x += allocation->x;
|
||||
child_allocation.width = min;
|
||||
gtk_widget_size_allocate (self->center_widget, &child_allocation);
|
||||
gtk_widget_get_clip (self->center_widget, &child_clip);
|
||||
gdk_rectangle_union (&clip, &clip, &child_clip);
|
||||
@ -229,6 +231,39 @@ gtk_center_box_snapshot (GtkWidget *widget,
|
||||
gtk_widget_snapshot_child (widget, self->end_widget, snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
update_css_node_order (GtkCenterBox *self)
|
||||
{
|
||||
GtkCssNode *parent;
|
||||
GtkCssNode *first;
|
||||
GtkCssNode *last;
|
||||
|
||||
parent = gtk_widget_get_css_node (GTK_WIDGET (self));
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_LTR)
|
||||
{
|
||||
first = self->start_widget ? gtk_widget_get_css_node (self->start_widget) : NULL;
|
||||
last = self->end_widget ? gtk_widget_get_css_node (self->end_widget) : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = self->end_widget ? gtk_widget_get_css_node (self->end_widget) : NULL;
|
||||
last = self->start_widget ? gtk_widget_get_css_node (self->start_widget) : NULL;
|
||||
}
|
||||
|
||||
if (first)
|
||||
gtk_css_node_insert_after (parent, first, NULL);
|
||||
if (last)
|
||||
gtk_css_node_insert_before (parent, last, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_center_box_direction_changed (GtkWidget *widget,
|
||||
GtkTextDirection previous_direction)
|
||||
{
|
||||
update_css_node_order (GTK_CENTER_BOX (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_center_box_class_init (GtkCenterBoxClass *klass)
|
||||
{
|
||||
@ -237,6 +272,7 @@ gtk_center_box_class_init (GtkCenterBoxClass *klass)
|
||||
widget_class->measure = gtk_center_box_measure;
|
||||
widget_class->size_allocate = gtk_center_box_size_allocate;
|
||||
widget_class->snapshot = gtk_center_box_snapshot;
|
||||
widget_class->direction_changed = gtk_center_box_direction_changed;
|
||||
|
||||
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_FILLER);
|
||||
gtk_widget_class_set_css_name (widget_class, "box");
|
||||
@ -286,6 +322,8 @@ gtk_center_box_set_start_widget (GtkCenterBox *self,
|
||||
self->start_widget = child;
|
||||
if (child)
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
|
||||
update_css_node_order (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,6 +345,8 @@ gtk_center_box_set_center_widget (GtkCenterBox *self,
|
||||
self->center_widget = child;
|
||||
if (child)
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
|
||||
update_css_node_order (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,6 +368,8 @@ gtk_center_box_set_end_widget (GtkCenterBox *self,
|
||||
self->end_widget = child;
|
||||
if (child)
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
|
||||
update_css_node_order (self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user