[gnome-builder/wip/lazy-tree: 5/5] tree: use signals for GbTreeBuilder



commit 27d68935c835cfdd3f3d56bc46755247f06effe4
Author: Christian Hergert <christian hergert me>
Date:   Sun Jun 14 12:09:03 2015 -0700

    tree: use signals for GbTreeBuilder
    
    Rather than using vfuncs, lets use signals here so that consumers do not
    need to subclass unless they want to.

 src/tree/gb-tree-builder.c |  184 +++++++++++++++++++++++++++++--------------
 src/tree/gb-tree-builder.h |   13 +---
 src/tree/gb-tree-private.h |   29 ++++++--
 src/tree/gb-tree.c         |   32 +++++---
 4 files changed, 167 insertions(+), 91 deletions(-)
---
diff --git a/src/tree/gb-tree-builder.c b/src/tree/gb-tree-builder.c
index afec38d..050d731 100644
--- a/src/tree/gb-tree-builder.c
+++ b/src/tree/gb-tree-builder.c
@@ -30,107 +30,100 @@ typedef struct
 
 G_DEFINE_TYPE_WITH_PRIVATE (GbTreeBuilder, gb_tree_builder, G_TYPE_INITIALLY_UNOWNED)
 
-enum
-{
+enum {
        PROP_0,
        PROP_TREE,
        LAST_PROP
 };
 
-static GParamSpec *gParamSpecs[LAST_PROP];
+enum {
+  ADDED,
+  REMOVED,
+  BUILD_NODE,
+  NODE_ACTIVATED,
+  NODE_POPUP,
+  NODE_SELECTED,
+  NODE_UNSELECTED,
+  LAST_SIGNAL
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+static guint gSignals [LAST_SIGNAL];
 
-/**
- * gb_tree_builder_node_activated:
- * @builder: (in): A #GbTreeBuilder.
- * @node: (in): A #GbTreeNode.
- *
- * Handle @node being activated. Builders may want to open a view
- * or perform an action on such an event.
- *
- * Returns: %TRUE if the node activation was handled.
- */
 gboolean
-gb_tree_builder_node_activated (GbTreeBuilder *builder,
-                                GbTreeNode    *node)
+_gb_tree_builder_node_activated (GbTreeBuilder *builder,
+                                 GbTreeNode    *node)
 {
+  gboolean ret = FALSE;
+
        g_return_val_if_fail (GB_IS_TREE_BUILDER(builder), FALSE);
        g_return_val_if_fail (GB_IS_TREE_NODE(node), FALSE);
 
-       if (GB_TREE_BUILDER_GET_CLASS (builder)->node_activated)
-               return GB_TREE_BUILDER_GET_CLASS (builder)->node_activated(builder, node);
+  g_signal_emit (builder, gSignals [NODE_ACTIVATED], 0, node, &ret);
 
-       return FALSE;
+       return ret;
 }
 
 void
-gb_tree_builder_node_popup (GbTreeBuilder *builder,
-                            GbTreeNode    *node,
-                            GMenu         *menu)
+_gb_tree_builder_node_popup (GbTreeBuilder *builder,
+                             GbTreeNode    *node,
+                             GMenu         *menu)
 {
   g_return_if_fail (GB_IS_TREE_BUILDER (builder));
   g_return_if_fail (GB_IS_TREE_NODE (node));
   g_return_if_fail (G_IS_MENU (menu));
 
-  if (GB_TREE_BUILDER_GET_CLASS (builder)->node_popup)
-    GB_TREE_BUILDER_GET_CLASS (builder)->node_popup (builder, node, menu);
+  g_signal_emit (builder, gSignals [NODE_POPUP], 0, node, menu);
 }
 
-/**
- * gb_tree_builder_node_selected:
- * @builder: (in): A #GbTreeBuilder.
- * @node: (in): A #GbTreeNode.
- *
- * Update @node for being selected and update any actions or ui based
- * on @node being selected.
- */
 void
-gb_tree_builder_node_selected (GbTreeBuilder *builder,
-                               GbTreeNode    *node)
+_gb_tree_builder_node_selected (GbTreeBuilder *builder,
+                                GbTreeNode    *node)
 {
        g_return_if_fail (GB_IS_TREE_BUILDER (builder));
        g_return_if_fail (GB_IS_TREE_NODE (node));
 
-       if (GB_TREE_BUILDER_GET_CLASS (builder)->node_selected)
-               GB_TREE_BUILDER_GET_CLASS (builder)->node_selected (builder, node);
+  g_signal_emit (builder, gSignals [NODE_SELECTED], 0, node);
 }
 
-/**
- * gb_tree_builder_node_unselected:
- * @builder: (in): A #GbTreeBuilder.
- * @node: (in): A #GbTreeNode.
- *
- * Update @node and any actions that may be related to @node to account
- * for it being unselected within the #GbTree.
- */
 void
-gb_tree_builder_node_unselected (GbTreeBuilder *builder,
-                                 GbTreeNode    *node)
+_gb_tree_builder_node_unselected (GbTreeBuilder *builder,
+                                  GbTreeNode    *node)
 {
        g_return_if_fail (GB_IS_TREE_BUILDER (builder));
        g_return_if_fail (GB_IS_TREE_NODE (node));
 
-       if (GB_TREE_BUILDER_GET_CLASS (builder)->node_selected)
-               GB_TREE_BUILDER_GET_CLASS (builder)->node_unselected (builder, node);
+  g_signal_emit (builder, gSignals [NODE_UNSELECTED], 0, node);
 }
 
-/**
- * gb_tree_builder_build_node:
- * @builder: (in): A #GbTreeBuilder.
- * @node: (in): A #GbTreeNode.
- *
- * Build @node by setting any needed properties for the item or
- * updating it's appearance. Additional actions may be registered
- * based on @node's type if needed.
- */
 void
-gb_tree_builder_build_node (GbTreeBuilder *builder,
-                            GbTreeNode    *node)
+_gb_tree_builder_build_node (GbTreeBuilder *builder,
+                             GbTreeNode    *node)
 {
        g_return_if_fail (GB_IS_TREE_BUILDER (builder));
        g_return_if_fail (GB_IS_TREE_NODE (node));
 
-       if (GB_TREE_BUILDER_GET_CLASS (builder)->build_node)
-               GB_TREE_BUILDER_GET_CLASS (builder)->build_node (builder, node);
+  g_signal_emit (builder, gSignals [BUILD_NODE], 0, node);
+}
+
+void
+_gb_tree_builder_added (GbTreeBuilder *builder,
+                        GbTree        *tree)
+{
+       g_return_if_fail (GB_IS_TREE_BUILDER (builder));
+       g_return_if_fail (GB_IS_TREE (tree));
+
+  g_signal_emit (builder, gSignals [ADDED], 0, tree);
+}
+
+void
+_gb_tree_builder_removed (GbTreeBuilder *builder,
+                          GbTree        *tree)
+{
+       g_return_if_fail (GB_IS_TREE_BUILDER (builder));
+       g_return_if_fail (GB_IS_TREE (tree));
+
+  g_signal_emit (builder, gSignals [REMOVED], 0, tree);
 }
 
 /**
@@ -246,6 +239,77 @@ gb_tree_builder_class_init (GbTreeBuilderClass *klass)
                                    G_PARAM_READWRITE);
 
   g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+
+  gSignals [ADDED] =
+    g_signal_new ("added",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GbTreeBuilderClass, added),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  1,
+                  GB_TYPE_TREE);
+
+  gSignals [BUILD_NODE] =
+    g_signal_new ("build-node",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GbTreeBuilderClass, build_node),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  1,
+                  GB_TYPE_TREE_NODE);
+
+  gSignals [NODE_ACTIVATED] =
+    g_signal_new ("node-activated",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GbTreeBuilderClass, node_activated),
+                  NULL, NULL, NULL,
+                  G_TYPE_BOOLEAN,
+                  1,
+                  GB_TYPE_TREE_NODE);
+
+  gSignals [NODE_POPUP] =
+    g_signal_new ("node-popup",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GbTreeBuilderClass, node_popup),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  2,
+                  GB_TYPE_TREE_NODE,
+                  G_TYPE_MENU);
+
+  gSignals [NODE_SELECTED] =
+    g_signal_new ("node-selected",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GbTreeBuilderClass, node_selected),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  1,
+                  GB_TYPE_TREE_NODE);
+
+  gSignals [NODE_UNSELECTED] =
+    g_signal_new ("node-unselected",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GbTreeBuilderClass, node_unselected),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  1,
+                  GB_TYPE_TREE_NODE);
+
+  gSignals [REMOVED] =
+    g_signal_new ("removed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GbTreeBuilderClass, removed),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  1,
+                  GB_TYPE_TREE);
 }
 
 static void
diff --git a/src/tree/gb-tree-builder.h b/src/tree/gb-tree-builder.h
index 08723f3..6a56a04 100644
--- a/src/tree/gb-tree-builder.h
+++ b/src/tree/gb-tree-builder.h
@@ -47,18 +47,7 @@ struct _GbTreeBuilderClass
                                GMenu         *menu);
 };
 
-GtkWidget *gb_tree_builder_get_tree        (GbTreeBuilder *builder);
-void       gb_tree_builder_build_node      (GbTreeBuilder *builder,
-                                            GbTreeNode    *node);
-gboolean   gb_tree_builder_node_activated  (GbTreeBuilder *builder,
-                                            GbTreeNode    *node);
-void       gb_tree_builder_node_popup      (GbTreeBuilder *builder,
-                                            GbTreeNode    *node,
-                                            GMenu         *menu);
-void       gb_tree_builder_node_selected   (GbTreeBuilder *builder,
-                                            GbTreeNode    *node);
-void       gb_tree_builder_node_unselected (GbTreeBuilder *builder,
-                                            GbTreeNode    *node);
+GtkWidget *gb_tree_builder_get_tree (GbTreeBuilder *builder);
 
 G_END_DECLS
 
diff --git a/src/tree/gb-tree-private.h b/src/tree/gb-tree-private.h
index da00704..df57db0 100644
--- a/src/tree/gb-tree-private.h
+++ b/src/tree/gb-tree-private.h
@@ -23,12 +23,29 @@
 
 G_BEGIN_DECLS
 
-void         _gb_tree_rebuild_node  (GbTree     *tree,
-                                     GbTreeNode *node);
-void         _gb_tree_node_set_tree (GbTreeNode *node,
-                                     GbTree     *tree);
-GtkTreePath *_gb_tree_get_path      (GbTree     *tree,
-                                     GList      *list);
+void         _gb_tree_rebuild_node            (GbTree        *tree,
+                                               GbTreeNode    *node);
+GtkTreePath *_gb_tree_get_path                (GbTree        *tree,
+                                               GList         *list);
+
+void         _gb_tree_node_set_tree           (GbTreeNode    *node,
+                                               GbTree        *tree);
+
+void         _gb_tree_builder_added           (GbTreeBuilder *builder,
+                                               GbTree        *tree);
+void         _gb_tree_builder_removed         (GbTreeBuilder *builder,
+                                               GbTree        *tree);
+void         _gb_tree_builder_build_node      (GbTreeBuilder *builder,
+                                               GbTreeNode    *node);
+gboolean     _gb_tree_builder_node_activated  (GbTreeBuilder *builder,
+                                               GbTreeNode    *node);
+void         _gb_tree_builder_node_popup      (GbTreeBuilder *builder,
+                                               GbTreeNode    *node,
+                                               GMenu         *menu);
+void         _gb_tree_builder_node_selected   (GbTreeBuilder *builder,
+                                               GbTreeNode    *node);
+void         _gb_tree_builder_node_unselected (GbTreeBuilder *builder,
+                                               GbTreeNode    *node);
 
 G_END_DECLS
 
diff --git a/src/tree/gb-tree.c b/src/tree/gb-tree.c
index d721097..b554bab 100644
--- a/src/tree/gb-tree.c
+++ b/src/tree/gb-tree.c
@@ -224,7 +224,7 @@ gb_tree_create_menu (GbTree     *self,
       GbTreeBuilder *builder;
 
       builder = g_ptr_array_index (priv->builders, i);
-      gb_tree_builder_node_popup (builder, node, menu);
+      _gb_tree_builder_node_popup (builder, node, menu);
     }
 
   return menu;
@@ -337,7 +337,7 @@ gb_tree_selection_changed (GbTree           *tree,
       for (i = 0; i < priv->builders->len; i++)
         {
           builder = g_ptr_array_index (priv->builders, i);
-          gb_tree_builder_node_unselected (builder, unselection);
+          _gb_tree_builder_node_unselected (builder, unselection);
         }
     }
 
@@ -349,7 +349,7 @@ gb_tree_selection_changed (GbTree           *tree,
           for (i = 0; i < priv->builders->len; i++)
             {
               builder = g_ptr_array_index (priv->builders, i);
-              gb_tree_builder_node_selected (builder, node);
+              _gb_tree_builder_node_selected (builder, node);
             }
           g_object_unref (node);
         }
@@ -429,7 +429,7 @@ gb_tree_add_builder_foreach_cb (GtkTreeModel *model,
   g_return_val_if_fail (iter != NULL, FALSE);
 
   gtk_tree_model_get (model, iter, 0, &node, -1);
-  gb_tree_builder_build_node (builder, node);
+  _gb_tree_builder_build_node (builder, node);
   g_clear_object (&node);
 
   IDE_RETURN (FALSE);
@@ -548,8 +548,7 @@ gb_tree_add_builder (GbTree        *tree,
       priv->building--;
     }
 
-  if (GB_TREE_BUILDER_GET_CLASS (builder)->added)
-    GB_TREE_BUILDER_GET_CLASS (builder)->added (builder, GTK_WIDGET (tree));
+  _gb_tree_builder_added (builder, tree);
 
   IDE_EXIT;
 }
@@ -566,16 +565,23 @@ gb_tree_remove_builder (GbTree        *tree,
                         GbTreeBuilder *builder)
 {
   GbTreePrivate *priv = gb_tree_get_instance_private (tree);
+  gsize i;
 
   IDE_ENTRY;
 
   g_return_if_fail (GB_IS_TREE (tree));
   g_return_if_fail (GB_IS_TREE_BUILDER (builder));
 
-  if (GB_TREE_BUILDER_GET_CLASS (builder)->removed)
-    GB_TREE_BUILDER_GET_CLASS (builder)->removed (builder, GTK_WIDGET (tree));
-
-  g_ptr_array_remove (priv->builders, builder);
+  for (i = 0; i < priv->builders->len; i++)
+    {
+      if (builder == g_ptr_array_index (priv->builders, i))
+        {
+          g_object_ref (builder);
+          g_ptr_array_remove_index (priv->builders, i);
+          _gb_tree_builder_removed (builder, tree);
+          g_object_unref (builder);
+        }
+    }
 
   IDE_EXIT;
 }
@@ -629,7 +635,7 @@ gb_tree_set_root (GbTree     *tree,
       for (i = 0; i < priv->builders->len; i++)
         {
           builder = g_ptr_array_index (priv->builders, i);
-          gb_tree_builder_build_node (builder, root);
+          _gb_tree_builder_build_node (builder, root);
         }
     }
 
@@ -762,7 +768,7 @@ gb_tree_add (GbTree     *tree,
       for (i = 0; i < priv->builders->len; i++)
         {
           builder = g_ptr_array_index (priv->builders, i);
-          gb_tree_builder_build_node (builder, child);
+          _gb_tree_builder_build_node (builder, child);
         }
     }
 }
@@ -838,7 +844,7 @@ gb_tree_row_activated (GtkTreeView *tree_view,
       for (i = 0; i < priv->builders->len; i++)
         {
           builder = g_ptr_array_index (priv->builders, i);
-          if ((handled = gb_tree_builder_node_activated (builder, node)))
+          if ((handled = _gb_tree_builder_node_activated (builder, node)))
             break;
         }
       g_clear_object (&node);


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