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.
This commit is contained in:
Timm Bäder 2016-11-18 09:29:52 +01:00
parent 626868c7ba
commit 1e031cba99
3 changed files with 123 additions and 3 deletions

View File

@ -3784,6 +3784,10 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
priv->alpha = 255; priv->alpha = 255;
priv->window = NULL; priv->window = NULL;
priv->parent = NULL; priv->parent = NULL;
priv->first_child = NULL;
priv->last_child = NULL;
priv->prev_sibling = NULL;
priv->next_sibling = NULL;
priv->sensitive = TRUE; priv->sensitive = TRUE;
priv->redraw_on_alloc = TRUE; priv->redraw_on_alloc = TRUE;
@ -4027,7 +4031,22 @@ gtk_widget_unparent (GtkWidget *widget)
priv->child_visible = TRUE; priv->child_visible = TRUE;
old_parent = priv->parent; 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->parent = NULL;
priv->prev_sibling = NULL;
priv->next_sibling = NULL;
/* parent may no longer expand if the removed /* parent may no longer expand if the removed
* child was expand=TRUE and could therefore * child was expand=TRUE and could therefore
@ -8395,6 +8414,15 @@ gtk_widget_set_parent (GtkWidget *widget,
gtk_widget_push_verify_invariants (widget); gtk_widget_push_verify_invariants (widget);
priv->parent = parent; 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); parent_flags = _gtk_widget_get_state_flags (parent);
@ -15655,3 +15683,54 @@ gtk_widget_render (GtkWidget *widget,
gsk_renderer_end_draw_frame (renderer, context); 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;
}
}

View File

@ -1254,6 +1254,15 @@ void gtk_widget_set_font_map (GtkWidget *
GDK_AVAILABLE_IN_3_18 GDK_AVAILABLE_IN_3_18
PangoFontMap * gtk_widget_get_font_map (GtkWidget *widget); 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(GtkWidget, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free)

View File

@ -149,12 +149,16 @@ struct _GtkWidgetPrivate
GdkWindow *window; GdkWindow *window;
GList *registered_windows; GList *registered_windows;
/* The widget's parent */
GtkWidget *parent;
GList *event_controllers; GList *event_controllers;
AtkObject *accessible; 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); GtkCssNode * gtk_widget_get_css_node (GtkWidget *widget);
@ -296,6 +300,10 @@ void gtk_widget_adjust_baseline_request (GtkWidget *widget,
gint *minimum_baseline, gint *minimum_baseline,
gint *natural_baseline); gint *natural_baseline);
void gtk_widget_forall (GtkWidget *widget,
GtkCallback callback,
gpointer user_data);
/* inline getters */ /* inline getters */
static inline gboolean static inline gboolean
@ -406,6 +414,30 @@ _gtk_widget_get_allocation (GtkWidget *widget,
*allocation = widget->priv->allocation; *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 G_END_DECLS
#endif /* __GTK_WIDGET_PRIVATE_H__ */ #endif /* __GTK_WIDGET_PRIVATE_H__ */