diff --git a/tests/testlistview.c b/tests/testlistview.c index 14d4cddbf0..676124237c 100644 --- a/tests/testlistview.c +++ b/tests/testlistview.c @@ -20,7 +20,8 @@ start_enumerate (GListStore *store) enumerate = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_ICON - "," G_FILE_ATTRIBUTE_STANDARD_NAME, + "," G_FILE_ATTRIBUTE_STANDARD_NAME + "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, &error); @@ -138,72 +139,116 @@ create_list_model_for_directory (gpointer file) return G_LIST_MODEL (sort); } +typedef struct _RowData RowData; +struct _RowData +{ + GtkWidget *depth_box; + GtkWidget *expander; + GtkWidget *icon; + GtkWidget *name; + + GtkTreeListRow *current_item; + GBinding *expander_binding; +}; + +static void row_data_notify_item (GtkListItem *item, + GParamSpec *pspec, + RowData *data); static void -bind_widget (GtkListItem *list_item, - gpointer unused) +row_data_unbind (RowData *data) +{ + if (data->current_item == NULL) + return; + + g_binding_unbind (data->expander_binding); + + g_clear_object (&data->current_item); +} + +static void +row_data_bind (RowData *data, + GtkTreeListRow *item) +{ + GFileInfo *info; + GIcon *icon; + guint depth; + + row_data_unbind (data); + + if (item == NULL) + return; + + data->current_item = g_object_ref (item); + + depth = gtk_tree_list_row_get_depth (item); + gtk_widget_set_size_request (data->depth_box, 16 * depth, 0); + + gtk_widget_set_sensitive (data->expander, gtk_tree_list_row_is_expandable (item)); + data->expander_binding = g_object_bind_property (item, "expanded", data->expander, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + + info = gtk_tree_list_row_get_item (item); + + icon = g_file_info_get_icon (info); + gtk_widget_set_visible (data->icon, icon != NULL); + if (icon) + gtk_image_set_from_gicon (GTK_IMAGE (data->icon), icon); + + gtk_label_set_label (GTK_LABEL (data->name), g_file_info_get_display_name (info)); + + g_object_unref (info); +} + +static void +row_data_notify_item (GtkListItem *item, + GParamSpec *pspec, + RowData *data) +{ + row_data_bind (data, gtk_list_item_get_item (item)); +} + +static void +row_data_free (gpointer _data) +{ + RowData *data = _data; + + row_data_unbind (data); + + g_slice_free (RowData, data); +} + +static void +setup_widget (GtkListItem *list_item, + gpointer unused) { GtkWidget *box, *child; - GFileInfo *info; - GFile *file; - guint depth; - GIcon *icon; - gpointer item; - char *s; + RowData *data; - item = gtk_list_item_get_item (list_item); + data = g_slice_new0 (RowData); + g_signal_connect (list_item, "notify::item", G_CALLBACK (row_data_notify_item), data); + g_object_set_data_full (G_OBJECT (list_item), "row-data", data, row_data_free); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); gtk_list_item_set_child (list_item, box); child = gtk_label_new (NULL); gtk_label_set_width_chars (GTK_LABEL (child), 5); - gtk_label_set_xalign (GTK_LABEL (child), 1.0); - g_object_bind_property (list_item, "position", child, "label", G_BINDING_SYNC_CREATE); gtk_box_append (GTK_BOX (box), child); - depth = gtk_tree_list_row_get_depth (item); - if (depth > 0) - { - child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_set_size_request (child, 16 * depth, 0); - gtk_box_append (GTK_BOX (box), child); - } + data->depth_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_append (GTK_BOX (box), data->depth_box); + + data->expander = g_object_new (GTK_TYPE_TOGGLE_BUTTON, "css-name", "expander-widget", NULL); + gtk_button_set_has_frame (GTK_BUTTON (data->expander), FALSE); + gtk_box_append (GTK_BOX (box), data->expander); + child = g_object_new (GTK_TYPE_SPINNER, "css-name", "expander", NULL); + g_object_bind_property (data->expander, "active", child, "spinning", G_BINDING_SYNC_CREATE); + gtk_button_set_child (GTK_BUTTON (data->expander), child); - if (gtk_tree_list_row_is_expandable (item)) - { - GtkWidget *arrow; + data->icon = gtk_image_new (); + gtk_box_append (GTK_BOX (box), data->icon); - child = g_object_new (GTK_TYPE_TOGGLE_BUTTON, "css-name", "expander-widget", NULL); - gtk_button_set_has_frame (GTK_BUTTON (child), FALSE); - g_object_bind_property (item, "expanded", child, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); - g_object_set_data_full (G_OBJECT (child), "make-sure-its-not-unreffed", g_object_ref (item), g_object_unref); - - arrow = g_object_new (GTK_TYPE_SPINNER, "css-name", "expander", NULL); - g_object_bind_property (item, "expanded", arrow, "spinning", G_BINDING_SYNC_CREATE); - gtk_button_set_child (GTK_BUTTON (child), arrow); - } - else - { - child = gtk_image_new (); /* empty whatever */ - } - gtk_box_append (GTK_BOX (box), child); - - info = gtk_tree_list_row_get_item (item); - - icon = g_file_info_get_icon (info); - if (icon) - { - child = gtk_image_new_from_gicon (icon); - gtk_box_append (GTK_BOX (box), child); - } - - file = g_object_get_data (G_OBJECT (info), "file"); - s = g_file_get_basename (file); - child = gtk_label_new (s); - g_free (s); - g_object_unref (info); - - gtk_box_append (GTK_BOX (box), child); + data->name = gtk_label_new (NULL); + gtk_box_append (GTK_BOX (box), data->name); } static GListModel * @@ -305,8 +350,8 @@ main (int argc, char *argv[]) listview = gtk_list_view_new (); gtk_list_view_set_functions (GTK_LIST_VIEW (listview), + setup_widget, NULL, - bind_widget, NULL, NULL); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);