diff --git a/gtk/gtkbuilderlistitemfactory.c b/gtk/gtkbuilderlistitemfactory.c index b8a9861e7b..da7ee8d715 100644 --- a/gtk/gtkbuilderlistitemfactory.c +++ b/gtk/gtkbuilderlistitemfactory.c @@ -55,13 +55,14 @@ static GParamSpec *properties[N_PROPS] = { NULL, }; static void gtk_builder_list_item_factory_setup (GtkListItemFactory *factory, + GtkListItemWidget *widget, GtkListItem *list_item) { GtkBuilderListItemFactory *self = GTK_BUILDER_LIST_ITEM_FACTORY (factory); GtkBuilder *builder; GError *error = NULL; - GTK_LIST_ITEM_FACTORY_CLASS (gtk_builder_list_item_factory_parent_class)->setup (factory, list_item); + GTK_LIST_ITEM_FACTORY_CLASS (gtk_builder_list_item_factory_parent_class)->setup (factory, widget, list_item); builder = gtk_builder_new (); diff --git a/gtk/gtkfunctionslistitemfactory.c b/gtk/gtkfunctionslistitemfactory.c index 41b708e36e..2f179c332d 100644 --- a/gtk/gtkfunctionslistitemfactory.c +++ b/gtk/gtkfunctionslistitemfactory.c @@ -43,18 +43,23 @@ G_DEFINE_TYPE (GtkFunctionsListItemFactory, gtk_functions_list_item_factory, GTK static void gtk_functions_list_item_factory_setup (GtkListItemFactory *factory, + GtkListItemWidget *widget, GtkListItem *list_item) { GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory); - GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->setup (factory, list_item); - if (self->setup_func) self->setup_func (list_item, self->user_data); + + GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->setup (factory, widget, list_item); + + if (gtk_list_item_get_item (list_item) != NULL && self->bind_func) + self->bind_func (list_item, self->user_data); } static void gtk_functions_list_item_factory_update (GtkListItemFactory *factory, + GtkListItemWidget *widget, GtkListItem *list_item, guint position, gpointer item, @@ -62,7 +67,7 @@ gtk_functions_list_item_factory_update (GtkListItemFactory *factory, { GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory); - GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->update (factory, list_item, position, item, selected); + GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected); if (item != NULL && self->bind_func) self->bind_func (list_item, self->user_data); diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c index ee50eb42ab..79d3e12e78 100644 --- a/gtk/gtklistitem.c +++ b/gtk/gtklistitem.c @@ -239,17 +239,10 @@ gtk_list_item_init (GtkListItem *self) } GtkListItem * -gtk_list_item_new (GtkListItemWidget *owner) +gtk_list_item_new (void) { - GtkListItem *result; - - g_return_val_if_fail (owner != NULL, NULL); - - result = g_object_new (GTK_TYPE_LIST_ITEM, - NULL); - result->owner = owner; - - return result; + return g_object_new (GTK_TYPE_LIST_ITEM, + NULL); } /** diff --git a/gtk/gtklistitemfactory.c b/gtk/gtklistitemfactory.c index d46cc624b8..83fdb08193 100644 --- a/gtk/gtklistitemfactory.c +++ b/gtk/gtklistitemfactory.c @@ -75,30 +75,31 @@ G_DEFINE_TYPE (GtkListItemFactory, gtk_list_item_factory, G_TYPE_OBJECT) static void gtk_list_item_factory_default_setup (GtkListItemFactory *self, + GtkListItemWidget *widget, GtkListItem *list_item) { + gtk_list_item_widget_default_setup (widget, list_item); } static void gtk_list_item_factory_default_teardown (GtkListItemFactory *self, + GtkListItemWidget *widget, GtkListItem *list_item) { + gtk_list_item_widget_default_teardown (widget, list_item); + gtk_list_item_set_child (list_item, NULL); - - gtk_list_item_set_selectable (list_item, TRUE); - } static void gtk_list_item_factory_default_update (GtkListItemFactory *self, + GtkListItemWidget *widget, GtkListItem *list_item, guint position, 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); + gtk_list_item_widget_default_update (widget, list_item, position, item, selected); } static void @@ -116,35 +117,49 @@ gtk_list_item_factory_init (GtkListItemFactory *self) void gtk_list_item_factory_setup (GtkListItemFactory *self, - GtkListItem *list_item) + GtkListItemWidget *widget) { + GtkListItem *list_item; + g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self)); - GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->setup (self, list_item); + list_item = gtk_list_item_new (); + + GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->setup (self, widget, list_item); } void gtk_list_item_factory_teardown (GtkListItemFactory *self, - GtkListItem *list_item) + GtkListItemWidget *widget) { + GtkListItem *list_item; + g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self)); - GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->teardown (self, list_item); + list_item = gtk_list_item_widget_get_list_item (widget); + + GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->teardown (self, widget, list_item); + + g_object_unref (list_item); } void gtk_list_item_factory_update (GtkListItemFactory *self, - GtkListItem *list_item, + GtkListItemWidget *widget, guint position, gpointer item, gboolean selected) { + GtkListItem *list_item; + g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self)); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (GTK_IS_LIST_ITEM_WIDGET (widget)); + + list_item = gtk_list_item_widget_get_list_item (widget); g_object_freeze_notify (G_OBJECT (list_item)); - GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->update (self, list_item, position, item, selected); + GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->update (self, widget, list_item, position, item, selected); g_object_thaw_notify (G_OBJECT (list_item)); } diff --git a/gtk/gtklistitemfactoryprivate.h b/gtk/gtklistitemfactoryprivate.h index 4cb49e8821..3ee5e5f088 100644 --- a/gtk/gtklistitemfactoryprivate.h +++ b/gtk/gtklistitemfactoryprivate.h @@ -22,8 +22,7 @@ #define __GTK_LIST_ITEM_FACTORY_PRIVATE_H__ #include -#include -#include +#include "gtk/gtklistitemwidgetprivate.h" G_BEGIN_DECLS @@ -38,14 +37,17 @@ struct _GtkListItemFactoryClass /* setup @list_item so it can be bound */ void (* setup) (GtkListItemFactory *self, + GtkListItemWidget *widget, GtkListItem *list_item); /* undo the effects of GtkListItemFactoryClass::setup() */ void (* teardown) (GtkListItemFactory *self, + GtkListItemWidget *widget, GtkListItem *list_item); /* Update properties on @list_item to the given @item, which is in @position and @selected state. * One or more of those properties might be unchanged. */ void (* update) (GtkListItemFactory *self, + GtkListItemWidget *widget, GtkListItem *list_item, guint position, gpointer item, @@ -53,12 +55,12 @@ struct _GtkListItemFactoryClass }; void gtk_list_item_factory_setup (GtkListItemFactory *self, - GtkListItem *list_item); + GtkListItemWidget *widget); void gtk_list_item_factory_teardown (GtkListItemFactory *self, - GtkListItem *list_item); + GtkListItemWidget *widget); void gtk_list_item_factory_update (GtkListItemFactory *self, - GtkListItem *list_item, + GtkListItemWidget *widget, guint position, gpointer item, gboolean selected); diff --git a/gtk/gtklistitemprivate.h b/gtk/gtklistitemprivate.h index 5912e406be..b84057f838 100644 --- a/gtk/gtklistitemprivate.h +++ b/gtk/gtklistitemprivate.h @@ -41,7 +41,7 @@ struct _GtkListItem guint selected : 1; }; -GtkListItem * gtk_list_item_new (GtkListItemWidget *owner); +GtkListItem * gtk_list_item_new (void); void gtk_list_item_set_item (GtkListItem *self, gpointer item); diff --git a/gtk/gtklistitemwidget.c b/gtk/gtklistitemwidget.c index c989731d60..c2cec1b271 100644 --- a/gtk/gtklistitemwidget.c +++ b/gtk/gtklistitemwidget.c @@ -107,9 +107,8 @@ gtk_list_item_widget_dispose (GObject *object) if (self->item) { - gtk_list_item_factory_teardown (self->factory, self->item); - self->item->owner = NULL; - g_clear_object (&self->item); + gtk_list_item_factory_teardown (self->factory, self); + g_assert (self->item == NULL); } g_clear_object (&self->factory); @@ -325,8 +324,6 @@ gtk_list_item_widget_init (GtkListItemWidget *self) controller = gtk_event_controller_key_new (); g_signal_connect (controller, "notify::contains-focus", G_CALLBACK (gtk_list_item_widget_focus_changed_cb), self); gtk_widget_add_controller (GTK_WIDGET (self), controller); - - self->item = gtk_list_item_new (self); } GtkWidget * @@ -344,7 +341,8 @@ gtk_list_item_widget_new (GtkListItemFactory *factory, { result->factory = g_object_ref (factory); - gtk_list_item_factory_setup (factory, result->item); + gtk_list_item_factory_setup (factory, result); + g_assert (result->item != NULL); } return GTK_WIDGET (result); @@ -356,7 +354,8 @@ gtk_list_item_widget_update (GtkListItemWidget *self, gpointer item, gboolean selected) { - gtk_list_item_factory_update (self->factory, self->item, position, item, selected); + if (self->factory) + gtk_list_item_factory_update (self->factory, self, position, item, selected); if (selected) gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED, FALSE); @@ -364,6 +363,42 @@ gtk_list_item_widget_update (GtkListItemWidget *self, gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED); } +void +gtk_list_item_widget_default_setup (GtkListItemWidget *self, + GtkListItem *list_item) +{ + self->item = list_item; + list_item->owner = self; + + if (list_item->child) + gtk_list_item_widget_add_child (self, list_item->child); +} + +void +gtk_list_item_widget_default_teardown (GtkListItemWidget *self, + GtkListItem *list_item) +{ + g_assert (self->item == list_item); + + self->item = NULL; + list_item->owner = NULL; + + if (list_item->child) + gtk_list_item_widget_remove_child (self, list_item->child); +} + +void +gtk_list_item_widget_default_update (GtkListItemWidget *self, + GtkListItem *list_item, + guint position, + 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); +} + void gtk_list_item_widget_add_child (GtkListItemWidget *self, GtkWidget *child) @@ -378,6 +413,12 @@ gtk_list_item_widget_remove_child (GtkListItemWidget *self, gtk_widget_unparent (child); } +GtkListItem * +gtk_list_item_widget_get_list_item (GtkListItemWidget *self) +{ + return self->item; +} + guint gtk_list_item_widget_get_position (GtkListItemWidget *self) { diff --git a/gtk/gtklistitemwidgetprivate.h b/gtk/gtklistitemwidgetprivate.h index b3289b139e..9b34e9f5d6 100644 --- a/gtk/gtklistitemwidgetprivate.h +++ b/gtk/gtklistitemwidgetprivate.h @@ -59,6 +59,17 @@ void gtk_list_item_widget_update (GtkListItemWidg guint position, gpointer item, gboolean selected); +GtkListItem * gtk_list_item_widget_get_list_item (GtkListItemWidget *self); + +void gtk_list_item_widget_default_setup (GtkListItemWidget *self, + GtkListItem *list_item); +void gtk_list_item_widget_default_teardown (GtkListItemWidget *self, + GtkListItem *list_item); +void gtk_list_item_widget_default_update (GtkListItemWidget *self, + GtkListItem *list_item, + guint position, + gpointer item, + gboolean selected); void gtk_list_item_widget_add_child (GtkListItemWidget *self, GtkWidget *child); diff --git a/gtk/gtksignallistitemfactory.c b/gtk/gtksignallistitemfactory.c index 467b55d540..c1c8ada1f6 100644 --- a/gtk/gtksignallistitemfactory.c +++ b/gtk/gtksignallistitemfactory.c @@ -81,18 +81,14 @@ struct _GtkSignalListItemFactoryClass { GtkListItemFactoryClass parent_class; - void (* setup) (GtkListItemFactory *self, - GtkListItem *list_item); - void (* teardown) (GtkListItemFactory *self, - GtkListItem *list_item); - - void (* bind) (GtkListItemFactory *self, - GtkListItem *list_item, - guint position, - gpointer item, - gboolean selected); - void (* unbind) (GtkListItemFactory *self, - GtkListItem *list_item); + void (* setup) (GtkSignalListItemFactory *self, + GtkListItem *list_item); + void (* teardown) (GtkSignalListItemFactory *self, + GtkListItem *list_item); + void (* bind) (GtkSignalListItemFactory *self, + GtkListItem *list_item); + void (* unbind) (GtkSignalListItemFactory *self, + GtkListItem *list_item); }; enum { @@ -109,15 +105,20 @@ static guint signals[LAST_SIGNAL] = { 0 }; static void gtk_signal_list_item_factory_setup (GtkListItemFactory *factory, + GtkListItemWidget *widget, GtkListItem *list_item) { - GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->setup (factory, list_item); - g_signal_emit (factory, signals[SETUP], 0, list_item); + + GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->setup (factory, widget, list_item); + + if (gtk_list_item_get_item (list_item)) + g_signal_emit (factory, signals[BIND], 0, list_item); } static void gtk_signal_list_item_factory_update (GtkListItemFactory *factory, + GtkListItemWidget *widget, GtkListItem *list_item, guint position, gpointer item, @@ -126,7 +127,7 @@ gtk_signal_list_item_factory_update (GtkListItemFactory *factory, if (gtk_list_item_get_item (list_item)) g_signal_emit (factory, signals[UNBIND], 0, list_item); - GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->update (factory, list_item, position, item, selected); + GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected); if (item) g_signal_emit (factory, signals[BIND], 0, list_item); @@ -134,14 +135,15 @@ gtk_signal_list_item_factory_update (GtkListItemFactory *factory, static void gtk_signal_list_item_factory_teardown (GtkListItemFactory *factory, + GtkListItemWidget *widget, GtkListItem *list_item) { if (gtk_list_item_get_item (list_item)) g_signal_emit (factory, signals[UNBIND], 0, list_item); - g_signal_emit (factory, signals[TEARDOWN], 0, list_item); + GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->teardown (factory, widget, list_item); - GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->teardown (factory, list_item); + g_signal_emit (factory, signals[TEARDOWN], 0, list_item); } static void