mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 06:21:14 +00:00
listitemmanager: Remove section when adding at its end
We are failing to go from this: [ BLUE ] [ RED ] ...to this: [ BLUE GREEN YELLOW ] [ RED ] ...where '[' and ']' represent section header and footer. Instead, the result is... [ BLUE ] [ GREEN YELLOW ] [ RED ] ... despite the first 3 items belonging to the same section according to the section model. This leaves the view in an inconsistent state and, ultimately, to crashes the non-removed footer. Indeed, when receiving items-changed(1,0,2), we call `append_items()` which inserts a new tile before the tile at `1` (which was RED), and then notices there is a HEADER right befo-re it, so it flags both it and the corresponding FOOTER as unmatched: [ BLUE ] ( GREEN-YELLOW RED ) ... where '(' and ')' represent unmatched header and footer. Problem is subsequent code in `release_items()` doesn't even touch the section boundary footer-header pair ('] ('), because they are belong in the tracked interval (visible items). And `ensure_items()` proceeds to match the header with a new footer, producing the result described above. To handle this correctly, `append_items()` must delete the section boundary, and flag as unmatched both the HEADER of the section before and the FOOTER of section after (whose respective footer and header has been marked for removal): ( BLUE . . GREEN-YELLOW RED ) ... where '.' represents tiles marked for removal. This way, `release_items()` will release the removed footer-header section boundary, and `ensure_items()` is going to reinstate new section remove the section boundary at the correct place, resulting in the expected behavior: [ BLUE GREEN YELLOW ] [ RED ]
This commit is contained in:
parent
4b45adaf39
commit
b05000d8bd
@ -968,10 +968,26 @@ gtk_list_item_manager_add_items (GtkListItemManager *self,
|
||||
|
||||
if (section != NULL && section->type == GTK_LIST_TILE_HEADER)
|
||||
{
|
||||
guint start, end;
|
||||
GtkListTile *footer = gtk_list_tile_get_footer (self, section);
|
||||
GtkListTile *previous_footer = gtk_list_tile_get_previous_skip (section);
|
||||
|
||||
gtk_section_model_get_section (GTK_SECTION_MODEL (self->model), position, &start, &end);
|
||||
|
||||
if (previous_footer != NULL && previous_footer->type == GTK_LIST_TILE_FOOTER &&
|
||||
position > start && position < end)
|
||||
{
|
||||
gtk_list_item_change_clear_header (change, §ion->widget);
|
||||
gtk_list_tile_set_type (section, GTK_LIST_TILE_REMOVED);
|
||||
gtk_list_tile_set_type (previous_footer, GTK_LIST_TILE_REMOVED);
|
||||
|
||||
section = gtk_list_tile_get_header (self, previous_footer);
|
||||
}
|
||||
|
||||
gtk_list_item_change_clear_header (change, §ion->widget);
|
||||
gtk_list_tile_set_type (section,
|
||||
GTK_LIST_TILE_UNMATCHED_HEADER);
|
||||
gtk_list_tile_set_type (gtk_list_tile_get_footer (self, section),
|
||||
gtk_list_tile_set_type (footer,
|
||||
GTK_LIST_TILE_UNMATCHED_FOOTER);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user