diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c index 79d3e12e78..01db2cdac4 100644 --- a/gtk/gtklistitem.c +++ b/gtk/gtklistitem.c @@ -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); } /** diff --git a/gtk/gtklistitemprivate.h b/gtk/gtklistitemprivate.h index b84057f838..d8f8833313 100644 --- a/gtk/gtklistitemprivate.h +++ b/gtk/gtklistitemprivate.h @@ -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 diff --git a/gtk/gtklistitemwidget.c b/gtk/gtklistitemwidget.c index fe314db13a..54f1eb0c96 100644 --- a/gtk/gtklistitemwidget.c +++ b/gtk/gtklistitemwidget.c @@ -30,6 +30,7 @@ #include "gtklistitemfactoryprivate.h" #include "gtklistitemprivate.h" #include "gtkmain.h" +#include "gtkselectionmodel.h" #include "gtkwidget.h" #include "gtkwidgetprivate.h" @@ -38,6 +39,10 @@ struct _GtkListItemWidgetPrivate { GtkListItemFactory *factory; GtkListItem *list_item; + + GObject *item; + guint position; + gboolean selected; }; enum @@ -55,13 +60,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 @@ -122,6 +127,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); @@ -136,7 +142,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); @@ -144,7 +150,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 @@ -233,13 +239,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; GdkModifierType mask; @@ -258,17 +264,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); } } @@ -291,7 +297,7 @@ gtk_list_item_widget_focus_changed_cb (GtkEventControllerKey *controller, gtk_widget_activate_action (widget, "list.scroll-to-item", "u", - priv->list_item->position); + priv->position); } } @@ -393,6 +399,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 @@ -408,6 +421,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 @@ -417,9 +437,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 @@ -449,7 +484,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 @@ -457,7 +492,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 @@ -465,6 +500,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; }