diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-04-27 18:14:04 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-05-05 20:40:41 -0400 |
commit | f923e24c72a0f99ec7b0585e63236b2ff4ca1e4e (patch) | |
tree | cdea791b2f8febc0bf2562ec557f6370568e0d63 | |
parent | 539f06147ab238c6186c63827f75ec6b7c84c2cc (diff) | |
download | gtk+-f923e24c72a0f99ec7b0585e63236b2ff4ca1e4e.tar.gz |
boxlayout: Add GtkBoxLayoutChild
Add a layout child for GtkBoxLayout, with an expand
property that can be used to control local expansion
without the propagation of GtkWidget:h/vexpand getting
in the way.
-rw-r--r-- | docs/reference/gtk/gtk4-sections.txt | 5 | ||||
-rw-r--r-- | gtk/gtkboxlayout.c | 168 | ||||
-rw-r--r-- | gtk/gtkboxlayout.h | 11 |
3 files changed, 174 insertions, 10 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 2123854971..16e26c3d2c 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -6668,6 +6668,11 @@ gtk_box_layout_get_spacing gtk_box_layout_set_baseline_position gtk_box_layout_get_baseline_position +<SUBSECTION> +GtkBoxLayoutChild +gtk_box_layout_child_set_expand +gtk_box_layout_child_get_expand + <SUBSECTION Standard> GTK_TYPE_BOX_LAYOUT gtk_box_layout_get_type diff --git a/gtk/gtkboxlayout.c b/gtk/gtkboxlayout.c index 098375973b..dfa5bf2388 100644 --- a/gtk/gtkboxlayout.c +++ b/gtk/gtkboxlayout.c @@ -49,6 +49,139 @@ * you can use the #GtkBoxLayout:spacing property. */ +struct _GtkBoxLayoutChild +{ + GtkLayoutChild parent_instance; + + gboolean expand; +}; + +enum { + PROP_CHILD_EXPAND = 1, + + N_CHILD_PROPERTIES +}; + +static GParamSpec *child_props[N_CHILD_PROPERTIES]; + +G_DEFINE_TYPE (GtkBoxLayoutChild, gtk_box_layout_child, GTK_TYPE_LAYOUT_CHILD) + +static void +gtk_box_layout_child_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkBoxLayoutChild *self = GTK_BOX_LAYOUT_CHILD (gobject); + + switch (prop_id) + { + case PROP_CHILD_EXPAND: + gtk_box_layout_child_set_expand (self, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +gtk_box_layout_child_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkBoxLayoutChild *self = GTK_BOX_LAYOUT_CHILD (gobject); + + switch (prop_id) + { + case PROP_CHILD_EXPAND: + g_value_set_boolean (value, self->expand); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +gtk_box_layout_child_class_init (GtkBoxLayoutChildClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = gtk_box_layout_child_set_property; + gobject_class->get_property = gtk_box_layout_child_get_property; + + /** + * GtkBoxLayoutChild:expand: + * + * Whether the child should receive extra space when the parent grows. + * + * Note that the effective expand value for a child also takes + * the #GtkWidget:hexpand or #GtkWidget:vexpand property into account. + */ + child_props[PROP_CHILD_EXPAND] = + g_param_spec_boolean ("expand", + P_("xpand"), + P_("Whether the child should receive extra space when the parent grows"), + FALSE, + GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + + g_object_class_install_properties (gobject_class, N_CHILD_PROPERTIES, child_props); +} + +static void +gtk_box_layout_child_init (GtkBoxLayoutChild *self) +{ +} + +/** + * gtk_box_layout_child_set_expand: + * @self: a #GtkBoxLayoutChild + * @expand: whether this child should receive extra space when the parent grows + * + * Sets whether the child should receive extra space (beyond its + * natural size) when the parent grows. + * + * Note that the effective expand is determined from this property + * and the #GtkWidget:hexpand or #GtkWidget:vexpand property of the + * child's widget. + */ +void +gtk_box_layout_child_set_expand (GtkBoxLayoutChild *self, + gboolean expand) +{ + g_return_if_fail (GTK_IS_BOX_LAYOUT_CHILD (self)); + + if (self->expand == expand) + return; + + self->expand = expand; + + gtk_layout_manager_layout_changed (gtk_layout_child_get_layout_manager (GTK_LAYOUT_CHILD (self))); + + g_object_notify_by_pspec (G_OBJECT (self), child_props[PROP_CHILD_EXPAND]); +} + +/** + * gtk_box_layout_child_get_expand: + * @self: a #GtkBoxLayoutChild + * + * Determines whether the child should receive extra space (beyond its + * natural size) when the parent grows. + * + * Returns: %TRUE if the child is set to expand + */ +gboolean +gtk_box_layout_child_get_expand (GtkBoxLayoutChild *self) +{ + g_return_val_if_fail (GTK_IS_BOX_LAYOUT_CHILD (self), FALSE); + + return self->expand; +} + struct _GtkBoxLayout { GtkLayoutManager parent_instance; @@ -160,11 +293,27 @@ gtk_box_layout_get_property (GObject *gobject, } } +static gboolean +child_should_expand (GtkBoxLayout *self, + GtkWidget *widget) +{ + GtkLayoutManager *layout; + GtkLayoutChild *child; + + if (gtk_widget_compute_expand (widget, self->orientation)) + return TRUE; + + layout = GTK_LAYOUT_MANAGER (self); + child = gtk_layout_manager_get_layout_child (layout, widget); + + return GTK_BOX_LAYOUT_CHILD (child)->expand; +} + static void -count_expand_children (GtkWidget *widget, - GtkOrientation orientation, - gint *visible_children, - gint *expand_children) +count_expand_children (GtkBoxLayout *self, + GtkWidget *widget, + int *visible_children, + int *expand_children) { GtkWidget *child; @@ -179,7 +328,7 @@ count_expand_children (GtkWidget *widget, *visible_children += 1; - if (gtk_widget_compute_expand (child, orientation)) + if (child_should_expand (self, child)) *expand_children += 1; } } @@ -281,7 +430,7 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self, int spacing; gboolean have_baseline; - count_expand_children (widget, self->orientation, &nvis_children, &nexpand_children); + count_expand_children (self, widget, &nvis_children, &nexpand_children); if (nvis_children <= 0) return; @@ -361,7 +510,7 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self, { child_size = sizes[i].minimum_size; - if (gtk_widget_compute_expand (child, self->orientation)) + if (child_should_expand (self, child)) { child_size += size_given_to_child; @@ -482,7 +631,7 @@ gtk_box_layout_allocate (GtkLayoutManager *layout_manager, gint child_size; gint spacing; - count_expand_children (widget, self->orientation, &nvis_children, &nexpand_children); + count_expand_children (self, widget, &nvis_children, &nexpand_children); /* If there is no visible child, simply return. */ if (nvis_children <= 0) @@ -575,7 +724,7 @@ gtk_box_layout_allocate (GtkLayoutManager *layout_manager, { child_size = sizes[i].minimum_size; - if (gtk_widget_compute_expand (child, self->orientation)) + if (child_should_expand (self, child)) { child_size += size_given_to_child; @@ -701,6 +850,7 @@ gtk_box_layout_class_init (GtkBoxLayoutClass *klass) gobject_class->set_property = gtk_box_layout_set_property; gobject_class->get_property = gtk_box_layout_get_property; + layout_manager_class->layout_child_type = GTK_TYPE_BOX_LAYOUT_CHILD; layout_manager_class->measure = gtk_box_layout_measure; layout_manager_class->allocate = gtk_box_layout_allocate; diff --git a/gtk/gtkboxlayout.h b/gtk/gtkboxlayout.h index 8d394219b7..86f5d308bf 100644 --- a/gtk/gtkboxlayout.h +++ b/gtk/gtkboxlayout.h @@ -27,7 +27,8 @@ G_BEGIN_DECLS -#define GTK_TYPE_BOX_LAYOUT (gtk_box_layout_get_type()) +#define GTK_TYPE_BOX_LAYOUT (gtk_box_layout_get_type()) +#define GTK_TYPE_BOX_LAYOUT_CHILD (gtk_box_layout_child_get_type()) GDK_AVAILABLE_IN_ALL G_DECLARE_FINAL_TYPE (GtkBoxLayout, gtk_box_layout, GTK, BOX_LAYOUT, GtkLayoutManager) @@ -51,4 +52,12 @@ void gtk_box_layout_set_baseline_position (GtkBoxLayout GDK_AVAILABLE_IN_ALL GtkBaselinePosition gtk_box_layout_get_baseline_position (GtkBoxLayout *box_layout); +GDK_AVAILABLE_IN_ALL +G_DECLARE_FINAL_TYPE (GtkBoxLayoutChild, gtk_box_layout_child, GTK, BOX_LAYOUT_CHILD, GtkLayoutChild) + +void gtk_box_layout_child_set_expand (GtkBoxLayoutChild *child, + gboolean expand); +GDK_AVAILABLE_IN_ALL +gboolean gtk_box_layout_child_get_expand (GtkBoxLayoutChild *child); + G_END_DECLS |