diff options
author | Matthias Clasen <mclasen@redhat.com> | 2023-04-05 22:23:19 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2023-04-05 22:23:19 +0000 |
commit | 9608e4e503df28e31137f4841409876f5aaf1e0d (patch) | |
tree | 3f5d32d68ce3c7008eed6261b74fed3d03773a55 | |
parent | 1859193c5de0669dc11e38354f4a77d0d7841420 (diff) | |
parent | c40fa8db987496ff788b86dab220968ec2ffb1b8 (diff) | |
download | gtk+-9608e4e503df28e31137f4841409876f5aaf1e0d.tar.gz |
Merge branch 'wip/exalm/centerlayout-shrink' into 'main'
centerlayout/box: Add :shrink-center-last
See merge request GNOME/gtk!5790
-rw-r--r-- | gtk/gtkcenterbox.c | 104 | ||||
-rw-r--r-- | gtk/gtkcenterbox.h | 6 | ||||
-rw-r--r-- | gtk/gtkcenterlayout.c | 135 | ||||
-rw-r--r-- | gtk/gtkcenterlayout.h | 5 |
4 files changed, 240 insertions, 10 deletions
diff --git a/gtk/gtkcenterbox.c b/gtk/gtkcenterbox.c index 367c0eab0b..e76ffc31dd 100644 --- a/gtk/gtkcenterbox.c +++ b/gtk/gtkcenterbox.c @@ -86,6 +86,7 @@ enum { PROP_CENTER_WIDGET, PROP_END_WIDGET, PROP_BASELINE_POSITION, + PROP_SHRINK_CENTER_LAST, /* orientable */ PROP_ORIENTATION, @@ -155,17 +156,21 @@ gtk_center_box_set_property (GObject *object, } break; - case PROP_START_WIDGET: - gtk_center_box_set_start_widget (self, GTK_WIDGET (g_value_get_object (value))); - break; + case PROP_START_WIDGET: + gtk_center_box_set_start_widget (self, GTK_WIDGET (g_value_get_object (value))); + break; - case PROP_CENTER_WIDGET: - gtk_center_box_set_center_widget (self, GTK_WIDGET (g_value_get_object (value))); - break; + case PROP_CENTER_WIDGET: + gtk_center_box_set_center_widget (self, GTK_WIDGET (g_value_get_object (value))); + break; - case PROP_END_WIDGET: - gtk_center_box_set_end_widget (self, GTK_WIDGET (g_value_get_object (value))); - break; + case PROP_END_WIDGET: + gtk_center_box_set_end_widget (self, GTK_WIDGET (g_value_get_object (value))); + break; + + case PROP_SHRINK_CENTER_LAST: + gtk_center_box_set_shrink_center_last (self, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -204,6 +209,10 @@ gtk_center_box_get_property (GObject *object, g_value_set_object (value, self->end_widget); break; + case PROP_SHRINK_CENTER_LAST: + g_value_set_boolean (value, gtk_center_layout_get_shrink_center_last (GTK_CENTER_LAYOUT (layout))); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -289,6 +298,25 @@ gtk_center_box_class_init (GtkCenterBoxClass *klass) GTK_TYPE_WIDGET, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkCenterBox:shrink-center-last: (attributes org.gtk.Property.get=gtk_center_box_get_shrink_center_last org.gtk.Property.set=gtk_center_box_set_shrink_center_last) + * + * Whether to shrink the center widget after other children. + * + * By default, when there's no space to give all three children their + * natural widths, the start and end widgets start shrinking and the + * center child keeps natural width until they reach minimum width. + * + * If set to `TRUE`, start and end widgets keep natural width and the + * center widget starts shrinking instead. + * + * Since: 4.12 + */ + props[PROP_SHRINK_CENTER_LAST] = + g_param_spec_boolean ("shrink-center-last", NULL, NULL, + FALSE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (object_class, LAST_PROP, props); gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CENTER_LAYOUT); @@ -513,3 +541,61 @@ gtk_center_box_get_baseline_position (GtkCenterBox *self) return gtk_center_layout_get_baseline_position (GTK_CENTER_LAYOUT (layout)); } +/** + * gtk_center_box_set_shrink_center_last: (attributes org.gtk.Method.set_property=shrink-center-last) + * @self: a `GtkCenterBox` + * @shrink_center_last: whether to shrink the center widget after others + * + * Sets whether to shrink the center widget after other children. + * + * By default, when there's no space to give all three children their + * natural widths, the start and end widgets start shrinking and the + * center child keeps natural width until they reach minimum width. + * + * If set to `TRUE`, start and end widgets keep natural width and the + * center widget starts shrinking instead. + * + * Since: 4.12 + */ +void +gtk_center_box_set_shrink_center_last (GtkCenterBox *self, + gboolean shrink_center_last) +{ + GtkLayoutManager *layout; + gboolean current_shrink_center_last; + + g_return_if_fail (GTK_IS_CENTER_BOX (self)); + + shrink_center_last = !!shrink_center_last; + + layout = gtk_widget_get_layout_manager (GTK_WIDGET (self)); + current_shrink_center_last = gtk_center_layout_get_shrink_center_last (GTK_CENTER_LAYOUT (layout)); + if (current_shrink_center_last != shrink_center_last) + { + gtk_center_layout_set_shrink_center_last (GTK_CENTER_LAYOUT (layout), shrink_center_last); + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SHRINK_CENTER_LAST]); + gtk_widget_queue_allocate (GTK_WIDGET (self)); + } +} + +/** + * gtk_center_box_get_shrink_center_last: (attributes org.gtk.Method.get_property=shrink-center-last) + * @self: a `GtkCenterBox` + * + * Gets whether @self shrinks the center widget after other children. + * + * Returns: whether to shrink the center widget after others + * + * Since: 4.12 + */ +gboolean +gtk_center_box_get_shrink_center_last (GtkCenterBox *self) +{ + GtkLayoutManager *layout; + + g_return_val_if_fail (GTK_IS_CENTER_BOX (self), FALSE); + + layout = gtk_widget_get_layout_manager (GTK_WIDGET (self)); + + return gtk_center_layout_get_shrink_center_last (GTK_CENTER_LAYOUT (layout)); +} diff --git a/gtk/gtkcenterbox.h b/gtk/gtkcenterbox.h index 1f5831fd79..1003c1524b 100644 --- a/gtk/gtkcenterbox.h +++ b/gtk/gtkcenterbox.h @@ -67,5 +67,11 @@ void gtk_center_box_set_baseline_position (GtkCenterBox *s GDK_AVAILABLE_IN_ALL GtkBaselinePosition gtk_center_box_get_baseline_position (GtkCenterBox *self); +GDK_AVAILABLE_IN_4_12 +void gtk_center_box_set_shrink_center_last (GtkCenterBox *self, + gboolean shrink_center_last); +GDK_AVAILABLE_IN_4_12 +gboolean gtk_center_box_get_shrink_center_last (GtkCenterBox *self); + G_END_DECLS diff --git a/gtk/gtkcenterlayout.c b/gtk/gtkcenterlayout.c index 8d09ce26de..c5eb07eef7 100644 --- a/gtk/gtkcenterlayout.c +++ b/gtk/gtkcenterlayout.c @@ -42,6 +42,7 @@ struct _GtkCenterLayout GtkBaselinePosition baseline_pos; GtkOrientation orientation; + gboolean shrink_center_last; union { struct { @@ -53,6 +54,14 @@ struct _GtkCenterLayout }; }; +enum { + PROP_0, + PROP_SHRINK_CENTER_LAST, + LAST_PROP +}; + +static GParamSpec *props[LAST_PROP] = { NULL, }; + G_DEFINE_TYPE (GtkCenterLayout, gtk_center_layout, GTK_TYPE_LAYOUT_MANAGER) static int @@ -146,7 +155,16 @@ gtk_center_layout_distribute (GtkCenterLayout *self, if (self->center_widget) { - center_size = CLAMP (size - needed_spacing - (sizes[0].minimum_size + sizes[2].minimum_size), sizes[1].minimum_size, sizes[1].natural_size); + int natural_size; + + avail = size - needed_spacing - (sizes[0].minimum_size + sizes[2].minimum_size); + + if (self->shrink_center_last) + natural_size = CLAMP (size - needed_spacing - (sizes[0].natural_size + sizes[2].natural_size), sizes[1].minimum_size, sizes[1].natural_size); + else + natural_size = sizes[1].natural_size; + + center_size = CLAMP (avail, sizes[1].minimum_size, natural_size); center_expand = get_expand (self->center_widget, self->orientation); } @@ -523,6 +541,46 @@ gtk_center_layout_allocate (GtkLayoutManager *layout_manager, } static void +gtk_center_layout_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkCenterLayout *self = GTK_CENTER_LAYOUT (object); + + switch (prop_id) + { + case PROP_SHRINK_CENTER_LAST: + gtk_center_layout_set_shrink_center_last (self, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_center_layout_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkCenterLayout *self = GTK_CENTER_LAYOUT (object); + + switch (prop_id) + { + case PROP_SHRINK_CENTER_LAST: + g_value_set_boolean (value, self->shrink_center_last); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void gtk_center_layout_dispose (GObject *object) { GtkCenterLayout *self = GTK_CENTER_LAYOUT (object); @@ -540,11 +598,34 @@ gtk_center_layout_class_init (GtkCenterLayoutClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass); + object_class->get_property = gtk_center_layout_get_property; + object_class->set_property = gtk_center_layout_set_property; object_class->dispose = gtk_center_layout_dispose; layout_class->get_request_mode = gtk_center_layout_get_request_mode; layout_class->measure = gtk_center_layout_measure; layout_class->allocate = gtk_center_layout_allocate; + + /** + * GtkCenterLayout:shrink-center-last: (attributes org.gtk.Property.get=gtk_center_layout_get_shrink_center_last org.gtk.Property.set=gtk_center_layout_set_shrink_center_last) + * + * Whether to shrink the center widget after other children. + * + * By default, when there's no space to give all three children their + * natural widths, the start and end widgets start shrinking and the + * center child keeps natural width until they reach minimum width. + * + * If set to `TRUE`, start and end widgets keep natural width and the + * center widget starts shrinking instead. + * + * Since: 4.12 + */ + props[PROP_SHRINK_CENTER_LAST] = + g_param_spec_boolean ("shrink-center-last", NULL, NULL, + FALSE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + + g_object_class_install_properties (object_class, LAST_PROP, props); } static void @@ -746,3 +827,55 @@ gtk_center_layout_get_end_widget (GtkCenterLayout *self) return self->end_widget; } + +/** + * gtk_center_layout_set_shrink_center_last: (attributes org.gtk.Method.set_property=shrink-center-last) + * @self: a `GtkCenterLayout` + * @shrink_center_last: whether to shrink the center widget after others + * + * Sets whether to shrink the center widget after other children. + * + * By default, when there's no space to give all three children their + * natural widths, the start and end widgets start shrinking and the + * center child keeps natural width until they reach minimum width. + * + * If set to `TRUE`, start and end widgets keep natural width and the + * center widget starts shrinking instead. + * + * Since: 4.12 + */ +void +gtk_center_layout_set_shrink_center_last (GtkCenterLayout *self, + gboolean shrink_center_last) +{ + g_return_if_fail (GTK_IS_CENTER_LAYOUT (self)); + + shrink_center_last = !!shrink_center_last; + + if (shrink_center_last == self->shrink_center_last) + return; + + self->shrink_center_last = shrink_center_last; + + gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self)); + + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SHRINK_CENTER_LAST]); +} + +/** + * gtk_center_layout_get_shrink_center_last: (attributes org.gtk.Method.get_property=shrink-center-last) + * @self: a `GtkCenterLayout` + * + * Gets whether @self shrinks the center widget after other children. + * + * Returns: whether to shrink the center widget after others + * + * Since: 4.12 + */ +gboolean +gtk_center_layout_get_shrink_center_last (GtkCenterLayout *self) +{ + g_return_val_if_fail (GTK_IS_CENTER_LAYOUT (self), FALSE); + + return self->shrink_center_last; +} diff --git a/gtk/gtkcenterlayout.h b/gtk/gtkcenterlayout.h index dde46ec2e5..3cd88b027d 100644 --- a/gtk/gtkcenterlayout.h +++ b/gtk/gtkcenterlayout.h @@ -54,5 +54,10 @@ void gtk_center_layout_set_end_widget (GtkCenterLayout GDK_AVAILABLE_IN_ALL GtkWidget * gtk_center_layout_get_end_widget (GtkCenterLayout *self); +GDK_AVAILABLE_IN_4_12 +void gtk_center_layout_set_shrink_center_last (GtkCenterLayout *self, + gboolean shrink_center_last); +GDK_AVAILABLE_IN_4_12 +gboolean gtk_center_layout_get_shrink_center_last (GtkCenterLayout *self); G_END_DECLS |