diff options
author | Benjamin Otte <otte@redhat.com> | 2011-05-25 23:38:59 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2011-06-02 02:03:51 +0200 |
commit | cd838480eb01ad8a9185cb1d407088b7eb34d926 (patch) | |
tree | 2b6d75f8c6e363f05411252ebf44958ad2ab9960 /gtk/gtkbox.c | |
parent | bc9c43c1cbb1fdb7faf292ee0e57c5efd06e890e (diff) | |
download | gtk+-cd838480eb01ad8a9185cb1d407088b7eb34d926.tar.gz |
box: Add support for siblings in widget paths of box children
Diffstat (limited to 'gtk/gtkbox.c')
-rw-r--r-- | gtk/gtkbox.c | 126 |
1 files changed, 123 insertions, 3 deletions
diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c index b1d1df952b..0c52a906e3 100644 --- a/gtk/gtkbox.c +++ b/gtk/gtkbox.c @@ -115,6 +115,7 @@ struct _GtkBoxPrivate GtkOrientation orientation; gint16 spacing; + GtkWidgetPath *sibling_path; guint default_expand : 1; guint homogeneous : 1; @@ -182,6 +183,9 @@ static void gtk_box_get_child_property (GtkContainer *container, GValue *value, GParamSpec *pspec); static GType gtk_box_child_type (GtkContainer *container); +static GtkWidgetPath * gtk_box_get_path_for_child + (GtkContainer *container, + GtkWidget *child); static void gtk_box_get_preferred_width (GtkWidget *widget, @@ -226,6 +230,7 @@ gtk_box_class_init (GtkBoxClass *class) container_class->child_type = gtk_box_child_type; container_class->set_child_property = gtk_box_set_child_property; container_class->get_child_property = gtk_box_get_child_property; + container_class->get_path_for_child = gtk_box_get_path_for_child; gtk_container_class_handle_border_width (container_class); g_object_class_override_property (object_class, @@ -831,6 +836,113 @@ gtk_box_get_child_property (GtkContainer *container, } } +typedef struct _CountingData CountingData; +struct _CountingData { + GtkWidget *widget; + gboolean found; + guint count; +}; + +static void +count_widget_position (GtkWidget *widget, + gpointer data) +{ + CountingData *count = data; + +#if 0 + /* We cannot reliably detect changes in widget visibility */ + if (!gtk_widget_get_visible (widget)) + return; +#endif + + if (count->found) + return; + + if (count->widget == widget) + { + count->found = TRUE; + return; + } + + count->count++; +} + +static guint +gtk_box_get_visible_position (GtkBox *box, + GtkWidget *child) +{ + CountingData count = { child, FALSE, 0 }; + + /* forall iterates in visible order */ + gtk_container_forall (GTK_CONTAINER (box), + count_widget_position, + &count); + + g_assert (count.found); + return count.count; +} + +static void +add_widget_to_path (GtkWidget *widget, + gpointer path) +{ +#if 0 + /* We cannot reliably detect changes in widget visibility */ + if (!gtk_widget_get_visible (widget)) + return; +#endif + + gtk_widget_path_append_for_widget (path, widget); +} + +static GtkWidgetPath * +gtk_box_get_path_for_child (GtkContainer *container, + GtkWidget *child) +{ + GtkWidgetPath *path; + GtkBox *box; + GtkBoxPrivate *private; + + box = GTK_BOX (container); + private = box->priv; + + if (private->sibling_path == NULL) + { + private->sibling_path = gtk_widget_path_new (); + /* forall iterates in visible order */ + gtk_container_forall (container, + add_widget_to_path, + private->sibling_path); + } + + path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container))); + if (gtk_widget_get_visible (child)) + gtk_widget_path_append_with_siblings (path, + private->sibling_path, + gtk_box_get_visible_position (box, + child)); + else + gtk_widget_path_append_for_widget (path, child); + + return path; +} + +static void +gtk_box_invalidate_order (GtkBox *box) +{ + GtkBoxPrivate *private = box->priv; + + if (private->sibling_path != NULL) + { + gtk_widget_path_unref (private->sibling_path); + private->sibling_path = NULL; + } + + gtk_container_foreach (GTK_CONTAINER (box), + (GtkCallback) gtk_widget_reset_style, + NULL); +} + static void gtk_box_pack (GtkBox *box, GtkWidget *child, @@ -857,6 +969,7 @@ gtk_box_pack (GtkBox *box, gtk_widget_freeze_child_notify (child); + gtk_box_invalidate_order (box); gtk_widget_set_parent (child, GTK_WIDGET (box)); gtk_widget_child_notify (child, "expand"); @@ -1495,7 +1608,10 @@ gtk_box_reorder_child (GtkBox *box, gtk_widget_child_notify (child, "position"); if (gtk_widget_get_visible (child) && gtk_widget_get_visible (GTK_WIDGET (box))) - gtk_widget_queue_resize (child); + { + gtk_box_invalidate_order (box); + gtk_widget_queue_resize (child); + } } /** @@ -1614,10 +1730,11 @@ gtk_box_set_child_packing (GtkBox *box, gtk_widget_child_notify (child, "padding"); if (pack_type != GTK_PACK_END) pack_type = GTK_PACK_START; - if (child_info->pack_type != pack_type) + if (child_info->pack != pack_type) { child_info->pack = GTK_PACK_END; gtk_widget_child_notify (child, "pack-type"); + gtk_box_invalidate_order (box); } if (gtk_widget_get_visible (child) @@ -1680,7 +1797,10 @@ gtk_box_remove (GtkContainer *container, * since that's what is needed by toplevels. */ if (was_visible) - gtk_widget_queue_resize (GTK_WIDGET (container)); + { + gtk_box_invalidate_order (box); + gtk_widget_queue_resize (GTK_WIDGET (container)); + } break; } |