diff options
author | Timm Bäder <mail@baedert.org> | 2017-04-22 20:18:17 +0200 |
---|---|---|
committer | Timm Bäder <mail@baedert.org> | 2017-04-25 20:30:37 +0200 |
commit | 066c1983ba2c6f1f891e600c561ab03eac2074a6 (patch) | |
tree | b3bd68d270eb6ade9f463f615ab7c4e92c59df2d /gtk/gtkcenterbox.c | |
parent | c92b7d4224b9cef1d08373fcc28f7fbd96c64e6d (diff) | |
download | gtk+-066c1983ba2c6f1f891e600c561ab03eac2074a6.tar.gz |
actionbar: Add explicit center widget
The center widget in GtkBox was only introduced to use it in
GtkActionBar. However, the implementation there is much more complex
than it needs to be, so move the center widget into GtkActionBar instead
and later remove it from GtkBox.
Diffstat (limited to 'gtk/gtkcenterbox.c')
-rw-r--r-- | gtk/gtkcenterbox.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/gtk/gtkcenterbox.c b/gtk/gtkcenterbox.c new file mode 100644 index 0000000000..316126c2ac --- /dev/null +++ b/gtk/gtkcenterbox.c @@ -0,0 +1,226 @@ + +#include "gtkcenterboxprivate.h" + +G_DEFINE_TYPE (GtkCenterBox, gtk_center_box, GTK_TYPE_WIDGET); + + +static void +gtk_center_box_measure (GtkWidget *widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline) +{ + GtkCenterBox *self = GTK_CENTER_BOX (widget); + int min, nat, min_baseline, nat_baseline; + + gtk_widget_measure (self->start_widget, + orientation, + for_size, + minimum, natural, + minimum_baseline, natural_baseline); + + if (self->center_widget) + { + gtk_widget_measure (self->center_widget, + orientation, + for_size, + &min, &nat, + &min_baseline, &nat_baseline); + + /* XXX How are baselines even handled? */ + + 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->end_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); + } + +} + +static void +gtk_center_box_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkCenterBox *self = GTK_CENTER_BOX (widget); + GtkAllocation child_allocation; + GtkAllocation clip = *allocation; + GtkAllocation child_clip; + int start_size, end_size; + int min, nat; + + GTK_WIDGET_CLASS (gtk_center_box_parent_class)->size_allocate (widget, allocation); + + + // TODO: Allocate natural sizes if possible? + + /* Start Box */ + gtk_widget_measure (self->start_widget, GTK_ORIENTATION_HORIZONTAL, + allocation->height, + &min, &nat, NULL, NULL); + child_allocation.x = allocation->x; + child_allocation.y = allocation->y; + child_allocation.width = min; + child_allocation.height = allocation->height; + + gtk_widget_size_allocate (self->start_widget, &child_allocation); + gtk_widget_get_clip (self->start_widget, &child_clip); + gdk_rectangle_union (&clip, &clip, &child_clip); + start_size = child_allocation.width; + + + /* End Box */ + 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; + + gtk_widget_size_allocate (self->end_widget, &child_allocation); + gtk_widget_get_clip (self->end_widget, &child_clip); + gdk_rectangle_union (&clip, &clip, &child_clip); + end_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); + + /* 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; + + 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); + } + + gtk_widget_set_clip (widget, &clip); +} + +static void +gtk_center_box_snapshot (GtkWidget *widget, + GtkSnapshot *snapshot) +{ + GtkCenterBox *self = GTK_CENTER_BOX (widget); + + gtk_widget_snapshot_child (widget, self->start_widget, snapshot); + + if (self->center_widget) + gtk_widget_snapshot_child (widget, self->center_widget, snapshot); + + gtk_widget_snapshot_child (widget, self->end_widget, snapshot); +} + +static void +gtk_center_box_class_init (GtkCenterBoxClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->measure = gtk_center_box_measure; + widget_class->size_allocate = gtk_center_box_size_allocate; + widget_class->snapshot = gtk_center_box_snapshot; +} + +static void +gtk_center_box_init (GtkCenterBox *self) +{ + gtk_widget_set_has_window (GTK_WIDGET (self), FALSE); + + self->start_widget = NULL; + self->center_widget = NULL; + self->end_widget = NULL; +} + +GtkWidget * +gtk_center_box_new (void) +{ + return GTK_WIDGET (g_object_new (GTK_TYPE_CENTER_BOX, NULL)); +} + +void +gtk_center_box_set_start_widget (GtkCenterBox *self, + GtkWidget *child) +{ + if (self->start_widget) + gtk_widget_unparent (self->start_widget); + + self->start_widget = child; + if (child) + gtk_widget_set_parent (child, GTK_WIDGET (self)); +} + +void +gtk_center_box_set_center_widget (GtkCenterBox *self, + GtkWidget *child) +{ + if (self->center_widget) + gtk_widget_unparent (self->center_widget); + + self->center_widget = child; + if (child) + gtk_widget_set_parent (child, GTK_WIDGET (self)); +} + +void +gtk_center_box_set_end_widget (GtkCenterBox *self, + GtkWidget *child) +{ + if (self->end_widget) + gtk_widget_unparent (self->end_widget); + + self->end_widget = child; + if (child) + gtk_widget_set_parent (child, GTK_WIDGET (self)); +} + +GtkWidget * +gtk_center_box_get_start_widget (GtkCenterBox *self) +{ + return self->start_widget; +} + +GtkWidget * +gtk_center_box_get_center_widget (GtkCenterBox *self) +{ + return self->center_widget; +} + +GtkWidget * +gtk_center_box_get_end_widget (GtkCenterBox *self) +{ + return self->end_widget; +} |