forked from AuroraMiddleware/gtk
box: Add support for siblings in widget paths of box children
This commit is contained in:
parent
bc9c43c1cb
commit
cd838480eb
126
gtk/gtkbox.c
126
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user