[gtk/wip/otte/listview: 23/133] listview: Change how binding is done
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 23/133] listview: Change how binding is done
- Date: Wed, 11 Dec 2019 04:02:24 +0000 (UTC)
commit eced7e657b721c44b2f2f4ec7a892fb06c4fccbd
Author: Benjamin Otte <otte redhat com>
Date: Mon Sep 24 04:42:15 2018 +0200
listview: Change how binding is done
We now don't let the functions create widgets for the item from the
listmodel, instead we hand out a GtkListItem for them to add a widget
to.
GtkListItems are created in advance and can only be filled in by the
binding code by gtk_container_add()ing a widget.
However, they are GObjects, so they can provide properties that the
binding code can make use of - either via notify signals or GBinding.
gtk/gtklistitem.h | 30 ++++++++++++++++++++++++++++--
gtk/gtklistitemfactory.c | 27 +++++++++++++--------------
gtk/gtklistitemfactoryprivate.h | 4 ++--
gtk/gtklistview.c | 15 +++++++--------
gtk/gtklistview.h | 35 +++--------------------------------
tests/testlistview-animating.c | 40 ++++++++++++++++++++++++++++------------
tests/testlistview.c | 20 ++++++++------------
7 files changed, 89 insertions(+), 82 deletions(-)
---
diff --git a/gtk/gtklistitem.h b/gtk/gtklistitem.h
index ed7f21c45f..dff9c889ee 100644
--- a/gtk/gtklistitem.h
+++ b/gtk/gtklistitem.h
@@ -28,7 +28,6 @@
G_BEGIN_DECLS
-#define GTK_TYPE_LIST_ITEM (gtk_list_item_get_type ())
#define GTK_TYPE_LIST_ITEM (gtk_list_item_get_type ())
#define GTK_LIST_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_LIST_ITEM, GtkListItem))
#define GTK_LIST_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_LIST_ITEM, GtkListItemClass))
@@ -39,9 +38,36 @@ G_BEGIN_DECLS
typedef struct _GtkListItem GtkListItem;
typedef struct _GtkListItemClass GtkListItemClass;
-GDK_AVAILABLE_IN_ALL
GType gtk_list_item_get_type (void) G_GNUC_CONST;
+/**
+ * GtkListItemSetupFunc:
+ * @item: the #GtkListItem to set up
+ * @user_data: (closure): user data
+ *
+ * Called whenever a new list item needs to be setup for managing a row in
+ * the list.
+ *
+ * At this point, the list item is not bound yet, so gtk_list_item_get_item()
+ * will return %NULL.
+ * The list item will later be bound to an item via the #GtkListItemBindFunc.
+ */
+typedef void (* GtkListItemSetupFunc) (GtkListItem *item, gpointer user_data);
+
+/**
+ * GtkListItemBindFunc:
+ * @item: the #GtkListItem to bind
+ * @user_data: (closure): user data
+ *
+ * Binds a#GtkListItem previously set up via a #GtkListItemSetupFunc to
+ * an @item.
+ *
+ * Rebinding a @item to different @items is supported as well as
+ * unbinding it by setting @item to %NULL.
+ */
+typedef void (* GtkListItemBindFunc) (GtkListItem *item,
+ gpointer user_data);
+
GDK_AVAILABLE_IN_ALL
gpointer gtk_list_item_get_item (GtkListItem *self);
GDK_AVAILABLE_IN_ALL
diff --git a/gtk/gtklistitemfactory.c b/gtk/gtklistitemfactory.c
index 684380f3b1..c8e60bc163 100644
--- a/gtk/gtklistitemfactory.c
+++ b/gtk/gtklistitemfactory.c
@@ -27,8 +27,8 @@ struct _GtkListItemFactory
{
GObject parent_instance;
- GtkListCreateWidgetFunc create_func;
- GtkListBindWidgetFunc bind_func;
+ GtkListItemSetupFunc setup_func;
+ GtkListItemBindFunc bind_func;
gpointer user_data;
GDestroyNotify user_destroy;
};
@@ -65,20 +65,19 @@ 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)
+gtk_list_item_factory_new (GtkListItemSetupFunc setup_func,
+ GtkListItemBindFunc 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 (setup_func || 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->setup_func = setup_func;
self->bind_func = bind_func;
self->user_data = user_data;
self->user_destroy = user_destroy;
@@ -89,15 +88,14 @@ gtk_list_item_factory_new (GtkListCreateWidgetFunc create_func,
GtkListItem *
gtk_list_item_factory_create (GtkListItemFactory *self)
{
- GtkWidget *widget, *result;
+ GtkWidget *result;
g_return_val_if_fail (GTK_IS_LIST_ITEM_FACTORY (self), NULL);
- widget = self->create_func (self->user_data);
-
result = gtk_list_item_new ("row");
- gtk_list_item_set_child (GTK_LIST_ITEM (result), widget);
+ if (self->setup_func)
+ self->setup_func (GTK_LIST_ITEM (result), self->user_data);
return GTK_LIST_ITEM (result);
}
@@ -116,7 +114,8 @@ gtk_list_item_factory_bind (GtkListItemFactory *self,
gtk_list_item_set_item (list_item, item);
gtk_list_item_set_position (list_item, position);
- self->bind_func (gtk_list_item_get_child (list_item), item, self->user_data);
+ if (self->bind_func)
+ self->bind_func (list_item, self->user_data);
g_object_thaw_notify (G_OBJECT (list_item));
}
diff --git a/gtk/gtklistitemfactoryprivate.h b/gtk/gtklistitemfactoryprivate.h
index 21bc5b5586..779251344b 100644
--- a/gtk/gtklistitemfactoryprivate.h
+++ b/gtk/gtklistitemfactoryprivate.h
@@ -38,8 +38,8 @@ 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,
+GtkListItemFactory * gtk_list_item_factory_new (GtkListItemSetupFunc setup_func,
+ GtkListItemBindFunc bind_func,
gpointer user_data,
GDestroyNotify user_destroy);
diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c
index 1539a2a530..36e710ab18 100644
--- a/gtk/gtklistview.c
+++ b/gtk/gtklistview.c
@@ -872,24 +872,23 @@ gtk_list_view_set_model (GtkListView *self,
}
void
-gtk_list_view_set_functions (GtkListView *self,
- GtkListCreateWidgetFunc create_func,
- GtkListBindWidgetFunc bind_func,
- gpointer user_data,
- GDestroyNotify user_destroy)
+gtk_list_view_set_functions (GtkListView *self,
+ GtkListItemSetupFunc setup_func,
+ GtkListItemBindFunc bind_func,
+ gpointer user_data,
+ GDestroyNotify user_destroy)
{
GtkListItemFactory *factory;
guint n_items;
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 (setup_func || bind_func);
g_return_if_fail (user_data != NULL || user_destroy == NULL);
n_items = self->model ? g_list_model_get_n_items (self->model) : 0;
gtk_list_view_remove_rows (self, NULL, 0, n_items);
- factory = gtk_list_item_factory_new (create_func, bind_func, user_data, user_destroy);
+ factory = gtk_list_item_factory_new (setup_func, bind_func, user_data, user_destroy);
gtk_list_item_manager_set_factory (self->item_manager, factory);
g_object_unref (factory);
diff --git a/gtk/gtklistview.h b/gtk/gtklistview.h
index 541bf14874..4d1a0a5d77 100644
--- a/gtk/gtklistview.h
+++ b/gtk/gtklistview.h
@@ -25,39 +25,10 @@
#endif
#include <gtk/gtkwidget.h>
+#include <gtk/gtklistitem.h>
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
@@ -73,8 +44,8 @@ void gtk_list_view_set_model (GtkListView
GListModel *model);
GDK_AVAILABLE_IN_ALL
void gtk_list_view_set_functions (GtkListView *self,
- GtkListCreateWidgetFunc create_func,
- GtkListBindWidgetFunc bind_func,
+ GtkListItemSetupFunc setup_func,
+ GtkListItemBindFunc bind_func,
gpointer user_data,
GDestroyNotify user_destroy);
diff --git a/tests/testlistview-animating.c b/tests/testlistview-animating.c
index 9d857c6737..adcafba4ae 100644
--- a/tests/testlistview-animating.c
+++ b/tests/testlistview-animating.c
@@ -8,30 +8,46 @@
#define VARIANCE 200
#endif
-static GtkWidget *
-create_widget (gpointer unused)
+static void
+update_label (GtkListItem *list_item,
+ GParamSpec *pspec,
+ GtkLabel *label)
{
- return gtk_label_new ("");
+ gpointer item;
+ char *s;
+
+ item = gtk_list_item_get_item (list_item);
+
+ if (item)
+ s = g_strdup_printf ("%u: %s",
+ gtk_list_item_get_position (list_item),
+ (const char *) g_object_get_data (item, "message"));
+ else
+ s = NULL;
+
+ gtk_label_set_text (label, s);
+
+ g_free (s);
}
static void
-bind_widget (GtkWidget *widget,
- gpointer item,
- gpointer unused)
+setup_list_item (GtkListItem *list_item,
+ gpointer unused)
{
- const char *message = g_object_get_data (item, "message");
+ GtkWidget *label = gtk_label_new ("");
- gtk_label_set_text (GTK_LABEL (widget), message);
+ g_signal_connect (list_item, "notify", G_CALLBACK (update_label), label);
+ gtk_list_item_set_child (list_item, label);
}
static GtkWidget *
create_widget_for_listbox (gpointer item,
gpointer unused)
{
+ const char *message = g_object_get_data (item, "message");
GtkWidget *widget;
- widget = create_widget (unused);
- bind_widget (widget, item, unused);
+ widget = gtk_label_new (message);
return widget;
}
@@ -131,8 +147,8 @@ main (int argc,
listview = gtk_list_view_new ();
gtk_list_view_set_functions (GTK_LIST_VIEW (listview),
- create_widget,
- bind_widget,
+ setup_list_item,
+ NULL,
NULL, NULL);
gtk_container_add (GTK_CONTAINER (sw), listview);
diff --git a/tests/testlistview.c b/tests/testlistview.c
index dce92f2e66..0b99e00446 100644
--- a/tests/testlistview.c
+++ b/tests/testlistview.c
@@ -138,25 +138,21 @@ create_list_model_for_directory (gpointer file)
return G_LIST_MODEL (sort);
}
-static GtkWidget *
-create_widget (gpointer unused)
-{
- return gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
-}
-
static void
-bind_widget (GtkWidget *box,
- gpointer item,
+bind_widget (GtkListItem *list_item,
gpointer unused)
{
- GtkWidget *child;
+ GtkWidget *box, *child;
GFileInfo *info;
GFile *file;
guint depth;
GIcon *icon;
+ gpointer item;
+
+ item = gtk_list_item_get_item (list_item);
- while (gtk_widget_get_first_child (box))
- gtk_container_remove (GTK_CONTAINER (box), gtk_widget_get_first_child (box));
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_list_item_set_child (list_item, box);
depth = gtk_tree_list_row_get_depth (item);
if (depth > 0)
@@ -302,7 +298,7 @@ main (int argc, char *argv[])
listview = gtk_list_view_new ();
gtk_list_view_set_functions (GTK_LIST_VIEW (listview),
- create_widget,
+ NULL,
bind_widget,
NULL, NULL);
gtk_container_add (GTK_CONTAINER (sw), listview);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]