[libdazzle] treenode: add support for reseting a node on collapse



commit cec15114d3a2c326bccdefc68b3cd0b31725d48b
Author: Christian Hergert <chergert redhat com>
Date:   Tue Nov 28 17:01:21 2017 -0800

    treenode: add support for reseting a node on collapse
    
    When a tree node is collapsed, we can reset the node by removing all the
    children and marking it for rebuild. This is useful in situations where
    new files are added in a file-browser and we want things to refresh
    immediately.

 src/tree/dzl-tree-node.c |   51 ++++++++++++++++++++++++++++++++++++++++++++++
 src/tree/dzl-tree-node.h |    5 ++++
 src/tree/dzl-tree.c      |   51 +++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 1 deletions(-)
---
diff --git a/src/tree/dzl-tree-node.c b/src/tree/dzl-tree-node.c
index 75f5273..cdc8e16 100644
--- a/src/tree/dzl-tree-node.c
+++ b/src/tree/dzl-tree-node.c
@@ -41,6 +41,7 @@ struct _DzlTreeNode
   guint              is_dummy : 1;
   guint              children_possible : 1;
   guint              use_dim_label : 1;
+  guint              reset_on_collapse : 1;
 };
 
 typedef struct
@@ -59,6 +60,7 @@ enum {
   PROP_GICON,
   PROP_ITEM,
   PROP_PARENT,
+  PROP_RESET_ON_COLLAPSE,
   PROP_TEXT,
   PROP_TREE,
   PROP_USE_DIM_LABEL,
@@ -732,6 +734,10 @@ dzl_tree_node_get_property (GObject    *object,
       g_value_set_object (value, node->parent);
       break;
 
+    case PROP_RESET_ON_COLLAPSE:
+      g_value_set_boolean (value, node->reset_on_collapse);
+      break;
+
     case PROP_TEXT:
       g_value_set_string (value, node->text);
       break;
@@ -779,6 +785,10 @@ dzl_tree_node_set_property (GObject      *object,
       dzl_tree_node_set_item (node, g_value_get_object (value));
       break;
 
+    case PROP_RESET_ON_COLLAPSE:
+      dzl_tree_node_set_reset_on_collapse (node, g_value_get_boolean (value));
+      break;
+
     case PROP_TEXT:
       dzl_tree_node_set_text (node, g_value_get_string (value));
       break;
@@ -880,6 +890,24 @@ dzl_tree_node_class_init (DzlTreeNodeClass *klass)
                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
   /**
+   * DzlTreeNode:reset-on-collapse:
+   *
+   * The "reset-on-collapse" property denotes that all children should be
+   * removed from the node when it's row is collapsed. It will also set
+   * #DzlTreeNode:needs-build to %TRUE so the next expansion rebuilds the
+   * children. This is useful for situations where you want to ensure the nodes
+   * are up to date (refreshed) on every expansion.
+   *
+   * Since: 3.28
+   */
+  properties [PROP_RESET_ON_COLLAPSE] =
+    g_param_spec_boolean ("reset-on-collapse",
+                          "Reset on Collapse",
+                          "Reset by clearing children on collapse, requiring a rebuild on next expand",
+                          FALSE,
+                          G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+  /**
    * DzlTreeNode:tree:
    *
    * The tree the node belongs to.
@@ -1180,3 +1208,26 @@ _dzl_tree_node_get_expanded_icon (DzlTreeNode *node)
 
   return g_quark_to_string (node->expanded_icon_name);
 }
+
+gboolean
+dzl_tree_node_get_reset_on_collapse (DzlTreeNode *self)
+{
+  g_return_val_if_fail (DZL_IS_TREE_NODE (self), FALSE);
+
+  return self->reset_on_collapse;
+}
+
+void
+dzl_tree_node_set_reset_on_collapse (DzlTreeNode *self,
+                                     gboolean     reset_on_collapse)
+{
+  g_return_if_fail (DZL_IS_TREE_NODE (self));
+
+  reset_on_collapse = !!reset_on_collapse;
+
+  if (reset_on_collapse != self->reset_on_collapse)
+    {
+      self->reset_on_collapse = reset_on_collapse;
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_RESET_ON_COLLAPSE]);
+    }
+}
diff --git a/src/tree/dzl-tree-node.h b/src/tree/dzl-tree-node.h
index fc6e5c2..057de5e 100644
--- a/src/tree/dzl-tree-node.h
+++ b/src/tree/dzl-tree-node.h
@@ -115,6 +115,11 @@ gboolean        dzl_tree_node_get_use_dim_label     (DzlTreeNode            *sel
 DZL_AVAILABLE_IN_ALL
 void            dzl_tree_node_set_use_dim_label     (DzlTreeNode            *self,
                                                      gboolean                use_dim_label);
+DZL_AVAILABLE_IN_3_28
+gboolean        dzl_tree_node_get_reset_on_collapse (DzlTreeNode            *self);
+DZL_AVAILABLE_IN_3_28
+void            dzl_tree_node_set_reset_on_collapse (DzlTreeNode            *self,
+                                                     gboolean                reset_on_collapse);
 
 G_END_DECLS
 
diff --git a/src/tree/dzl-tree.c b/src/tree/dzl-tree.c
index d7502c6..4c9e16f 100644
--- a/src/tree/dzl-tree.c
+++ b/src/tree/dzl-tree.c
@@ -600,8 +600,8 @@ dzl_tree_row_expanded (GtkTreeView *tree_view,
   g_assert (path != NULL);
 
   model = gtk_tree_view_get_model (tree_view);
-
   gtk_tree_model_get (model, iter, 0, &node, -1);
+  g_assert (DZL_IS_TREE_NODE (node));
 
   /*
    * If we are expanding a row that has a dummy child, we might need to
@@ -617,6 +617,54 @@ dzl_tree_row_expanded (GtkTreeView *tree_view,
   g_clear_object (&node);
 }
 
+static void
+dzl_tree_row_collapsed (GtkTreeView *tree_view,
+                        GtkTreeIter *iter,
+                        GtkTreePath *path)
+{
+  DzlTree *self = (DzlTree *)tree_view;
+  DzlTreePrivate *priv = dzl_tree_get_instance_private (self);
+  GtkTreeModel *model;
+  DzlTreeNode *node;
+
+  g_assert (DZL_IS_TREE (self));
+  g_assert (iter != NULL);
+  g_assert (path != NULL);
+
+  model = gtk_tree_view_get_model (tree_view);
+
+  /* Ignore things when we are showing a filter. There isn't a whole lot we
+   * can do here without getting into some weird corner cases, so we'll punt
+   * until someone really asks for the feature.
+   */
+  if (model != GTK_TREE_MODEL (priv->store))
+    return;
+
+  /* Get the node in question */
+  gtk_tree_model_get (model, iter, 0, &node, -1);
+  g_assert (DZL_IS_TREE_NODE (node));
+
+  /*
+   * If we are collapsing a row that requests to have its children removed
+   * and the dummy node re-inserted, go ahead and do so now.
+   */
+  if (dzl_tree_node_get_reset_on_collapse (node))
+    {
+      GtkTreeIter child;
+
+      if (gtk_tree_model_iter_children (model, &child, iter))
+        {
+          while (gtk_tree_store_remove (priv->store, &child))
+            { /* Do Nothing */ }
+        }
+
+      _dzl_tree_node_add_dummy_child (node);
+      _dzl_tree_node_set_needs_build (node, TRUE);
+    }
+
+  g_clear_object (&node);
+}
+
 static gboolean
 dzl_tree_button_press_event (GtkWidget      *widget,
                              GdkEventButton *button)
@@ -925,6 +973,7 @@ dzl_tree_class_init (DzlTreeClass *klass)
 
   tree_view_class->row_activated = dzl_tree_row_activated;
   tree_view_class->row_expanded = dzl_tree_row_expanded;
+  tree_view_class->row_collapsed = dzl_tree_row_collapsed;
 
   klass->action = dzl_tree_real_action;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]