forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
fe14181d4e
commit
e5add36a17
@ -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))
|
||||
@ -42,6 +41,34 @@ 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
|
||||
|
@ -75,8 +75,8 @@ struct _GtkListItemFactory
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkListCreateWidgetFunc create_func;
|
||||
GtkListBindWidgetFunc bind_func;
|
||||
GtkListItemSetupFunc setup_func;
|
||||
GtkListItemBindFunc bind_func;
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_destroy;
|
||||
};
|
||||
@ -113,20 +113,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;
|
||||
@ -137,15 +136,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);
|
||||
}
|
||||
@ -164,7 +162,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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -8,30 +8,46 @@
|
||||
#define VARIANCE 200
|
||||
#endif
|
||||
|
||||
static GtkWidget *
|
||||
create_widget (gpointer unused)
|
||||
static void
|
||||
setup_list_item (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
{
|
||||
return gtk_label_new ("");
|
||||
GtkWidget *label = gtk_label_new ("");
|
||||
|
||||
gtk_list_item_set_child (list_item, label);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_widget (GtkWidget *widget,
|
||||
gpointer item,
|
||||
gpointer unused)
|
||||
bind_list_item (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
{
|
||||
const char *message = g_object_get_data (item, "message");
|
||||
GtkWidget *label;
|
||||
gpointer item;
|
||||
char *s;
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (widget), message);
|
||||
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;
|
||||
|
||||
label = gtk_list_item_get_child (list_item);
|
||||
gtk_label_set_text (GTK_LABEL (label), s);
|
||||
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
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,
|
||||
bind_list_item,
|
||||
NULL, NULL);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||
|
||||
|
@ -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,
|
||||
gpointer unused)
|
||||
bind_widget (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkWidget *box, *child;
|
||||
GFileInfo *info;
|
||||
GFile *file;
|
||||
guint depth;
|
||||
GIcon *icon;
|
||||
gpointer item;
|
||||
|
||||
while (gtk_widget_get_first_child (box))
|
||||
gtk_box_remove (GTK_BOX (box), gtk_widget_get_first_child (box));
|
||||
item = gtk_list_item_get_item (list_item);
|
||||
|
||||
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)
|
||||
@ -300,7 +296,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_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||
|
Loading…
Reference in New Issue
Block a user