[gnome-builder] libide/tweaks: cleanup visitor usage



commit 127b0c32a9356049b9cc0be003dc1e2f7aec0a91
Author: Christian Hergert <chergert redhat com>
Date:   Thu Aug 4 15:55:23 2022 -0700

    libide/tweaks: cleanup visitor usage
    
    We can still probably improve the enum states for accept/recurse and
    possibily a break or something. But this is fine for now.

 src/libide/tweaks/ide-tweaks-factory.c | 67 ++++++++++++++++++++++++++++++
 src/libide/tweaks/ide-tweaks-factory.h | 10 +++--
 src/libide/tweaks/ide-tweaks-item.h    |  2 +-
 src/libide/tweaks/ide-tweaks-model.c   | 27 +++++--------
 src/libide/tweaks/ide-tweaks-panel.c   | 74 +++++++++++++++++-----------------
 5 files changed, 120 insertions(+), 60 deletions(-)
---
diff --git a/src/libide/tweaks/ide-tweaks-factory.c b/src/libide/tweaks/ide-tweaks-factory.c
index 3b116885f..dfe9ffacc 100644
--- a/src/libide/tweaks/ide-tweaks-factory.c
+++ b/src/libide/tweaks/ide-tweaks-factory.c
@@ -220,3 +220,70 @@ _ide_tweaks_factory_inflate (IdeTweaksFactory *self)
 
   return ar;
 }
+
+gboolean
+ide_tweaks_factory_visit (IdeTweaksFactory     *self,
+                          IdeTweaksItemVisitor  visitor,
+                          gpointer              visitor_data)
+{
+  g_autoptr(GListModel) model = NULL;
+  IdeTweaksItem *child;
+  gboolean ret = FALSE;
+  guint n_items;
+
+  g_return_val_if_fail (IDE_IS_TWEAKS_FACTORY (self), FALSE);
+  g_return_val_if_fail (visitor != NULL, FALSE);
+
+  if (!g_set_object (&model, self->model))
+    return FALSE;
+
+  if (!(child = ide_tweaks_item_get_first_child (IDE_TWEAKS_ITEM (self))))
+    return FALSE;
+
+  n_items = g_list_model_get_n_items (model);
+
+  for (guint i = 0; i < n_items; i++)
+    {
+      g_autoptr(GObject) item = g_list_model_get_item (model, i);
+      g_autoptr(IdeTweaksItem) copy = NULL;
+      IdeTweaksItemVisitResult res;
+
+      /* This is sort of where the "magic" happens. We set
+       * #IdeTweaksFactory:item so all of the <binding/> and similar
+       * expressions in the template update. We will snapshot a copy
+       * of that state (without bindings applied) and use it to build
+       * new "clone" objects.
+       *
+       * Those clones will have a surrogate parent applied (a weak
+       * pointer back to the original parent) which is used when
+       * walking back up the tree from the non-original leaves.
+       */
+
+      if (g_set_object (&self->item, item))
+        g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ITEM]);
+
+      copy = ide_tweaks_item_copy (child);
+
+      res = visitor (copy, visitor_data);
+
+      if (res == IDE_TWEAKS_ITEM_VISIT_STOP)
+        {
+          ret = TRUE;
+          break;
+        }
+
+      if (res == IDE_TWEAKS_ITEM_VISIT_RECURSE)
+        {
+          if (ide_tweaks_item_visit_children (copy, visitor, visitor_data))
+            {
+              ret = TRUE;
+              break;
+            }
+        }
+    }
+
+  if (g_set_object (&self->item, NULL))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ITEM]);
+
+  return ret;
+}
diff --git a/src/libide/tweaks/ide-tweaks-factory.h b/src/libide/tweaks/ide-tweaks-factory.h
index fbadef114..8ff6b5885 100644
--- a/src/libide/tweaks/ide-tweaks-factory.h
+++ b/src/libide/tweaks/ide-tweaks-factory.h
@@ -32,9 +32,13 @@ G_DECLARE_FINAL_TYPE (IdeTweaksFactory, ide_tweaks_factory, IDE, TWEAKS_FACTORY,
 IDE_AVAILABLE_IN_ALL
 IdeTweaksFactory *ide_tweaks_factory_new       (void);
 IDE_AVAILABLE_IN_ALL
-GListModel       *ide_tweaks_factory_get_model (IdeTweaksFactory *self);
+GListModel       *ide_tweaks_factory_get_model (IdeTweaksFactory     *self);
 IDE_AVAILABLE_IN_ALL
-void              ide_tweaks_factory_set_model (IdeTweaksFactory *self,
-                                                GListModel       *model);
+void              ide_tweaks_factory_set_model (IdeTweaksFactory     *self,
+                                                GListModel           *model);
+IDE_AVAILABLE_IN_ALL
+gboolean          ide_tweaks_factory_visit     (IdeTweaksFactory     *self,
+                                                IdeTweaksItemVisitor  visitor,
+                                                gpointer              visitor_data);
 
 G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-item.h b/src/libide/tweaks/ide-tweaks-item.h
index 8a0665573..c54462f99 100644
--- a/src/libide/tweaks/ide-tweaks-item.h
+++ b/src/libide/tweaks/ide-tweaks-item.h
@@ -30,7 +30,7 @@ G_BEGIN_DECLS
 
 typedef enum
 {
-  IDE_TWEAKS_ITEM_VISIT_STOP = 0,
+  IDE_TWEAKS_ITEM_VISIT_STOP = 1,
   IDE_TWEAKS_ITEM_VISIT_CONTINUE,
   IDE_TWEAKS_ITEM_VISIT_RECURSE,
   IDE_TWEAKS_ITEM_VISIT_ACCEPT_AND_CONTINUE,
diff --git a/src/libide/tweaks/ide-tweaks-model.c b/src/libide/tweaks/ide-tweaks-model.c
index 298a8392a..1107e7e8b 100644
--- a/src/libide/tweaks/ide-tweaks-model.c
+++ b/src/libide/tweaks/ide-tweaks-model.c
@@ -84,39 +84,30 @@ ide_tweaks_model_populate_cb (IdeTweaksItem *item,
                               gpointer       user_data)
 {
   IdeTweaksModel *self = user_data;
+  IdeTweaksItemVisitResult res;
 
   if (IDE_IS_TWEAKS_FACTORY (item))
     {
-      g_autoptr(GPtrArray) factory_items = _ide_tweaks_factory_inflate (IDE_TWEAKS_FACTORY (item));
-
-      for (guint i = 0; i < factory_items->len; i++)
-        {
-          IdeTweaksItem *factory_item = g_ptr_array_index (factory_items, i);
-
-          if (ide_tweaks_model_populate_cb (factory_item, self) == IDE_TWEAKS_ITEM_VISIT_STOP)
-            return IDE_TWEAKS_ITEM_VISIT_STOP;
-        }
-
+      if (ide_tweaks_factory_visit (IDE_TWEAKS_FACTORY (item),
+                                    ide_tweaks_model_populate_cb,
+                                    self))
+        return IDE_TWEAKS_ITEM_VISIT_STOP;
       return IDE_TWEAKS_ITEM_VISIT_CONTINUE;
     }
 
-  switch (self->visitor (item, self->visitor_data))
+  res = self->visitor (item, self->visitor_data);
+
+  switch (res)
     {
     case IDE_TWEAKS_ITEM_VISIT_ACCEPT_AND_CONTINUE:
       g_ptr_array_add (self->items, g_object_ref (item));
       return IDE_TWEAKS_ITEM_VISIT_CONTINUE;
 
     case IDE_TWEAKS_ITEM_VISIT_RECURSE:
-      if (ide_tweaks_item_visit_children (item, ide_tweaks_model_populate_cb, self))
-        return IDE_TWEAKS_ITEM_VISIT_STOP;
-      return IDE_TWEAKS_ITEM_VISIT_CONTINUE;
-
     case IDE_TWEAKS_ITEM_VISIT_STOP:
-      return IDE_TWEAKS_ITEM_VISIT_STOP;
-
     case IDE_TWEAKS_ITEM_VISIT_CONTINUE:
     default:
-      return IDE_TWEAKS_ITEM_VISIT_CONTINUE;
+      return res;
     }
 
   g_assert_not_reached ();
diff --git a/src/libide/tweaks/ide-tweaks-panel.c b/src/libide/tweaks/ide-tweaks-panel.c
index fae39c827..f86b48c42 100644
--- a/src/libide/tweaks/ide-tweaks-panel.c
+++ b/src/libide/tweaks/ide-tweaks-panel.c
@@ -23,16 +23,17 @@
 #include "config.h"
 
 #include "ide-tweaks-group.h"
-#include "ide-tweaks-model-private.h"
 #include "ide-tweaks-page.h"
 #include "ide-tweaks-panel-private.h"
+#include "ide-tweaks-widget-private.h"
 
 struct _IdeTweaksPanel
 {
-  AdwBin              parent_instance;
-  AdwPreferencesPage *prefs_page;
-  IdeTweaksPage      *page;
-  guint               folded : 1;
+  AdwBin               parent_instance;
+  AdwPreferencesPage  *prefs_page;
+  AdwPreferencesGroup *current_group;
+  IdeTweaksPage       *page;
+  guint                folded : 1;
 };
 
 enum {
@@ -46,35 +47,40 @@ G_DEFINE_FINAL_TYPE (IdeTweaksPanel, ide_tweaks_panel, ADW_TYPE_BIN)
 
 static GParamSpec *properties [N_PROPS];
 
-static void
-ide_tweaks_panel_add_group (IdeTweaksPanel *self,
-                            IdeTweaksGroup *group)
-{
-  AdwPreferencesGroup *prefs_group;
-
-  g_assert (IDE_IS_TWEAKS_PANEL (self));
-  g_assert (IDE_IS_TWEAKS_GROUP (group));
-
-  prefs_group = g_object_new (ADW_TYPE_PREFERENCES_GROUP,
-                              "title", ide_tweaks_group_get_title (group),
-                              NULL);
-  adw_preferences_page_add (self->prefs_page, prefs_group);
-}
-
 static IdeTweaksItemVisitResult
-group_visitor_func (IdeTweaksItem *item,
-                    gpointer       user_data)
+ide_tweaks_panel_visitor_cb (IdeTweaksItem *item,
+                             gpointer       user_data)
 {
   IdeTweaksPanel *self = user_data;
 
   g_assert (IDE_IS_TWEAKS_ITEM (item));
   g_assert (IDE_IS_TWEAKS_PANEL (self));
 
-  if (item == IDE_TWEAKS_ITEM (self->page))
-    return IDE_TWEAKS_ITEM_VISIT_RECURSE;
+  if (FALSE) {}
+  else if (IDE_IS_TWEAKS_GROUP (item))
+    {
+      IdeTweaksGroup *group = IDE_TWEAKS_GROUP (item);
+
+      self->current_group = g_object_new (ADW_TYPE_PREFERENCES_GROUP,
+                            "title", ide_tweaks_group_get_title (group),
+                            NULL);
+      adw_preferences_page_add (self->prefs_page, self->current_group);
 
-  if (IDE_IS_TWEAKS_GROUP (item))
-    return IDE_TWEAKS_ITEM_VISIT_ACCEPT_AND_CONTINUE;
+      return IDE_TWEAKS_ITEM_VISIT_RECURSE;
+    }
+  else if (IDE_IS_TWEAKS_WIDGET (item))
+    {
+      GtkWidget *child = _ide_tweaks_widget_inflate (IDE_TWEAKS_WIDGET (item));
+
+      if (child == NULL)
+        g_critical ("Failed to create widget from #%s",
+                    ide_tweaks_item_get_id (item));
+      else if (self->current_group)
+        g_critical ("Attempt to add #%s without a group!",
+                    ide_tweaks_item_get_id (item));
+      else
+        adw_preferences_group_add (self->current_group, child);
+    }
 
   return IDE_TWEAKS_ITEM_VISIT_CONTINUE;
 }
@@ -82,20 +88,12 @@ group_visitor_func (IdeTweaksItem *item,
 static void
 ide_tweaks_panel_rebuild (IdeTweaksPanel *self)
 {
-  g_autoptr(IdeTweaksModel) model = NULL;
-  guint n_items;
-
+  g_assert (IDE_IS_TWEAKS_PANEL (self));
   g_assert (IDE_IS_TWEAKS_PAGE (self->page));
 
-  model = ide_tweaks_model_new (IDE_TWEAKS_ITEM (self->page), group_visitor_func, self, NULL);
-  n_items = g_list_model_get_n_items (G_LIST_MODEL (model));
-
-  for (guint i = 0; i < n_items; i++)
-    {
-      g_autoptr(IdeTweaksGroup) group = g_list_model_get_item (G_LIST_MODEL (model), i);
-
-      ide_tweaks_panel_add_group (self, group);
-    }
+  ide_tweaks_item_visit_children (IDE_TWEAKS_ITEM (self->page),
+                                  ide_tweaks_panel_visitor_cb,
+                                  self);
 }
 
 static void


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