fixed: Remove child list

Use the child widget list from GtkWidget and attach x/y positions via a
qdata.
This commit is contained in:
Timm Bäder 2018-07-05 19:06:48 +02:00
parent 4dd1ff6dd2
commit da8050979e
2 changed files with 64 additions and 116 deletions

View File

@ -80,11 +80,12 @@
#include "gtkprivate.h" #include "gtkprivate.h"
#include "gtkintl.h" #include "gtkintl.h"
typedef struct typedef struct
{ {
GList *children; GtkWidget *widget;
} GtkFixedPrivate; gint x;
gint y;
} GtkFixedChild;
enum { enum {
CHILD_PROP_0, CHILD_PROP_0,
@ -92,6 +93,8 @@ enum {
CHILD_PROP_Y CHILD_PROP_Y
}; };
static GQuark child_data_quark = 0;
static void gtk_fixed_measure (GtkWidget *widget, static void gtk_fixed_measure (GtkWidget *widget,
GtkOrientation orientation, GtkOrientation orientation,
int for_size, int for_size,
@ -124,7 +127,15 @@ static void gtk_fixed_get_child_property (GtkContainer *container,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
G_DEFINE_TYPE_WITH_PRIVATE (GtkFixed, gtk_fixed, GTK_TYPE_CONTAINER) G_DEFINE_TYPE (GtkFixed, gtk_fixed, GTK_TYPE_CONTAINER)
static GtkFixedChild *
get_fixed_child (GtkWidget *widget)
{
g_assert (GTK_IS_FIXED (gtk_widget_get_parent (widget)));
return (GtkFixedChild *) g_object_get_qdata (G_OBJECT (widget), child_data_quark);
}
static void static void
gtk_fixed_class_init (GtkFixedClass *class) gtk_fixed_class_init (GtkFixedClass *class)
@ -160,6 +171,8 @@ gtk_fixed_class_init (GtkFixedClass *class)
P_("Y position of child widget"), P_("Y position of child widget"),
G_MININT, G_MAXINT, 0, G_MININT, G_MAXINT, 0,
GTK_PARAM_READWRITE)); GTK_PARAM_READWRITE));
child_data_quark = g_quark_from_static_string ("gtk-fixed-child-data");
} }
static GType static GType
@ -171,10 +184,6 @@ gtk_fixed_child_type (GtkContainer *container)
static void static void
gtk_fixed_init (GtkFixed *fixed) gtk_fixed_init (GtkFixed *fixed)
{ {
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
priv->children = NULL;
gtk_widget_set_has_surface (GTK_WIDGET (fixed), FALSE); gtk_widget_set_has_surface (GTK_WIDGET (fixed), FALSE);
} }
@ -191,26 +200,6 @@ gtk_fixed_new (void)
return g_object_new (GTK_TYPE_FIXED, NULL); return g_object_new (GTK_TYPE_FIXED, NULL);
} }
static GtkFixedChild*
get_child (GtkFixed *fixed,
GtkWidget *widget)
{
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
GList *children;
for (children = priv->children; children; children = children->next)
{
GtkFixedChild *child;
child = children->data;
if (child->widget == widget)
return child;
}
return NULL;
}
/** /**
* gtk_fixed_put: * gtk_fixed_put:
* @fixed: a #GtkFixed. * @fixed: a #GtkFixed.
@ -226,7 +215,6 @@ gtk_fixed_put (GtkFixed *fixed,
gint x, gint x,
gint y) gint y)
{ {
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
GtkFixedChild *child_info; GtkFixedChild *child_info;
g_return_if_fail (GTK_IS_FIXED (fixed)); g_return_if_fail (GTK_IS_FIXED (fixed));
@ -234,41 +222,39 @@ gtk_fixed_put (GtkFixed *fixed,
g_return_if_fail (_gtk_widget_get_parent (widget) == NULL); g_return_if_fail (_gtk_widget_get_parent (widget) == NULL);
child_info = g_new (GtkFixedChild, 1); child_info = g_new (GtkFixedChild, 1);
child_info->widget = widget;
child_info->x = x; child_info->x = x;
child_info->y = y; child_info->y = y;
g_object_set_qdata_full (G_OBJECT (widget), child_data_quark, child_info, g_free);
gtk_widget_set_parent (widget, GTK_WIDGET (fixed)); gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
priv->children = g_list_append (priv->children, child_info);
} }
static void static void
gtk_fixed_move_internal (GtkFixed *fixed, gtk_fixed_move_internal (GtkFixed *fixed,
GtkWidget *widget,
GtkFixedChild *child, GtkFixedChild *child,
gint x, gint x,
gint y) gint y)
{ {
g_return_if_fail (GTK_IS_FIXED (fixed)); g_return_if_fail (GTK_IS_FIXED (fixed));
g_return_if_fail (gtk_widget_get_parent (child->widget) == GTK_WIDGET (fixed));
gtk_widget_freeze_child_notify (child->widget); gtk_widget_freeze_child_notify (widget);
if (child->x != x) if (child->x != x)
{ {
child->x = x; child->x = x;
gtk_widget_child_notify (child->widget, "x"); gtk_widget_child_notify (widget, "x");
} }
if (child->y != y) if (child->y != y)
{ {
child->y = y; child->y = y;
gtk_widget_child_notify (child->widget, "y"); gtk_widget_child_notify (widget, "y");
} }
gtk_widget_thaw_child_notify (child->widget); gtk_widget_thaw_child_notify (widget);
if (gtk_widget_get_visible (child->widget) && if (gtk_widget_get_visible (widget) &&
gtk_widget_get_visible (GTK_WIDGET (fixed))) gtk_widget_get_visible (GTK_WIDGET (fixed)))
gtk_widget_queue_resize (GTK_WIDGET (fixed)); gtk_widget_queue_resize (GTK_WIDGET (fixed));
} }
@ -288,7 +274,9 @@ gtk_fixed_move (GtkFixed *fixed,
gint x, gint x,
gint y) gint y)
{ {
gtk_fixed_move_internal (fixed, get_child (fixed, widget), x, y); g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (fixed));
gtk_fixed_move_internal (fixed, widget, get_fixed_child (widget), x, y);
} }
static void static void
@ -299,20 +287,20 @@ gtk_fixed_set_child_property (GtkContainer *container,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GtkFixed *fixed = GTK_FIXED (container); GtkFixed *fixed = GTK_FIXED (container);
GtkFixedChild *fixed_child; GtkFixedChild *fixed_child = get_fixed_child (child);
fixed_child = get_child (fixed, child);
switch (property_id) switch (property_id)
{ {
case CHILD_PROP_X: case CHILD_PROP_X:
gtk_fixed_move_internal (fixed, gtk_fixed_move_internal (fixed,
child,
fixed_child, fixed_child,
g_value_get_int (value), g_value_get_int (value),
fixed_child->y); fixed_child->y);
break; break;
case CHILD_PROP_Y: case CHILD_PROP_Y:
gtk_fixed_move_internal (fixed, gtk_fixed_move_internal (fixed,
child,
fixed_child, fixed_child,
fixed_child->x, fixed_child->x,
g_value_get_int (value)); g_value_get_int (value));
@ -330,10 +318,8 @@ gtk_fixed_get_child_property (GtkContainer *container,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GtkFixedChild *fixed_child; GtkFixedChild *fixed_child = get_fixed_child (child);
fixed_child = get_child (GTK_FIXED (container), child);
switch (property_id) switch (property_id)
{ {
case CHILD_PROP_X: case CHILD_PROP_X:
@ -357,33 +343,30 @@ gtk_fixed_measure (GtkWidget *widget,
int *minimum_baseline, int *minimum_baseline,
int *natural_baseline) int *natural_baseline)
{ {
GtkFixed *fixed = GTK_FIXED (widget); int child_min, child_nat;
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed); GtkWidget *child;
GtkFixedChild *child; GtkFixedChild *child_info;
GList *children;
gint child_min, child_nat;
*minimum = 0; for (child = gtk_widget_get_first_child (widget);
*natural = 0; child != NULL;
child = gtk_widget_get_next_sibling (child))
for (children = priv->children; children; children = children->next)
{ {
child = children->data; child_info = get_fixed_child (child);
if (!gtk_widget_get_visible (child->widget)) if (!gtk_widget_get_visible (child))
continue; continue;
gtk_widget_measure (child->widget, orientation, -1, &child_min, &child_nat, NULL, NULL); gtk_widget_measure (child, orientation, -1, &child_min, &child_nat, NULL, NULL);
if (orientation == GTK_ORIENTATION_HORIZONTAL) if (orientation == GTK_ORIENTATION_HORIZONTAL)
{ {
*minimum = MAX (*minimum, child->x + child_min); *minimum = MAX (*minimum, child_info->x + child_min);
*natural = MAX (*natural, child->x + child_nat); *natural = MAX (*natural, child_info->x + child_nat);
} }
else /* VERTICAL */ else /* VERTICAL */
{ {
*minimum = MAX (*minimum, child->y + child_min); *minimum = MAX (*minimum, child_info->y + child_min);
*natural = MAX (*natural, child->y + child_nat); *natural = MAX (*natural, child_info->y + child_nat);
} }
} }
} }
@ -393,27 +376,27 @@ gtk_fixed_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation, const GtkAllocation *allocation,
int baseline) int baseline)
{ {
GtkFixed *fixed = GTK_FIXED (widget); GtkWidget *child;
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed); GtkFixedChild *child_info;
GtkFixedChild *child;
GtkAllocation child_allocation; GtkAllocation child_allocation;
GtkRequisition child_requisition; GtkRequisition child_requisition;
GList *children;
for (children = priv->children; children; children = children->next) for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{ {
child = children->data; child_info = get_fixed_child (child);
if (!gtk_widget_get_visible (child->widget)) if (!gtk_widget_get_visible (child))
continue; continue;
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL); gtk_widget_get_preferred_size (child, &child_requisition, NULL);
child_allocation.x = child->x; child_allocation.x = child_info->x;
child_allocation.y = child->y; child_allocation.y = child_info->y;
child_allocation.width = child_requisition.width; child_allocation.width = child_requisition.width;
child_allocation.height = child_requisition.height; child_allocation.height = child_requisition.height;
gtk_widget_size_allocate (child->widget, &child_allocation, -1); gtk_widget_size_allocate (child, &child_allocation, -1);
} }
} }
@ -428,32 +411,7 @@ static void
gtk_fixed_remove (GtkContainer *container, gtk_fixed_remove (GtkContainer *container,
GtkWidget *widget) GtkWidget *widget)
{ {
GtkFixed *fixed = GTK_FIXED (container); gtk_widget_unparent (widget);
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed);
GtkFixedChild *child;
GtkWidget *widget_container = GTK_WIDGET (container);
GList *children;
for (children = priv->children; children; children = children->next)
{
child = children->data;
if (child->widget == widget)
{
gboolean was_visible = gtk_widget_get_visible (widget);
gtk_widget_unparent (widget);
priv->children = g_list_remove_link (priv->children, children);
g_list_free (children);
g_free (child);
if (was_visible && gtk_widget_get_visible (widget_container))
gtk_widget_queue_resize (widget_container);
break;
}
}
} }
static void static void
@ -461,17 +419,16 @@ gtk_fixed_forall (GtkContainer *container,
GtkCallback callback, GtkCallback callback,
gpointer callback_data) gpointer callback_data)
{ {
GtkFixed *fixed = GTK_FIXED (container); GtkWidget *widget = GTK_WIDGET (container);
GtkFixedPrivate *priv = gtk_fixed_get_instance_private (fixed); GtkWidget *child;
GtkFixedChild *child;
GList *children;
children = priv->children; child = gtk_widget_get_first_child (widget);
while (children) while (child)
{ {
child = children->data; GtkWidget *next = gtk_widget_get_next_sibling (child);
children = children->next;
(* callback) (child->widget, callback_data); (* callback) (child, callback_data);
child = next;
} }
} }

View File

@ -44,7 +44,6 @@ G_BEGIN_DECLS
typedef struct _GtkFixed GtkFixed; typedef struct _GtkFixed GtkFixed;
typedef struct _GtkFixedClass GtkFixedClass; typedef struct _GtkFixedClass GtkFixedClass;
typedef struct _GtkFixedChild GtkFixedChild;
struct _GtkFixed struct _GtkFixed
{ {
@ -62,14 +61,6 @@ struct _GtkFixedClass
void (*_gtk_reserved4) (void); void (*_gtk_reserved4) (void);
}; };
struct _GtkFixedChild
{
GtkWidget *widget;
gint x;
gint y;
};
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GType gtk_fixed_get_type (void) G_GNUC_CONST; GType gtk_fixed_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL