diff --git a/gtk/gtklistitemfactory.c b/gtk/gtklistitemfactory.c new file mode 100644 index 0000000000..cc69210aeb --- /dev/null +++ b/gtk/gtklistitemfactory.c @@ -0,0 +1,105 @@ +/* + * Copyright © 2018 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include "gtklistitemfactoryprivate.h" + +struct _GtkListItemFactory +{ + GObject parent_instance; + + GtkListCreateWidgetFunc create_func; + GtkListBindWidgetFunc bind_func; + gpointer user_data; + GDestroyNotify user_destroy; +}; + +struct _GtkListItemFactoryClass +{ + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (GtkListItemFactory, gtk_list_item_factory, G_TYPE_OBJECT) + +static void +gtk_list_item_factory_finalize (GObject *object) +{ + GtkListItemFactory *self = GTK_LIST_ITEM_FACTORY (object); + + if (self->user_destroy) + self->user_destroy (self->user_data); + + G_OBJECT_CLASS (gtk_list_item_factory_parent_class)->finalize (object); +} + +static void +gtk_list_item_factory_class_init (GtkListItemFactoryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gtk_list_item_factory_finalize; +} + +static void +gtk_list_item_factory_init (GtkListItemFactory *self) +{ +} + +GtkListItemFactory * +gtk_list_item_factory_new (GtkListCreateWidgetFunc create_func, + GtkListBindWidgetFunc bind_func, + gpointer user_data, + GDestroyNotify user_destroy) +{ + GtkListItemFactory *self; + + g_return_val_if_fail (create_func, NULL); + g_return_val_if_fail (bind_func, NULL); + g_return_val_if_fail (user_data != NULL || user_destroy == NULL, NULL); + + self = g_object_new (GTK_TYPE_LIST_ITEM_FACTORY, NULL); + + self->create_func = create_func; + self->bind_func = bind_func; + self->user_data = user_data; + self->user_destroy = user_destroy; + + return self; +} + +GtkWidget * +gtk_list_item_factory_create (GtkListItemFactory *self) +{ + g_return_val_if_fail (GTK_IS_LIST_ITEM_FACTORY (self), NULL); + + return self->create_func (self->user_data); +} + +void +gtk_list_item_factory_bind (GtkListItemFactory *self, + GtkWidget *widget, + gpointer item) +{ + g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + + self->bind_func (widget, item, self->user_data); +} + diff --git a/gtk/gtklistitemfactoryprivate.h b/gtk/gtklistitemfactoryprivate.h new file mode 100644 index 0000000000..28ae55b4aa --- /dev/null +++ b/gtk/gtklistitemfactoryprivate.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: Benjamin Otte + */ + + +#ifndef __GTK_LIST_ITEM_FACTORY_H__ +#define __GTK_LIST_ITEM_FACTORY_H__ + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_LIST_ITEM_FACTORY (gtk_list_item_factory_get_type ()) +#define GTK_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_LIST_ITEM_FACTORY, GtkListItemFactory)) +#define GTK_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_LIST_ITEM_FACTORY, GtkListItemFactoryClass)) +#define GTK_IS_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_LIST_ITEM_FACTORY)) +#define GTK_IS_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_LIST_ITEM_FACTORY)) +#define GTK_LIST_ITEM_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_LIST_ITEM_FACTORY, GtkListItemFactoryClass)) + +typedef struct _GtkListItemFactory GtkListItemFactory; +typedef struct _GtkListItemFactoryClass GtkListItemFactoryClass; + +GType gtk_list_item_factory_get_type (void) G_GNUC_CONST; + +GtkListItemFactory * gtk_list_item_factory_new (GtkListCreateWidgetFunc create_func, + GtkListBindWidgetFunc bind_func, + gpointer user_data, + GDestroyNotify user_destroy); + +GtkWidget * gtk_list_item_factory_create (GtkListItemFactory *self); + +void gtk_list_item_factory_bind (GtkListItemFactory *self, + GtkWidget *widget, + gpointer item); + + +G_END_DECLS + +#endif /* __GTK_LIST_ITEM_FACTORY_H__ */ diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c index d5f2ca3841..b8a5337d8a 100644 --- a/gtk/gtklistview.c +++ b/gtk/gtklistview.c @@ -22,7 +22,7 @@ #include "gtklistview.h" #include "gtkintl.h" -#include "gtkprivate.h" +#include "gtklistitemfactoryprivate.h" /** * SECTION:gtklistview @@ -38,6 +38,7 @@ struct _GtkListView GtkWidget parent_instance; GListModel *model; + GtkListItemFactory *item_factory; }; enum @@ -116,6 +117,8 @@ gtk_list_view_dispose (GObject *object) gtk_list_view_clear_model (self); + g_clear_object (&self->item_factory); + G_OBJECT_CLASS (gtk_list_view_parent_class)->dispose (object); } @@ -258,3 +261,20 @@ gtk_list_view_set_model (GtkListView *self, g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]); } +void +gtk_list_view_set_functions (GtkListView *self, + GtkListCreateWidgetFunc create_func, + GtkListBindWidgetFunc bind_func, + gpointer user_data, + GDestroyNotify user_destroy) +{ + g_return_if_fail (GTK_IS_LIST_VIEW (self)); + g_return_if_fail (create_func); + g_return_if_fail (bind_func); + g_return_if_fail (user_data != NULL || user_destroy == NULL); + + g_clear_object (&self->item_factory); + + self->item_factory = gtk_list_item_factory_new (create_func, bind_func, user_data, user_destroy); +} + diff --git a/gtk/gtklistview.h b/gtk/gtklistview.h index 9329e21d75..541bf14874 100644 --- a/gtk/gtklistview.h +++ b/gtk/gtklistview.h @@ -28,6 +28,36 @@ G_BEGIN_DECLS +/** + * GtkListCreateWidgetFunc: + * @user_data: (closure): user data + * + * Called whenever a new widget needs to be created for managing a row in + * the list. + * + * The widget will later be bound to an item via the #GtkListBindWidgetFunc. + * + * Returns: (transfer full): a #GtkWidget + */ +typedef GtkWidget * (* GtkListCreateWidgetFunc) (gpointer user_data); + +/** + * GtkListBindWidgetFunc: + * @widget: The #GtkWidget to bind + * @item: (type GObject) (allow-none): item to bind or %NULL to unbind + * the widget. + * @user_data: (closure): user data + * + * Binds a widget previously created via a #GtkListCreateWidgetFunc to + * an @item. + * + * Rebinding a @widget to different @items is supported as well as + * unbinding it by setting @item to %NULL. + */ +typedef void (* GtkListBindWidgetFunc) (GtkWidget *widget, + gpointer item, + gpointer user_data); + #define GTK_TYPE_LIST_VIEW (gtk_list_view_get_type ()) GDK_AVAILABLE_IN_ALL @@ -41,7 +71,12 @@ GListModel * gtk_list_view_get_model (GtkListView GDK_AVAILABLE_IN_ALL void gtk_list_view_set_model (GtkListView *self, GListModel *model); - +GDK_AVAILABLE_IN_ALL +void gtk_list_view_set_functions (GtkListView *self, + GtkListCreateWidgetFunc create_func, + GtkListBindWidgetFunc bind_func, + gpointer user_data, + GDestroyNotify user_destroy); G_END_DECLS diff --git a/gtk/meson.build b/gtk/meson.build index 8e12cc6027..96d66ad4b3 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -281,6 +281,7 @@ gtk_public_sources = files([ 'gtklevelbar.c', 'gtklinkbutton.c', 'gtklistbox.c', + 'gtklistitemfactory.c', 'gtklistlistmodel.c', 'gtkliststore.c', 'gtklistview.c',