[gtk/wip/otte/canvas: 1/2] listview: cull listitems that are out of view




commit f186a5b8496ecb301305628b8782a51fc9ec93bc
Author: Benjamin Otte <otte redhat com>
Date:   Wed Jun 1 04:29:15 2022 +0200

    listview: cull listitems that are out of view
    
    Use set_child_visible(FALSE) on those widgets and don't allocate them.
    
    This should usually be the majority of items, so it's quite a worthwhile
    addition.

 gtk/gtklistbase.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)
---
diff --git a/gtk/gtklistbase.c b/gtk/gtklistbase.c
index bf0657a04f..81c95d1a4d 100644
--- a/gtk/gtklistbase.c
+++ b/gtk/gtklistbase.c
@@ -37,6 +37,13 @@
 #include "gtktypebuiltins.h"
 #include "gtkwidgetprivate.h"
 
+/* Allow shadows to overdraw without immediately culling the widget at the viewport
+ * boundary.
+ * Choose this so that roughly 1 extra widget gets drawn on each side of the viewport,
+ * but not more. Icons are 16px, text height is somewhere there, too.
+ */
+#define GTK_LIST_BASE_CHILD_MAX_OVERDRAW 10
+
 typedef struct _RubberbandData RubberbandData;
 
 struct _RubberbandData
@@ -1351,6 +1358,22 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
                                    int          height)
 {
   GtkAllocation child_allocation;
+  int self_width, self_height;
+
+  self_width = gtk_widget_get_width (GTK_WIDGET (self));
+  self_height = gtk_widget_get_height (GTK_WIDGET (self));
+
+  if (y + height + GTK_LIST_BASE_CHILD_MAX_OVERDRAW <= 0 ||
+      y - GTK_LIST_BASE_CHILD_MAX_OVERDRAW >= self_height ||
+      x + width + GTK_LIST_BASE_CHILD_MAX_OVERDRAW <= 0 ||
+      x - GTK_LIST_BASE_CHILD_MAX_OVERDRAW >= self_width)
+    {
+      /* child is fully outside the viewport, hide it and don't allocate it */
+      gtk_widget_set_child_visible (child, FALSE);
+      return;
+    }
+
+  gtk_widget_set_child_visible (child, TRUE);
 
   if (gtk_list_base_get_orientation (GTK_LIST_BASE (self)) == GTK_ORIENTATION_VERTICAL)
     {
@@ -1363,9 +1386,7 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
         }
       else
         {
-          int mirror_point = gtk_widget_get_width (GTK_WIDGET (self));
-
-          child_allocation.x = mirror_point - x - width;
+          child_allocation.x = self_width - x - width;
           child_allocation.y = y;
           child_allocation.width = width;
           child_allocation.height = height;
@@ -1382,9 +1403,7 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
         }
       else
         {
-          int mirror_point = gtk_widget_get_width (GTK_WIDGET (self));
-
-          child_allocation.x = mirror_point - y - height;
+          child_allocation.x = self_width - y - height;
           child_allocation.y = x;
           child_allocation.width = height;
           child_allocation.height = width;


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