treeexpander: Add hide-expander property
authorCorey Berla <corey@berla.me>
Sun, 27 Nov 2022 05:02:14 +0000 (21:02 -0800)
committerCorey Berla <corey@berla.me>
Mon, 28 Nov 2022 03:36:11 +0000 (19:36 -0800)
When set to TRUE hide-expander hides the expander icon in a
GtkTreeListRow.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4969
gtk/gtktreeexpander.c
gtk/gtktreeexpander.h

index ef404039381b4a5c22dbe066e1744add64e7f9cf..eb0a78f950f7a7379f9b68ea90d8af346dc6bbb3 100644 (file)
  * [method@Gtk.TreeExpander.set_child] sets the widget that displays
  * the actual row contents.
  *
+ * `GtkTreeExpander` can be modified with properties such as [property@Gtk.indent-for-icon],
+ * [property@Gtk.indent-for-depth], and [property@Gtk.hide-expander] to achieve a
+ * different appearance. This can even be done to influence individual rows, for example
+ * by binding the [property@Gtk.hide-expander] property to the treelistrow's model's
+ * item count to hide the expander for rows without children, even if the row is
+ * expandable.
+ *
  * # CSS nodes
  *
  * ```
@@ -85,6 +92,7 @@ struct _GtkTreeExpander
   GtkWidget *expander_icon;
   guint notify_handler;
 
+  gboolean hide_expander;
   gboolean indent_for_icon;
 
   guint expand_timer;
@@ -94,6 +102,7 @@ enum
 {
   PROP_0,
   PROP_CHILD,
+  PROP_HIDE_EXPANDER,
   PROP_ITEM,
   PROP_LIST_ROW,
   PROP_INDENT_FOR_ICON,
@@ -170,7 +179,7 @@ gtk_tree_expander_update_for_list_row (GtkTreeExpander *self)
       guint i, depth;
 
       depth = gtk_tree_list_row_get_depth (self->list_row);
-      if (gtk_tree_list_row_is_expandable (self->list_row))
+      if (gtk_tree_list_row_is_expandable (self->list_row) && !self->hide_expander)
         {
           if (self->expander_icon == NULL)
             {
@@ -394,6 +403,10 @@ gtk_tree_expander_get_property (GObject    *object,
       g_value_set_object (value, self->child);
       break;
 
+    case PROP_HIDE_EXPANDER:
+      g_value_set_boolean (value, gtk_tree_expander_get_hide_expander (self));
+      break;
+
     case PROP_ITEM:
       g_value_take_object (value, gtk_tree_expander_get_item (self));
       break;
@@ -426,6 +439,10 @@ gtk_tree_expander_set_property (GObject      *object,
       gtk_tree_expander_set_child (self, g_value_get_object (value));
       break;
 
+    case PROP_HIDE_EXPANDER:
+      gtk_tree_expander_set_hide_expander (self, g_value_get_boolean (value));
+      break;
+
     case PROP_LIST_ROW:
       gtk_tree_expander_set_list_row (self, g_value_get_object (value));
       break;
@@ -532,6 +549,23 @@ gtk_tree_expander_class_init (GtkTreeExpanderClass *klass)
                          GTK_TYPE_WIDGET,
                          G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
 
+  /**
+   * GtkTreeExpander:hide-expander: (attributes org.gtk.Property.get=gtk_tree_expander_get_hide_expander org.gtk.Property.set=gtk_tree_expander_set_hide_expander)
+   *
+   * Whether the expander icon should be hidden in a GtkTreeListRow.
+   * Note that this property simply hides the icon.  The actions and keybinding
+   * (i.e. collapse and expand) are not affected by this property.
+   *
+   * A common use for this property would be to bind to the number of children in a
+   * GtkTreeListRow's model in order to hide the expander when a row has no children.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_HIDE_EXPANDER] =
+      g_param_spec_boolean ("hide-expander", NULL, NULL,
+                            FALSE,
+                            G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
   /**
    * GtkTreeExpander:item: (attributes org.gtk.Property.get=gtk_tree_expander_get_item)
    *
@@ -891,3 +925,46 @@ gtk_tree_expander_set_indent_for_icon (GtkTreeExpander *self,
 
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INDENT_FOR_ICON]);
 }
+
+/**
+ * gtk_tree_expander_get_hide_expander: (attributes org.gtk.Method.get_property=hide-expander)
+ * @self: a `GtkTreeExpander`
+ *
+ * Gets whether the TreeExpander should be hidden in a GtkTreeListRow.
+ *
+ * Returns: TRUE if the expander icon should be hidden. Otherwise FALSE.
+ *
+ * Since: 4.10
+ */
+gboolean
+gtk_tree_expander_get_hide_expander (GtkTreeExpander *self)
+{
+  g_return_val_if_fail (GTK_IS_TREE_EXPANDER (self), FALSE);
+
+  return self->hide_expander;
+}
+
+/**
+ * gtk_tree_expander_set_hide_expander: (attributes org.gtk.Method.set_property=hide-expander)
+ * @self: a `GtkTreeExpander` widget
+ * @hide_expander: TRUE if the expander should be hidden. Otherwise FALSE.
+ *
+ * Sets whether the expander icon should be visible in a GtkTreeListRow.
+ *
+ * Since: 4.10
+ */
+void
+gtk_tree_expander_set_hide_expander (GtkTreeExpander *self,
+                                     gboolean         hide_expander)
+{
+  g_return_if_fail (GTK_IS_TREE_EXPANDER (self));
+
+  if (hide_expander == self->hide_expander)
+    return;
+
+  self->hide_expander = hide_expander;
+
+  gtk_tree_expander_update_for_list_row (self);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HIDE_EXPANDER]);
+}
index eec33f091f8b18f9d7baeb642d53a72e8370c520..676185b1766c3829928e5f0b10b0398948868cd0 100644 (file)
@@ -55,6 +55,11 @@ gboolean                gtk_tree_expander_get_indent_for_icon (GtkTreeExpander
 GDK_AVAILABLE_IN_4_6
 void                    gtk_tree_expander_set_indent_for_icon (GtkTreeExpander        *self,
                                                                gboolean               indent_for_icon);
+GDK_AVAILABLE_IN_4_10
+gboolean                gtk_tree_expander_get_hide_expander   (GtkTreeExpander *self);
+GDK_AVAILABLE_IN_4_10
+void                    gtk_tree_expander_set_hide_expander   (GtkTreeExpander *self,
+                                                               gboolean         hide_expander);
 
 G_END_DECLS