From 4ea818fee628b4207b73bc5a474d2aeb0f49b1e2 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 24 Feb 2023 12:28:24 +0000 Subject: [PATCH 1/2] Add GtkButton:can-shrink For certain kinds of layouts, especially ones where one or both sizes of a top level is constrained by physical limits, it's acceptable to have buttons that rely on the minimum size of their contents, rather than the natural size. It is left to the application authors, or the localization teams, to ensure that things like translations and font sizes do not result in a broken UI. --- gtk/gtkbutton.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ gtk/gtkbutton.h | 8 +++- 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index e0038973d3..763b9a50ce 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -94,6 +94,7 @@ struct _GtkButtonPrivate guint button_down : 1; guint use_underline : 1; guint child_type : 2; + guint can_shrink : 1; }; enum { @@ -109,6 +110,7 @@ enum { PROP_USE_UNDERLINE, PROP_ICON_NAME, PROP_CHILD, + PROP_CAN_SHRINK, /* actionable properties */ PROP_ACTION_NAME, @@ -260,6 +262,24 @@ gtk_button_class_init (GtkButtonClass *klass) GTK_TYPE_WIDGET, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkButton:can-shrink: + * + * Whether the size of the button can be made smaller than the natural + * size of its contents. + * + * For text buttons, setting this property will allow ellipsizing the label. + * + * If the contents of a button are an icon or a custom widget, setting this + * property has no effect. + * + * Since: 4.12 + */ + props[PROP_CAN_SHRINK] = + g_param_spec_boolean ("can-shrink", NULL, NULL, + FALSE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, LAST_PROP, props); g_object_class_override_property (gobject_class, PROP_ACTION_NAME, "action-name"); @@ -510,6 +530,9 @@ gtk_button_set_property (GObject *object, case PROP_CHILD: gtk_button_set_child (button, g_value_get_object (value)); break; + case PROP_CAN_SHRINK: + gtk_button_set_can_shrink (button, g_value_get_boolean (value)); + break; case PROP_ACTION_NAME: gtk_button_set_action_name (GTK_ACTIONABLE (button), g_value_get_string (value)); break; @@ -548,6 +571,9 @@ gtk_button_get_property (GObject *object, case PROP_CHILD: g_value_set_object (value, priv->child); break; + case PROP_CAN_SHRINK: + g_value_set_boolean (value, priv->can_shrink); + break; case PROP_ACTION_NAME: g_value_set_string (value, gtk_action_helper_get_action_name (priv->action_helper)); break; @@ -837,6 +863,10 @@ gtk_button_set_label (GtkButton *button, } gtk_label_set_label (GTK_LABEL (priv->child), label); + gtk_label_set_ellipsize (GTK_LABEL (priv->child), + priv->can_shrink ? PANGO_ELLIPSIZE_END + : PANGO_ELLIPSIZE_NONE); + gtk_button_set_child_type (button, LABEL_CHILD); gtk_accessible_update_property (GTK_ACCESSIBLE (button), @@ -1067,3 +1097,73 @@ gtk_button_get_child (GtkButton *button) return priv->child; } + +/** + * gtk_button_set_can_shrink: + * @button: a button + * @can_shrink: whether the button can shrink + * + * Sets whether the button size can be smaller than the natural size of + * its contents. + * + * For text buttons, setting @can_shrink to true will ellipsize the label. + * + * For icons and custom children, this function has no effect. + * + * Since: 4.12 + */ +void +gtk_button_set_can_shrink (GtkButton *button, + gboolean can_shrink) +{ + GtkButtonPrivate *priv = gtk_button_get_instance_private (button); + + g_return_if_fail (GTK_IS_BUTTON (button)); + + can_shrink = !!can_shrink; + + if (priv->can_shrink != can_shrink) + { + priv->can_shrink = can_shrink; + + switch (priv->child_type) + { + case LABEL_CHILD: + gtk_label_set_ellipsize (GTK_LABEL (priv->child), + priv->can_shrink ? PANGO_ELLIPSIZE_END + : PANGO_ELLIPSIZE_NONE); + break; + + case ICON_CHILD: + case WIDGET_CHILD: + break; + + default: + g_assert_not_reached (); + break; + } + + g_object_notify_by_pspec (G_OBJECT (button), props[PROP_CAN_SHRINK]); + } +} + +/** + * gtk_button_get_can_shrink: + * @button: a button + * + * Retrieves whether the button can be smaller than the natural + * size of its contents. + * + * Returns: true if the button can shrink, and false otherwise + * + * Since: 4.12 + */ +gboolean +gtk_button_get_can_shrink (GtkButton *button) +{ + GtkButtonPrivate *priv = gtk_button_get_instance_private (button); + + g_return_val_if_fail (GTK_IS_BUTTON (button), FALSE); + + return priv->can_shrink; +} diff --git a/gtk/gtkbutton.h b/gtk/gtkbutton.h index 799126b63d..25ab50d6d7 100644 --- a/gtk/gtkbutton.h +++ b/gtk/gtkbutton.h @@ -93,7 +93,7 @@ GDK_AVAILABLE_IN_ALL void gtk_button_set_label (GtkButton *button, const char *label); GDK_AVAILABLE_IN_ALL -const char * gtk_button_get_label (GtkButton *button); +const char * gtk_button_get_label (GtkButton *button); GDK_AVAILABLE_IN_ALL void gtk_button_set_use_underline (GtkButton *button, gboolean use_underline); @@ -112,6 +112,12 @@ void gtk_button_set_child (GtkButton *button, GDK_AVAILABLE_IN_ALL GtkWidget * gtk_button_get_child (GtkButton *button); +GDK_AVAILABLE_IN_4_12 +void gtk_button_set_can_shrink (GtkButton *button, + gboolean can_shrink); +GDK_AVAILABLE_IN_4_12 +gboolean gtk_button_get_can_shrink (GtkButton *button); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkButton, g_object_unref) G_END_DECLS From e28676869e5b4dc9d1431329c537740bd4348f27 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 14 Apr 2023 13:08:13 +0100 Subject: [PATCH 2/2] Add GtkMenuButton:can-shrink Map the GtkMenuButton property to the underlying GtkButton widget. --- gtk/gtkmenubutton.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ gtk/gtkmenubutton.h | 11 +++++-- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/gtk/gtkmenubutton.c b/gtk/gtkmenubutton.c index ad723aa38b..e6870523b5 100644 --- a/gtk/gtkmenubutton.c +++ b/gtk/gtkmenubutton.c @@ -128,6 +128,7 @@ struct _GtkMenuButton gboolean always_show_arrow; gboolean primary; + gboolean can_shrink; }; struct _GtkMenuButtonClass @@ -151,6 +152,7 @@ enum PROP_PRIMARY, PROP_CHILD, PROP_ACTIVE, + PROP_CAN_SHRINK, LAST_PROP }; @@ -212,6 +214,9 @@ gtk_menu_button_set_property (GObject *object, case PROP_ACTIVE: gtk_menu_button_set_active (self, g_value_get_boolean (value)); break; + case PROP_CAN_SHRINK: + gtk_menu_button_set_can_shrink (self, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -260,6 +265,9 @@ gtk_menu_button_get_property (GObject *object, case PROP_ACTIVE: g_value_set_boolean (value, gtk_menu_button_get_active (self)); break; + case PROP_CAN_SHRINK: + g_value_set_boolean (value, gtk_menu_button_get_can_shrink (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -534,6 +542,19 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass) FALSE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkMenuButton:can-shrink: (attributes org.gtk.Property.get=gtk_menu_button_get_can_shrink org.gtk.Property.set=gtk_menu_button_set_can_shrink) + * + * Whether the size of the button can be made smaller than the natural + * size of its contents. + * + * Since: 4.12 + */ + menu_button_props[PROP_CAN_SHRINK] = + g_param_spec_boolean ("can-shrink", NULL, NULL, + FALSE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, LAST_PROP, menu_button_props); /** @@ -1150,6 +1171,9 @@ gtk_menu_button_set_label (GtkMenuButton *menu_button, gtk_label_set_xalign (GTK_LABEL (label_widget), 0); gtk_label_set_use_underline (GTK_LABEL (label_widget), gtk_button_get_use_underline (GTK_BUTTON (menu_button->button))); + gtk_label_set_ellipsize (GTK_LABEL (label_widget), + menu_button->can_shrink ? PANGO_ELLIPSIZE_END + : PANGO_ELLIPSIZE_NONE); gtk_widget_set_hexpand (label_widget, TRUE); gtk_widget_set_halign (label_widget, GTK_ALIGN_CENTER); arrow = gtk_builtin_icon_new ("arrow"); @@ -1566,3 +1590,59 @@ gtk_menu_button_get_active (GtkMenuButton *menu_button) return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (menu_button->button)); } + +/** + * gtk_menu_button_set_can_shrink: + * @menu_button: a menu button + * @can_shrink: whether the button can shrink + * + * Sets whether the button size can be smaller than the natural size of + * its contents. + * + * For text buttons, setting @can_shrink to true will ellipsize the label. + * + * For icon buttons, this function has no effect. + * + * Since: 4.12 + */ +void +gtk_menu_button_set_can_shrink (GtkMenuButton *menu_button, + gboolean can_shrink) +{ + g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button)); + + can_shrink = !!can_shrink; + + if (menu_button->can_shrink == can_shrink) + return; + + menu_button->can_shrink = can_shrink; + + if (menu_button->label_widget != NULL) + { + gtk_label_set_ellipsize (GTK_LABEL (menu_button->label_widget), + can_shrink ? PANGO_ELLIPSIZE_END + : PANGO_ELLIPSIZE_NONE); + } + + g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_CAN_SHRINK]); +} + +/** + * gtk_menu_button_get_can_shrink: + * @menu_button: a button + * + * Retrieves whether the button can be smaller than the natural + * size of its contents. + * + * Returns: true if the button can shrink, and false otherwise + * + * Since: 4.12 + */ +gboolean +gtk_menu_button_get_can_shrink (GtkMenuButton *menu_button) +{ + g_return_val_if_fail (GTK_IS_MENU_BUTTON (menu_button), FALSE); + + return menu_button->can_shrink; +} diff --git a/gtk/gtkmenubutton.h b/gtk/gtkmenubutton.h index 566f592d35..5b2e3322b4 100644 --- a/gtk/gtkmenubutton.h +++ b/gtk/gtkmenubutton.h @@ -127,10 +127,17 @@ GDK_AVAILABLE_IN_4_6 GtkWidget * gtk_menu_button_get_child (GtkMenuButton *menu_button); GDK_AVAILABLE_IN_4_10 -void gtk_menu_button_set_active (GtkMenuButton *menu_button, +void gtk_menu_button_set_active (GtkMenuButton *menu_button, gboolean active); GDK_AVAILABLE_IN_4_10 -gboolean gtk_menu_button_get_active (GtkMenuButton *menu_button); +gboolean gtk_menu_button_get_active (GtkMenuButton *menu_button); + +GDK_AVAILABLE_IN_4_12 +void gtk_menu_button_set_can_shrink (GtkMenuButton *menu_button, + gboolean can_shrink); +GDK_AVAILABLE_IN_4_12 +gboolean gtk_menu_button_get_can_shrink (GtkMenuButton *menu_button); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuButton, g_object_unref)