summaryrefslogtreecommitdiff
path: root/gtk/gtkcenterbox.c
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2017-04-22 20:18:17 +0200
committerTimm Bäder <mail@baedert.org>2017-04-25 20:30:37 +0200
commit066c1983ba2c6f1f891e600c561ab03eac2074a6 (patch)
treeb3bd68d270eb6ade9f463f615ab7c4e92c59df2d /gtk/gtkcenterbox.c
parentc92b7d4224b9cef1d08373fcc28f7fbd96c64e6d (diff)
downloadgtk+-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.c226
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;
+}