diff options
author | Matthias Clasen <mclasen@redhat.com> | 2017-06-04 15:57:58 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2017-06-04 15:57:58 -0400 |
commit | dc6c27fb88920dba6329f0caff393449f285356a (patch) | |
tree | ebe6c99bf07c950e7003fc7b05272b1313acfbe3 | |
parent | ebabb4bf30808c30257e3b3499f5e5f9775611d7 (diff) | |
download | gtk+-center-box.tar.gz |
GtkCenterBox: Implement baseline supportcenter-box
-rw-r--r-- | gtk/gtkcenterbox.c | 183 |
1 files changed, 96 insertions, 87 deletions
diff --git a/gtk/gtkcenterbox.c b/gtk/gtkcenterbox.c index b8acd84be5..b8df2c8d33 100644 --- a/gtk/gtkcenterbox.c +++ b/gtk/gtkcenterbox.c @@ -247,41 +247,62 @@ gtk_center_box_measure_opposite (GtkWidget *widget, int *natural_baseline) { GtkCenterBox *self = GTK_CENTER_BOX (widget); - 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; + int child_min, child_nat; + int child_min_baseline, child_nat_baseline; + int total_min, above_min, below_min; + int total_nat, above_nat, below_nat; + GtkWidget *child[3]; GtkRequestedSize sizes[3]; + int i; + + child[0] = self->start_widget; + child[1] = self->center_widget; + child[2] = self->end_widget; if (for_size >= 0) gtk_center_box_distribute (self, -1, for_size, sizes); - if (self->start_widget) - gtk_widget_measure (self->start_widget, - orientation, - for_size >= 0 ? sizes[0].minimum_size : -1, - &start_min, &start_nat, - &min_baseline, &nat_baseline); + above_min = below_min = above_nat = below_nat = -1; + total_min = total_nat = 0; - if (self->center_widget) - gtk_widget_measure (self->center_widget, - orientation, - for_size >= 0 ? sizes[1].minimum_size : -1, - ¢er_min, ¢er_nat, - &min_baseline, &nat_baseline); + for (i = 0; i < 3; i++) + { + if (child[i] == NULL) + continue; - if (self->end_widget) - gtk_widget_measure (self->end_widget, - orientation, - for_size >= 0 ? sizes[2].minimum_size : -1, - &end_min, &end_nat, - &min_baseline, &nat_baseline); + gtk_widget_measure (child[i], + orientation, + for_size >= 0 ? sizes[i].minimum_size : -1, + &child_min, &child_nat, + &child_min_baseline, &child_nat_baseline); - *minimum = MAX (start_min, MAX (center_min, end_min)); - *natural = MAX (start_nat, MAX (center_nat, end_nat)); + if (child_min_baseline >= 0) + { + below_min = MAX (below_min, child_min - child_min_baseline); + above_min = MAX (above_min, child_min_baseline); + below_nat = MAX (below_nat, child_nat - child_nat_baseline); + above_nat = MAX (above_nat, child_nat_baseline); + } + else + { + total_min = MAX (total_min, child_min); + total_nat = MAX (total_nat, child_nat); + } + } + + if (above_min >= 0) + { + total_min = MAX (total_min, above_min + below_min); + total_nat = MAX (total_nat, above_nat + below_nat); + /* assume GTK_BASELINE_POSITION_CENTER for now */ + if (minimum_baseline) + *minimum_baseline = above_min + (total_min - (above_min + below_min)) / 2; + if (natural_baseline) + *natural_baseline = above_nat + (total_nat - (above_nat + below_nat)) / 2; + } + + *minimum = total_min; + *natural = total_nat; } static void @@ -301,22 +322,6 @@ gtk_center_box_measure (GtkWidget *widget, gtk_center_box_measure_opposite (widget, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline); } -#define SET_CHILD_ALLOC(pos,size) \ - if (self->orientation == GTK_ORIENTATION_HORIZONTAL) \ - { \ - child_allocation.x = allocation->x + (pos); \ - child_allocation.y = allocation->y; \ - child_allocation.width = (size); \ - child_allocation.height = allocation->height; \ - } \ - else \ - { \ - child_allocation.x = allocation->x; \ - child_allocation.y = allocation->y + (pos); \ - child_allocation.width = allocation->width; \ - child_allocation.height = (size); \ - } - static void gtk_center_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -325,16 +330,14 @@ gtk_center_box_size_allocate (GtkWidget *widget, GtkAllocation child_allocation; GtkAllocation clip = *allocation; GtkAllocation child_clip; - GtkWidget *start; - GtkWidget *center; - GtkWidget *end; - int start_size = 0; - int center_size = 0; - int end_size = 0; + GtkWidget *child[3]; + int child_size[3]; + int child_pos[3]; GtkRequestedSize sizes[3]; int size; int for_size; - int child_pos; + int baseline; + int i; GTK_WIDGET_CLASS (gtk_center_box_parent_class)->size_allocate (widget, allocation); @@ -342,11 +345,13 @@ gtk_center_box_size_allocate (GtkWidget *widget, { size = allocation->width; for_size = allocation->height; + baseline = gtk_widget_get_allocated_baseline (widget); } else { size = allocation->height; for_size = allocation->width; + baseline = -1; } gtk_center_box_distribute (self, for_size, size, sizes); @@ -354,56 +359,60 @@ gtk_center_box_size_allocate (GtkWidget *widget, if (self->orientation == GTK_ORIENTATION_HORIZONTAL && gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { - start = self->end_widget; - start_size = sizes[2].minimum_size; - end = self->start_widget; - end_size = sizes[0].minimum_size; + child[0] = self->end_widget; + child[1] = self->center_widget; + child[2] = self->start_widget; + child_size[0] = sizes[2].minimum_size; + child_size[1] = sizes[1].minimum_size; + child_size[2] = sizes[0].minimum_size; } else { - start = self->start_widget; - start_size = sizes[0].minimum_size; - end = self->end_widget; - end_size = sizes[2].minimum_size; + child[0] = self->start_widget; + child[1] = self->center_widget; + child[2] = self->end_widget; + child_size[0] = sizes[0].minimum_size; + child_size[1] = sizes[1].minimum_size; + child_size[2] = sizes[2].minimum_size; } - center = self->center_widget; - center_size = sizes[1].minimum_size; + child_pos[0] = 0; + child_pos[1] = (size / 2) - (child_size[1] / 2); + child_pos[2] = size - child_size[2]; - child_allocation = *allocation; - - if (center) + if (child[1]) { - child_pos = (size / 2) - (center_size / 2); - /* Push in from start/end */ - if (start_size > child_pos) - child_pos = start_size; - else if (size - end_size < child_pos + center_size) - child_pos = size - center_size - end_size; - - SET_CHILD_ALLOC (child_pos, center_size); - - gtk_widget_size_allocate (center, &child_allocation); - gtk_widget_get_clip (center, &child_clip); - gdk_rectangle_union (&clip, &clip, &child_clip); + if (child_size[0] > child_pos[1]) + child_pos[1] = child_size[0]; + else if (size - child_size[2] < child_pos[1] + child_size[1]) + child_pos[1] = size - child_size[1] - child_size[2]; } - if (start) - { - SET_CHILD_ALLOC (0, start_size); - - gtk_widget_size_allocate (start, &child_allocation); - gtk_widget_get_clip (start, &child_clip); - gdk_rectangle_union (&clip, &clip, &child_clip); - } + child_allocation = *allocation; - if (end) + for (i = 0; i < 3; i++) { - SET_CHILD_ALLOC (size - end_size, end_size); + if (child[i] == NULL) + continue; + + if (self->orientation == GTK_ORIENTATION_HORIZONTAL) + { + child_allocation.x = allocation->x + child_pos[i]; + child_allocation.y = allocation->y; + child_allocation.width = child_size[i]; + child_allocation.height = allocation->height; + } + else + { + child_allocation.x = allocation->x; + child_allocation.y = allocation->y + child_pos[i]; + child_allocation.width = allocation->width; + child_allocation.height = child_size[i]; + } - gtk_widget_size_allocate (end, &child_allocation); - gtk_widget_get_clip (end, &child_clip); + gtk_widget_size_allocate_with_baseline (child[i], &child_allocation, baseline); + gtk_widget_get_clip (child[i], &child_clip); gdk_rectangle_union (&clip, &clip, &child_clip); } |