mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 14:00:09 +00:00
listitem: Move position/item/selected tracking to widget
This way, we can ensure it's always there when we need it (before the item gets created) and gone when we don't (if some GC language holds on to the item after we've destroyed the widget).
This commit is contained in:
parent
32eedec565
commit
9d86020d4c
@ -98,11 +98,15 @@ gtk_list_item_get_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_value_set_object (value, self->item);
|
||||
if (self->owner)
|
||||
g_value_set_object (value, gtk_list_item_widget_get_item (self->owner));
|
||||
break;
|
||||
|
||||
case PROP_POSITION:
|
||||
g_value_set_uint (value, self->position);
|
||||
if (self->owner)
|
||||
g_value_set_uint (value, gtk_list_item_widget_get_position (self->owner));
|
||||
else
|
||||
g_value_set_uint (value, GTK_INVALID_LIST_POSITION);
|
||||
break;
|
||||
|
||||
case PROP_SELECTABLE:
|
||||
@ -110,7 +114,10 @@ gtk_list_item_get_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_SELECTED:
|
||||
g_value_set_boolean (value, self->selected);
|
||||
if (self->owner)
|
||||
g_value_set_boolean (value, gtk_list_item_widget_get_selected (self->owner));
|
||||
else
|
||||
g_value_set_boolean (value, FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -259,7 +266,10 @@ gtk_list_item_get_item (GtkListItem *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM (self), NULL);
|
||||
|
||||
return self->item;
|
||||
if (self->owner == NULL)
|
||||
return NULL;
|
||||
|
||||
return gtk_list_item_widget_get_item (self->owner);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,23 +326,6 @@ gtk_list_item_set_child (GtkListItem *self,
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ITEM]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_set_item (GtkListItem *self,
|
||||
gpointer item)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_LIST_ITEM (self));
|
||||
g_return_if_fail (item == NULL || G_IS_OBJECT (item));
|
||||
|
||||
if (self->item == item)
|
||||
return;
|
||||
|
||||
g_clear_object (&self->item);
|
||||
if (item)
|
||||
self->item = g_object_ref (item);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ITEM]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_list_item_get_position:
|
||||
* @self: a #GtkListItem
|
||||
@ -345,23 +338,12 @@ gtk_list_item_set_item (GtkListItem *self,
|
||||
guint
|
||||
gtk_list_item_get_position (GtkListItem *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM (self), 0);
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM (self), GTK_INVALID_LIST_POSITION);
|
||||
|
||||
return self->position;
|
||||
}
|
||||
if (self->owner == NULL)
|
||||
return GTK_INVALID_LIST_POSITION;
|
||||
|
||||
void
|
||||
gtk_list_item_set_position (GtkListItem *self,
|
||||
guint position)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_LIST_ITEM (self));
|
||||
|
||||
if (self->position == position)
|
||||
return;
|
||||
|
||||
self->position = position;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_POSITION]);
|
||||
return gtk_list_item_widget_get_position (self->owner);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,21 +361,10 @@ gtk_list_item_get_selected (GtkListItem *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM (self), FALSE);
|
||||
|
||||
return self->selected;
|
||||
}
|
||||
if (self->owner == NULL)
|
||||
return FALSE;
|
||||
|
||||
void
|
||||
gtk_list_item_set_selected (GtkListItem *self,
|
||||
gboolean selected)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_LIST_ITEM (self));
|
||||
|
||||
if (self->selected == selected)
|
||||
return;
|
||||
|
||||
self->selected = selected;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
|
||||
return gtk_list_item_widget_get_selected (self->owner);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,23 +32,14 @@ struct _GtkListItem
|
||||
|
||||
GtkListItemWidget *owner; /* has a reference */
|
||||
|
||||
GObject *item;
|
||||
GtkWidget *child;
|
||||
guint position;
|
||||
|
||||
guint activatable : 1;
|
||||
guint selectable : 1;
|
||||
guint selected : 1;
|
||||
};
|
||||
|
||||
GtkListItem * gtk_list_item_new (void);
|
||||
|
||||
void gtk_list_item_set_item (GtkListItem *self,
|
||||
gpointer item);
|
||||
void gtk_list_item_set_position (GtkListItem *self,
|
||||
guint position);
|
||||
void gtk_list_item_set_selected (GtkListItem *self,
|
||||
gboolean selected);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "gtklistitemfactoryprivate.h"
|
||||
#include "gtklistitemprivate.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkselectionmodel.h"
|
||||
#include "gtkwidget.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
@ -37,6 +38,10 @@ struct _GtkListItemWidgetPrivate
|
||||
{
|
||||
GtkListItemFactory *factory;
|
||||
GtkListItem *list_item;
|
||||
|
||||
GObject *item;
|
||||
guint position;
|
||||
gboolean selected;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -54,13 +59,13 @@ gtk_list_item_widget_activate_signal (GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
if (!priv->list_item->activatable)
|
||||
if (priv->list_item && !priv->list_item->activatable)
|
||||
return;
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
priv->list_item->position);
|
||||
priv->position);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -121,6 +126,7 @@ gtk_list_item_widget_dispose (GObject *object)
|
||||
gtk_list_item_factory_teardown (priv->factory, self);
|
||||
g_assert (priv->list_item == NULL);
|
||||
}
|
||||
g_clear_object (&priv->item);
|
||||
g_clear_object (&priv->factory);
|
||||
|
||||
G_OBJECT_CLASS (gtk_list_item_widget_parent_class)->dispose (object);
|
||||
@ -135,7 +141,7 @@ gtk_list_item_widget_select_action (GtkWidget *widget,
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
gboolean modify, extend;
|
||||
|
||||
if (!priv->list_item->selectable)
|
||||
if (priv->list_item && !priv->list_item->selectable)
|
||||
return;
|
||||
|
||||
g_variant_get (parameter, "(bb)", &modify, &extend);
|
||||
@ -143,7 +149,7 @@ gtk_list_item_widget_select_action (GtkWidget *widget,
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
priv->list_item->position, modify, extend);
|
||||
priv->position, modify, extend);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -229,13 +235,13 @@ gtk_list_item_widget_click_gesture_pressed (GtkGestureClick *gesture,
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
|
||||
if (!priv->list_item->selectable && !priv->list_item->activatable)
|
||||
if (priv->list_item && !priv->list_item->selectable && !priv->list_item->activatable)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->list_item->selectable)
|
||||
if (!priv->list_item || priv->list_item->selectable)
|
||||
{
|
||||
GdkModifierType state;
|
||||
GdkEvent *event;
|
||||
@ -250,17 +256,17 @@ gtk_list_item_widget_click_gesture_pressed (GtkGestureClick *gesture,
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
priv->list_item->position, modify, extend);
|
||||
priv->position, modify, extend);
|
||||
}
|
||||
|
||||
if (priv->list_item->activatable)
|
||||
if (!priv->list_item || priv->list_item->activatable)
|
||||
{
|
||||
if (n_press == 2)
|
||||
{
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
priv->list_item->position);
|
||||
priv->position);
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,7 +286,7 @@ gtk_list_item_widget_enter_cb (GtkEventControllerFocus *controller,
|
||||
gtk_widget_activate_action (widget,
|
||||
"list.scroll-to-item",
|
||||
"u",
|
||||
priv->list_item->position);
|
||||
priv->position);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -381,6 +387,13 @@ gtk_list_item_widget_default_setup (GtkListItemWidget *self,
|
||||
|
||||
if (list_item->child)
|
||||
gtk_list_item_widget_add_child (self, list_item->child);
|
||||
|
||||
if (priv->item)
|
||||
g_object_notify (G_OBJECT (list_item), "item");
|
||||
if (priv->position != GTK_INVALID_LIST_POSITION)
|
||||
g_object_notify (G_OBJECT (list_item), "position");
|
||||
if (priv->selected)
|
||||
g_object_notify (G_OBJECT (list_item), "selected");
|
||||
}
|
||||
|
||||
void
|
||||
@ -396,6 +409,13 @@ gtk_list_item_widget_default_teardown (GtkListItemWidget *self,
|
||||
|
||||
if (list_item->child)
|
||||
gtk_list_item_widget_remove_child (self, list_item->child);
|
||||
|
||||
if (priv->item)
|
||||
g_object_notify (G_OBJECT (list_item), "item");
|
||||
if (priv->position != GTK_INVALID_LIST_POSITION)
|
||||
g_object_notify (G_OBJECT (list_item), "position");
|
||||
if (priv->selected)
|
||||
g_object_notify (G_OBJECT (list_item), "selected");
|
||||
}
|
||||
|
||||
void
|
||||
@ -405,9 +425,24 @@ gtk_list_item_widget_default_update (GtkListItemWidget *self,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
gtk_list_item_set_item (list_item, item);
|
||||
gtk_list_item_set_position (list_item, position);
|
||||
gtk_list_item_set_selected (list_item, selected);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
/* FIXME: It's kinda evil to notify external objects from here... */
|
||||
|
||||
if (g_set_object (&priv->item, item))
|
||||
g_object_notify (G_OBJECT (list_item), "item");
|
||||
|
||||
if (priv->position != position)
|
||||
{
|
||||
priv->position = position;
|
||||
g_object_notify (G_OBJECT (list_item), "position");
|
||||
}
|
||||
|
||||
if (priv->selected != selected)
|
||||
{
|
||||
priv->selected = selected;
|
||||
g_object_notify (G_OBJECT (list_item), "selected");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -437,7 +472,7 @@ gtk_list_item_widget_get_position (GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
return priv->list_item->position;
|
||||
return priv->position;
|
||||
}
|
||||
|
||||
gpointer
|
||||
@ -445,7 +480,7 @@ gtk_list_item_widget_get_item (GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
return priv->list_item->item;
|
||||
return priv->item;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -453,6 +488,6 @@ gtk_list_item_widget_get_selected (GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
return priv->list_item->selected;
|
||||
return priv->selected;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user