[gtk+/wip/baedert/children: 347/365] widget: Add children and sibling pointers



commit be2dbd9bbe617f5a2960a643e3c4b28cd528711e
Author: Timm Bäder <mail baedert org>
Date:   Fri Nov 18 09:29:52 2016 +0100

    widget: Add children and sibling pointers
    
    and a (private) way to access them. We will later use these pointers to
    manage children of non-container widgets and containers alike.

 gtk/gtkwidget.c        |   79 ++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkwidget.h        |    9 +++++
 gtk/gtkwidgetprivate.h |   38 +++++++++++++++++++++--
 3 files changed, 123 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 8b52b6c..91a5d67 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -3784,6 +3784,10 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
   priv->alpha = 255;
   priv->window = NULL;
   priv->parent = NULL;
+  priv->first_child = NULL;
+  priv->last_child = NULL;
+  priv->prev_sibling = NULL;
+  priv->next_sibling = NULL;
 
   priv->sensitive = TRUE;
   priv->redraw_on_alloc = TRUE;
@@ -4027,7 +4031,22 @@ gtk_widget_unparent (GtkWidget *widget)
   priv->child_visible = TRUE;
 
   old_parent = priv->parent;
+  if (old_parent)
+    {
+      if (old_parent->priv->first_child == widget)
+        old_parent->priv->first_child = priv->next_sibling;
+
+      if (old_parent->priv->last_child == widget)
+        old_parent->priv->last_child = priv->prev_sibling;
+
+      if (priv->prev_sibling)
+        priv->prev_sibling->priv->next_sibling = priv->next_sibling;
+      if (priv->next_sibling)
+        priv->next_sibling->priv->prev_sibling = priv->prev_sibling;
+    }
   priv->parent = NULL;
+  priv->prev_sibling = NULL;
+  priv->next_sibling = NULL;
 
   /* parent may no longer expand if the removed
    * child was expand=TRUE and could therefore
@@ -8395,6 +8414,15 @@ gtk_widget_set_parent (GtkWidget *widget,
   gtk_widget_push_verify_invariants (widget);
 
   priv->parent = parent;
+  if (parent)
+    {
+      priv->prev_sibling = parent->priv->last_child;
+      if (parent->priv->last_child)
+        parent->priv->last_child->priv->next_sibling = widget;
+      parent->priv->last_child = widget;
+      if (!parent->priv->first_child)
+        parent->priv->first_child = widget;
+    }
 
   parent_flags = _gtk_widget_get_state_flags (parent);
 
@@ -15655,3 +15683,54 @@ gtk_widget_render (GtkWidget            *widget,
 
   gsk_renderer_end_draw_frame (renderer, context);
 }
+
+GtkWidget *
+gtk_widget_get_first_child (GtkWidget *widget)
+{
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  return widget->priv->first_child;
+}
+
+GtkWidget *
+gtk_widget_get_last_child (GtkWidget *widget)
+{
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  return widget->priv->last_child;
+}
+
+GtkWidget *
+gtk_widget_get_next_sibling (GtkWidget *widget)
+{
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  return widget->priv->next_sibling;
+}
+
+GtkWidget *
+gtk_widget_get_prev_sibling (GtkWidget *widget)
+{
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  return widget->priv->prev_sibling;
+}
+
+void
+gtk_widget_forall (GtkWidget   *widget,
+                   GtkCallback  callback,
+                   gpointer     user_data)
+{
+  GtkWidget *child;
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  child = gtk_widget_get_first_child (widget);
+  while (child)
+    {
+      GtkWidget *next = gtk_widget_get_next_sibling (child);
+
+      callback(child, user_data);
+
+      child = next;
+    }
+}
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 1511742..ed3bfbb 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -1254,6 +1254,15 @@ void                    gtk_widget_set_font_map         (GtkWidget             *
 GDK_AVAILABLE_IN_3_18
 PangoFontMap *          gtk_widget_get_font_map         (GtkWidget             *widget);
 
+GDK_AVAILABLE_IN_3_90
+GtkWidget *             gtk_widget_get_first_child      (GtkWidget *widget);
+GDK_AVAILABLE_IN_3_90
+GtkWidget *             gtk_widget_get_last_child       (GtkWidget *widget);
+GDK_AVAILABLE_IN_3_90
+GtkWidget *             gtk_widget_get_next_sibling     (GtkWidget *widget);
+GDK_AVAILABLE_IN_3_90
+GtkWidget *             gtk_widget_get_prev_sibling     (GtkWidget *widget);
+
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free)
 
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index aea3534..c19dd2a 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -149,12 +149,16 @@ struct _GtkWidgetPrivate
   GdkWindow *window;
   GList *registered_windows;
 
-  /* The widget's parent */
-  GtkWidget *parent;
-
   GList *event_controllers;
 
   AtkObject *accessible;
+
+  /* Widget tree */
+  GtkWidget *parent;
+  GtkWidget *prev_sibling;
+  GtkWidget *next_sibling;
+  GtkWidget *first_child;
+  GtkWidget *last_child;
 };
 
 GtkCssNode *  gtk_widget_get_css_node       (GtkWidget *widget);
@@ -296,6 +300,10 @@ void              gtk_widget_adjust_baseline_request       (GtkWidget *widget,
                                                             gint      *minimum_baseline,
                                                             gint      *natural_baseline);
 
+void              gtk_widget_forall                        (GtkWidget            *widget,
+                                                            GtkCallback           callback,
+                                                            gpointer              user_data);
+
 /* inline getters */
 
 static inline gboolean
@@ -406,6 +414,30 @@ _gtk_widget_get_allocation (GtkWidget     *widget,
   *allocation = widget->priv->allocation;
 }
 
+static inline GtkWidget *
+_gtk_widget_get_prev_sibling (GtkWidget *widget)
+{
+  return widget->priv->prev_sibling;
+}
+
+static inline GtkWidget *
+_gtk_widget_get_next_sibling (GtkWidget *widget)
+{
+  return widget->priv->next_sibling;
+}
+
+static inline GtkWidget *
+_gtk_widget_get_first_child (GtkWidget *widget)
+{
+  return widget->priv->first_child;
+}
+
+static inline GtkWidget *
+_gtk_widget_get_last_child (GtkWidget *widget)
+{
+  return widget->priv->last_child;
+}
+
 G_END_DECLS
 
 #endif /* __GTK_WIDGET_PRIVATE_H__ */


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