[gtk/wip/otte/listview: 310/327] listview: Make the listitemmanager stricter



commit ae1331ee92b65fcfba46446a362860377078041e
Author: Benjamin Otte <otte redhat com>
Date:   Fri Sep 21 05:32:00 2018 +0200

    listview: Make the listitemmanager stricter
    
    Require that items created with the manager get destroyed via the
    manager.
    
    To that purpose, renamed create_list_item() to acquire_list_item() and
    add a matching release_list_item() function.
    
    This way, the manager can in the future keep track of all items and
    cache information about them.

 gtk/gtklistitemmanager.c        | 35 ++++++++++++++++++++++++++++++-----
 gtk/gtklistitemmanagerprivate.h |  4 +++-
 gtk/gtklistview.c               | 10 ++++++----
 3 files changed, 39 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c
index 500cc38e5e..2f2a1d2db9 100644
--- a/gtk/gtklistitemmanager.c
+++ b/gtk/gtklistitemmanager.c
@@ -149,21 +149,27 @@ gtk_list_item_manager_model_changed (GtkListItemManager *self,
 }
 
 /*
- * gtk_list_item_manager_create_list_item:
+ * gtk_list_item_manager_acquire_list_item:
  * @self: a #GtkListItemManager
  * @position: the row in the model to create a list item for
  * @next_sibling: the widget this widget should be inserted before or %NULL
  *     if none
  *
- * Creates a new list item widget to use for @position. No widget may
+ * Creates a list item widget to use for @position. No widget may
  * yet exist that is used for @position.
  *
+ * When the returned item is no longer needed, the caller is responsible
+ * for calling gtk_list_item_manager_release_list_item().  
+ * A particular case is when the row at @position is removed. In that case,
+ * all list items in the removed range must be released before
+ * gtk_list_item_manager_model_changed() is called.
+ *
  * Returns: a properly setup widget to use in @position
  **/
 GtkWidget *
-gtk_list_item_manager_create_list_item (GtkListItemManager *self,
-                                        guint               position,
-                                        GtkWidget          *next_sibling)
+gtk_list_item_manager_acquire_list_item (GtkListItemManager *self,
+                                         guint               position,
+                                         GtkWidget          *next_sibling)
 {
   GtkListItem *result;
   gpointer item;
@@ -179,3 +185,22 @@ gtk_list_item_manager_create_list_item (GtkListItemManager *self,
 
   return GTK_WIDGET (result);
 }
+
+/*
+ * gtk_list_item_manager_release_list_item:
+ * @self: a #GtkListItemManager
+ * @item: an item previously acquired with
+ *     gtk_list_item_manager_acquire_list_item()
+ *
+ * Releases an item that was previously acquired via
+ * gtk_list_item_manager_acquire_list_item() and is no longer in use.
+ **/
+void
+gtk_list_item_manager_release_list_item (GtkListItemManager *self,
+                                         GtkWidget          *item)
+{
+  g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
+  g_return_if_fail (GTK_IS_LIST_ITEM (item));
+
+  gtk_widget_unparent (item);
+}
diff --git a/gtk/gtklistitemmanagerprivate.h b/gtk/gtklistitemmanagerprivate.h
index 34b57da97e..84f574576e 100644
--- a/gtk/gtklistitemmanagerprivate.h
+++ b/gtk/gtklistitemmanagerprivate.h
@@ -53,9 +53,11 @@ void                    gtk_list_item_manager_model_changed     (GtkListItemMana
                                                                  guint                   position,
                                                                  guint                   removed,
                                                                  guint                   added);
-GtkWidget *             gtk_list_item_manager_create_list_item  (GtkListItemManager     *self,
+GtkWidget *             gtk_list_item_manager_acquire_list_item (GtkListItemManager     *self,
                                                                  guint                   position,
                                                                  GtkWidget              *next_sibling);
+void                    gtk_list_item_manager_release_list_item (GtkListItemManager     *self,
+                                                                 GtkWidget              *widget);
 
 G_END_DECLS
 
diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c
index 23fd8c482b..852f74775b 100644
--- a/gtk/gtklistview.c
+++ b/gtk/gtklistview.c
@@ -126,7 +126,7 @@ list_row_clear (gpointer _row)
 {
   ListRow *row = _row;
 
-  g_clear_pointer (&row->widget, gtk_widget_unparent);
+  g_assert (row->widget == NULL);
 }
 
 static ListRow *
@@ -489,6 +489,8 @@ gtk_list_view_remove_rows (GtkListView *self,
   for (i = 0; i < n_rows; i++)
     {
       ListRow *next = gtk_css_rb_tree_get_next (self->rows, row);
+      gtk_list_item_manager_release_list_item (self->item_manager, row->widget);
+      row->widget = NULL;
       gtk_css_rb_tree_remove (self->rows, row);
       row = next;
     }
@@ -522,9 +524,9 @@ gtk_list_view_add_rows (GtkListView *self,
         
       new_row = gtk_css_rb_tree_insert_before (self->rows, row);
       new_row->n_rows = 1;
-      new_row->widget = gtk_list_item_manager_create_list_item (self->item_manager,
-                                                                position + i,
-                                                                row ? row->widget : NULL);
+      new_row->widget = gtk_list_item_manager_acquire_list_item (self->item_manager,
+                                                                 position + i,
+                                                                 row ? row->widget : NULL);
     }
 
   gtk_widget_queue_resize (GTK_WIDGET (self));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]