summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte.benjamin@googlemail.com>2022-11-28 15:53:17 +0000
committerBenjamin Otte <otte.benjamin@googlemail.com>2022-11-28 15:53:17 +0000
commit57ac4740b388db9fbbbfc02f7f71d9137d78da15 (patch)
tree1edf36acdae866e02cdc032290f271b021562113
parent005574b1b22745589ea673c8531a39e6a5b2f571 (diff)
parent72bc97fff551a4d1170cd7336ab85a40d9714ae3 (diff)
downloadgtk+-57ac4740b388db9fbbbfc02f7f71d9137d78da15.tar.gz
Merge branch 'wip/corey/tree-expander' into 'main'
treeexpander: Add hide-expander and indent-for-depth properties Closes #4969 See merge request GNOME/gtk!5268
-rw-r--r--gtk/gtktreeexpander.c187
-rw-r--r--gtk/gtktreeexpander.h32
2 files changed, 186 insertions, 33 deletions
diff --git a/gtk/gtktreeexpander.c b/gtk/gtktreeexpander.c
index ef40403938..cad8c8d8d0 100644
--- a/gtk/gtktreeexpander.c
+++ b/gtk/gtktreeexpander.c
@@ -52,6 +52,13 @@
* [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,8 @@ struct _GtkTreeExpander
GtkWidget *expander_icon;
guint notify_handler;
+ gboolean hide_expander;
+ gboolean indent_for_depth;
gboolean indent_for_icon;
guint expand_timer;
@@ -94,9 +103,11 @@ enum
{
PROP_0,
PROP_CHILD,
+ PROP_HIDE_EXPANDER,
+ PROP_INDENT_FOR_DEPTH,
+ PROP_INDENT_FOR_ICON,
PROP_ITEM,
PROP_LIST_ROW,
- PROP_INDENT_FOR_ICON,
N_PROPS
};
@@ -169,8 +180,8 @@ gtk_tree_expander_update_for_list_row (GtkTreeExpander *self)
GtkWidget *child;
guint i, depth;
- depth = gtk_tree_list_row_get_depth (self->list_row);
- if (gtk_tree_list_row_is_expandable (self->list_row))
+ depth = self->indent_for_depth ? gtk_tree_list_row_get_depth (self->list_row) : 0;
+ if (gtk_tree_list_row_is_expandable (self->list_row) && !self->hide_expander)
{
if (self->expander_icon == NULL)
{
@@ -394,18 +405,26 @@ gtk_tree_expander_get_property (GObject *object,
g_value_set_object (value, self->child);
break;
- case PROP_ITEM:
- g_value_take_object (value, gtk_tree_expander_get_item (self));
+ case PROP_HIDE_EXPANDER:
+ g_value_set_boolean (value, gtk_tree_expander_get_hide_expander (self));
break;
- case PROP_LIST_ROW:
- g_value_set_object (value, self->list_row);
+ case PROP_INDENT_FOR_DEPTH:
+ g_value_set_boolean (value, gtk_tree_expander_get_indent_for_depth (self));
break;
case PROP_INDENT_FOR_ICON:
g_value_set_boolean (value, gtk_tree_expander_get_indent_for_icon (self));
break;
+ case PROP_ITEM:
+ g_value_take_object (value, gtk_tree_expander_get_item (self));
+ break;
+
+ case PROP_LIST_ROW:
+ g_value_set_object (value, self->list_row);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -426,14 +445,22 @@ gtk_tree_expander_set_property (GObject *object,
gtk_tree_expander_set_child (self, g_value_get_object (value));
break;
- case PROP_LIST_ROW:
- gtk_tree_expander_set_list_row (self, g_value_get_object (value));
+ case PROP_HIDE_EXPANDER:
+ gtk_tree_expander_set_hide_expander (self, g_value_get_boolean (value));
+ break;
+
+ case PROP_INDENT_FOR_DEPTH:
+ gtk_tree_expander_set_indent_for_depth (self, g_value_get_boolean (value));
break;
case PROP_INDENT_FOR_ICON:
gtk_tree_expander_set_indent_for_icon (self, g_value_get_boolean (value));
break;
+ case PROP_LIST_ROW:
+ gtk_tree_expander_set_list_row (self, g_value_get_object (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -533,24 +560,33 @@ gtk_tree_expander_class_init (GtkTreeExpanderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
- * GtkTreeExpander:item: (attributes org.gtk.Property.get=gtk_tree_expander_get_item)
+ * GtkTreeExpander:hide-expander: (attributes org.gtk.Property.get=gtk_tree_expander_get_hide_expander org.gtk.Property.set=gtk_tree_expander_set_hide_expander)
*
- * The item held by this expander's row.
+ * 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_ITEM] =
- g_param_spec_object ("item", NULL, NULL,
- G_TYPE_OBJECT,
- G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ properties[PROP_HIDE_EXPANDER] =
+ g_param_spec_boolean ("hide-expander", NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
- * GtkTreeExpander:list-row: (attributes org.gtk.Property.get=gtk_tree_expander_get_list_row org.gtk.Property.set=gtk_tree_expander_set_list_row)
+ * GtkTreeExpander:indent-for-depth: (attributes org.gtk.Property.get=gtk_tree_expander_get_indent_for_depth org.gtk.Property.set=gtk_tree_expander_set_indent_for_depth)
*
- * The list row to track for expander state.
+ * TreeExpander indents the child according to its depth.
+ *
+ * Since: 4.10
*/
- properties[PROP_LIST_ROW] =
- g_param_spec_object ("list-row", NULL, NULL,
- GTK_TYPE_TREE_LIST_ROW,
- G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ properties[PROP_INDENT_FOR_DEPTH] =
+ g_param_spec_boolean ("indent-for-depth", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkTreeExpander:indent-for-icon: (attributes org.gtk.Property.get=gtk_tree_expander_get_indent_for_icon org.gtk.Property.set=gtk_tree_expander_set_indent_for_icon)
@@ -564,6 +600,26 @@ gtk_tree_expander_class_init (GtkTreeExpanderClass *klass)
TRUE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * GtkTreeExpander:item: (attributes org.gtk.Property.get=gtk_tree_expander_get_item)
+ *
+ * The item held by this expander's row.
+ */
+ properties[PROP_ITEM] =
+ g_param_spec_object ("item", NULL, NULL,
+ G_TYPE_OBJECT,
+ G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtkTreeExpander:list-row: (attributes org.gtk.Property.get=gtk_tree_expander_get_list_row org.gtk.Property.set=gtk_tree_expander_set_list_row)
+ *
+ * The list row to track for expander state.
+ */
+ properties[PROP_LIST_ROW] =
+ g_param_spec_object ("list-row", NULL, NULL,
+ GTK_TYPE_TREE_LIST_ROW,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (gobject_class, N_PROPS, properties);
/**
@@ -697,6 +753,7 @@ gtk_tree_expander_init (GtkTreeExpander *self)
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
self->indent_for_icon = TRUE;
+ self->indent_for_depth = TRUE;
controller = gtk_drop_controller_motion_new ();
g_signal_connect (controller, "enter", G_CALLBACK (gtk_tree_expander_drag_enter), self);
@@ -850,6 +907,49 @@ gtk_tree_expander_set_list_row (GtkTreeExpander *self,
}
/**
+ * gtk_tree_expander_get_indent_for_depth: (attributes org.gtk.Method.get_property=indent-for-depth)
+ * @self: a `GtkTreeExpander`
+ *
+ * TreeExpander indents each level of depth with an additional indent.
+ *
+ * Returns: TRUE if the child should be indented . Otherwise FALSE.
+ *
+ * Since: 4.10
+ */
+gboolean
+gtk_tree_expander_get_indent_for_depth (GtkTreeExpander *self)
+{
+ g_return_val_if_fail (GTK_IS_TREE_EXPANDER (self), FALSE);
+
+ return self->indent_for_depth;
+}
+
+/**
+ * gtk_tree_expander_set_indent_for_depth: (attributes org.gtk.Method.set_property=indent-for-depth)
+ * @self: a `GtkTreeExpander` widget
+ * @indent_for_depth: TRUE if the child should be indented. Otherwise FALSE.
+ *
+ * Sets if the TreeExpander should indent the child according to its depth.
+ *
+ * Since: 4.10
+ */
+void
+gtk_tree_expander_set_indent_for_depth (GtkTreeExpander *self,
+ gboolean indent_for_depth)
+{
+ g_return_if_fail (GTK_IS_TREE_EXPANDER (self));
+
+ if (indent_for_depth == self->indent_for_depth)
+ return;
+
+ self->indent_for_depth = indent_for_depth;
+
+ gtk_tree_expander_update_for_list_row (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INDENT_FOR_DEPTH]);
+}
+
+/**
* gtk_tree_expander_get_indent_for_icon: (attributes org.gtk.Method.get_property=indent-for-icon)
* @self: a `GtkTreeExpander`
*
@@ -878,7 +978,7 @@ gtk_tree_expander_get_indent_for_icon (GtkTreeExpander *self)
*/
void
gtk_tree_expander_set_indent_for_icon (GtkTreeExpander *self,
- gboolean indent_for_icon)
+ gboolean indent_for_icon)
{
g_return_if_fail (GTK_IS_TREE_EXPANDER (self));
@@ -891,3 +991,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]);
+}
diff --git a/gtk/gtktreeexpander.h b/gtk/gtktreeexpander.h
index eec33f091f..bb4db67a4a 100644
--- a/gtk/gtktreeexpander.h
+++ b/gtk/gtktreeexpander.h
@@ -35,26 +35,36 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkTreeExpander, gtk_tree_expander, GTK, TREE_EXPANDER, GtkWidget)
GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_tree_expander_new (void);
+GtkWidget * gtk_tree_expander_new (void);
GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_tree_expander_get_child (GtkTreeExpander *self);
+GtkWidget * gtk_tree_expander_get_child (GtkTreeExpander *self);
GDK_AVAILABLE_IN_ALL
-void gtk_tree_expander_set_child (GtkTreeExpander *self,
- GtkWidget *child);
+void gtk_tree_expander_set_child (GtkTreeExpander *self,
+ GtkWidget *child);
GDK_AVAILABLE_IN_ALL
-gpointer gtk_tree_expander_get_item (GtkTreeExpander *self);
+gpointer gtk_tree_expander_get_item (GtkTreeExpander *self);
GDK_AVAILABLE_IN_ALL
-GtkTreeListRow * gtk_tree_expander_get_list_row (GtkTreeExpander *self);
+GtkTreeListRow * gtk_tree_expander_get_list_row (GtkTreeExpander *self);
GDK_AVAILABLE_IN_ALL
-void gtk_tree_expander_set_list_row (GtkTreeExpander *self,
- GtkTreeListRow *list_row);
+void gtk_tree_expander_set_list_row (GtkTreeExpander *self,
+ GtkTreeListRow *list_row);
+GDK_AVAILABLE_IN_4_10
+gboolean gtk_tree_expander_get_indent_for_depth (GtkTreeExpander *self);
+GDK_AVAILABLE_IN_4_10
+void gtk_tree_expander_set_indent_for_depth (GtkTreeExpander *self,
+ gboolean indent_for_depth);
GDK_AVAILABLE_IN_4_6
-gboolean gtk_tree_expander_get_indent_for_icon (GtkTreeExpander *self);
+gboolean gtk_tree_expander_get_indent_for_icon (GtkTreeExpander *self);
GDK_AVAILABLE_IN_4_6
-void gtk_tree_expander_set_indent_for_icon (GtkTreeExpander *self,
- gboolean indent_for_icon);
+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