From 215f60e450e7f09ddea002f25ae29f3888921041 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 23 May 2023 13:49:04 -0400 Subject: [PATCH] listitemmanager: Listen to sections-changed And recreate header and footer tiles as needed. This commit was tested using a sortlistmodel, changing the section sorter from sorting only by first char to sorting by the first two chars, which changes the number of sections, but leaves the alphabetic order of items unchanged. --- gtk/gtklistitemmanager.c | 69 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c index aa5c9b1bf8..3c63c70ac3 100644 --- a/gtk/gtklistitemmanager.c +++ b/gtk/gtklistitemmanager.c @@ -1565,6 +1565,67 @@ gtk_list_item_manager_model_items_changed_cb (GListModel *model, gtk_widget_queue_resize (self->widget); } +static void +gtk_list_item_manager_model_sections_changed_cb (GListModel *model, + guint position, + guint n_items, + GtkListItemManager *self) +{ + GtkListItemChange change; + GtkListTile *tile, *header; + guint offset; + + if (!gtk_list_item_manager_has_sections (self)) + return; + + gtk_list_item_change_init (&change); + + tile = gtk_list_item_manager_get_nth (self, position, &offset); + header = gtk_list_tile_get_header (self, tile); + gtk_list_item_change_clear_header (&change, &header->widget); + gtk_list_tile_set_type (header, GTK_LIST_TILE_UNMATCHED_HEADER); + + n_items -= MIN (n_items, position - offset); + while (n_items > 0) + { + switch (tile->type) + { + case GTK_LIST_TILE_HEADER: + case GTK_LIST_TILE_UNMATCHED_HEADER: + gtk_list_item_change_clear_header (&change, &tile->widget); + gtk_list_tile_set_type (tile, GTK_LIST_TILE_REMOVED); + break; + + case GTK_LIST_TILE_FOOTER: + case GTK_LIST_TILE_UNMATCHED_FOOTER: + gtk_list_tile_set_type (tile, GTK_LIST_TILE_REMOVED); + break; + + case GTK_LIST_TILE_ITEM: + n_items -= MIN (n_items, tile->n_items); + break; + + case GTK_LIST_TILE_REMOVED: + default: + g_assert_not_reached (); + break; + } + + tile = gtk_list_tile_get_next_skip (tile); + } + + if (!gtk_list_tile_is_footer (tile)) + tile = gtk_list_tile_get_footer (self, tile); + + gtk_list_tile_set_type (tile, GTK_LIST_TILE_UNMATCHED_FOOTER); + + gtk_list_item_manager_ensure_items (self, &change, G_MAXUINT, 0); + + gtk_list_item_change_finish (&change); + + gtk_widget_queue_resize (GTK_WIDGET (self->widget)); +} + static void gtk_list_item_manager_model_selection_changed_cb (GListModel *model, guint position, @@ -1624,6 +1685,9 @@ gtk_list_item_manager_clear_model (GtkListItemManager *self) g_signal_handlers_disconnect_by_func (self->model, gtk_list_item_manager_model_items_changed_cb, self); + g_signal_handlers_disconnect_by_func (self->model, + gtk_list_item_manager_model_sections_changed_cb, + self); g_clear_object (&self->model); gtk_list_item_manager_gc_tiles (self); @@ -1682,6 +1746,11 @@ gtk_list_item_manager_set_model (GtkListItemManager *self, "selection-changed", G_CALLBACK (gtk_list_item_manager_model_selection_changed_cb), self); + if (GTK_IS_SECTION_MODEL (model)) + g_signal_connect (model, + "sections-changed", + G_CALLBACK (gtk_list_item_manager_model_sections_changed_cb), + self); gtk_list_item_change_init (&change); gtk_list_item_manager_add_items (self, &change, 0, g_list_model_get_n_items (G_LIST_MODEL (model))); -- 2.30.2