Add GtkButton:can-shrink
authorEmmanuele Bassi <ebassi@gnome.org>
Fri, 24 Feb 2023 12:28:24 +0000 (12:28 +0000)
committerEmmanuele Bassi <ebassi@gnome.org>
Fri, 14 Apr 2023 14:00:07 +0000 (15:00 +0100)
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
gtk/gtkbutton.h

index e0038973d3a7710b7c52e6dbf6994876b9fd967e..763b9a50ce8d41173ee1091fb5c538f664bc94a0 100644 (file)
@@ -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;
+}
index 799126b63d2c50b87541399c93d394d2690933c5..25ab50d6d74911da397ea84081ba7d1db522d537 100644 (file)
@@ -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