summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-04-07 04:00:00 +0200
committerBenjamin Otte <otte@redhat.com>2023-04-11 15:59:43 +0200
commit77f3cd00a93a14fdce07d3ab1919c68be3611d3c (patch)
tree093d0d017d10253ac47c513d50f489d06928a23d
parenta1f41485f87cb4fa0ae1121e54411dc4559014d0 (diff)
downloadgtk+-77f3cd00a93a14fdce07d3ab1919c68be3611d3c.tar.gz
listitemmanager: Add section tiles
For now, we just have a HEADER at the start and a FOOTER at the end. That's hard enough to get right.
-rw-r--r--gtk/gtklistitemmanager.c13
-rw-r--r--gtk/gtklistitemmanagerprivate.h4
-rw-r--r--testsuite/gtk/listitemmanager.c65
3 files changed, 82 insertions, 0 deletions
diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c
index f976b0063e..10ca102e27 100644
--- a/gtk/gtklistitemmanager.c
+++ b/gtk/gtklistitemmanager.c
@@ -132,6 +132,7 @@ gtk_list_item_manager_new (GtkWidget *widget,
GtkListItemBase * (* create_widget) (GtkWidget *))
{
GtkListItemManager *self;
+ GtkListTile *header, *footer;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
@@ -148,6 +149,12 @@ gtk_list_item_manager_new (GtkWidget *widget,
gtk_list_item_manager_clear_node,
NULL);
+ header = gtk_rb_tree_insert_after (self->items, NULL);
+ header->type = GTK_LIST_TILE_HEADER;
+
+ footer = gtk_rb_tree_insert_before (self->items, NULL);
+ footer->type = GTK_LIST_TILE_FOOTER;
+
return self;
}
@@ -618,6 +625,8 @@ gtk_list_item_manager_add_items (GtkListItemManager *self,
return;
tile = gtk_list_item_manager_get_nth (self, position, &offset);
+ if (tile == NULL)
+ tile = gtk_rb_tree_get_last (self->items);
if (offset)
tile = gtk_list_item_manager_ensure_split (self, tile, offset);
@@ -761,6 +770,10 @@ gtk_list_tile_gc (GtkListItemManager *self,
continue;
break;
+ case GTK_LIST_TILE_HEADER:
+ case GTK_LIST_TILE_FOOTER:
+ case GTK_LIST_TILE_UNMATCHED_HEADER:
+ case GTK_LIST_TILE_UNMATCHED_FOOTER:
case GTK_LIST_TILE_FILLER:
break;
diff --git a/gtk/gtklistitemmanagerprivate.h b/gtk/gtklistitemmanagerprivate.h
index df6e0d1211..9efaf0461b 100644
--- a/gtk/gtklistitemmanagerprivate.h
+++ b/gtk/gtklistitemmanagerprivate.h
@@ -46,6 +46,10 @@ typedef struct _GtkListItemTracker GtkListItemTracker;
typedef enum
{
GTK_LIST_TILE_ITEM,
+ GTK_LIST_TILE_HEADER,
+ GTK_LIST_TILE_FOOTER,
+ GTK_LIST_TILE_UNMATCHED_HEADER,
+ GTK_LIST_TILE_UNMATCHED_FOOTER,
GTK_LIST_TILE_FILLER,
GTK_LIST_TILE_REMOVED,
} GtkListTileType;
diff --git a/testsuite/gtk/listitemmanager.c b/testsuite/gtk/listitemmanager.c
index a8d3096239..38dcf8238a 100644
--- a/testsuite/gtk/listitemmanager.c
+++ b/testsuite/gtk/listitemmanager.c
@@ -45,6 +45,11 @@ check_list_item_manager (GtkListItemManager *items,
GtkListTile *tile;
guint n_items = 0;
guint i;
+ enum {
+ NO_SECTION,
+ MATCHED_SECTION,
+ UNMATCHED_SECTION
+ } section_state = NO_SECTION;
for (tile = gtk_list_item_manager_get_first (items);
tile != NULL;
@@ -52,7 +57,36 @@ check_list_item_manager (GtkListItemManager *items,
{
switch (tile->type)
{
+ case GTK_LIST_TILE_HEADER:
+ g_assert_cmpint (section_state, ==, NO_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = MATCHED_SECTION;
+ break;
+
+ case GTK_LIST_TILE_UNMATCHED_HEADER:
+ g_assert_cmpint (section_state, ==, NO_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = UNMATCHED_SECTION;
+ break;
+
+ case GTK_LIST_TILE_FOOTER:
+ g_assert_cmpint (section_state, ==, MATCHED_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = NO_SECTION;
+ break;
+
+ case GTK_LIST_TILE_UNMATCHED_FOOTER:
+ g_assert_cmpint (section_state, ==, UNMATCHED_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = NO_SECTION;
+ break;
+
case GTK_LIST_TILE_ITEM:
+ g_assert_cmpint (section_state, !=, NO_SECTION);
if (tile->widget)
{
GObject *item = g_list_model_get_item (model, n_items);
@@ -81,6 +115,7 @@ check_list_item_manager (GtkListItemManager *items,
}
}
+ g_assert_cmpint (section_state, ==, NO_SECTION);
g_assert_cmpint (n_items, ==, g_list_model_get_n_items (model));
for (i = 0; i < n_trackers; i++)
@@ -109,7 +144,36 @@ check_list_item_manager (GtkListItemManager *items,
{
switch (tile->type)
{
+ case GTK_LIST_TILE_HEADER:
+ g_assert_cmpint (section_state, ==, NO_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = MATCHED_SECTION;
+ break;
+
+ case GTK_LIST_TILE_UNMATCHED_HEADER:
+ g_assert_cmpint (section_state, ==, NO_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = UNMATCHED_SECTION;
+ break;
+
+ case GTK_LIST_TILE_FOOTER:
+ g_assert_cmpint (section_state, ==, MATCHED_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = NO_SECTION;
+ break;
+
+ case GTK_LIST_TILE_UNMATCHED_FOOTER:
+ g_assert_cmpint (section_state, ==, UNMATCHED_SECTION);
+ g_assert_cmpint (tile->n_items, ==, 0);
+ g_assert_false (tile->widget);
+ section_state = NO_SECTION;
+ break;
+
case GTK_LIST_TILE_ITEM:
+ g_assert_cmpint (section_state, !=, NO_SECTION);
if (tile->widget)
{
g_assert_cmpint (tile->n_items, ==, 1);
@@ -126,6 +190,7 @@ check_list_item_manager (GtkListItemManager *items,
}
}
+ g_assert_cmpint (section_state, ==, NO_SECTION);
g_assert_cmpint (n_items, ==, g_list_model_get_n_items (model));
for (i = 0; i < n_trackers; i++)