[gtk+/nth-child: 22/33] box: Add support for siblings in widget paths of box children
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/nth-child: 22/33] box: Add support for siblings in widget paths of box children
- Date: Fri, 27 May 2011 23:05:31 +0000 (UTC)
commit 6ca088a11eb9368ecb8fdf83e16e841f8236a72a
Author: Benjamin Otte <otte redhat com>
Date: Wed May 25 23:38:59 2011 +0200
box: Add support for siblings in widget paths of box children
gtk/gtkbox.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 123 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c
index b1d1df9..0c6a5d9 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
+one_two_three_ah_ah_ah (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),
+ one_two_three_ah_ah_ah,
+ &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;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]