summaryrefslogtreecommitdiff
path: root/gtk/gtkgridview.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2020-06-26 02:56:38 +0200
committerBenjamin Otte <otte@redhat.com>2020-06-26 07:13:32 +0200
commita5949960bcfe62a810c9fa7d42729d614602f7e2 (patch)
treecad90e098372876d33f56c277067e17a3ac846a3 /gtk/gtkgridview.c
parentec4a48909356ca4c764beb3d57f8da957894d53f (diff)
downloadgtk+-a5949960bcfe62a810c9fa7d42729d614602f7e2.tar.gz
listbase: Compute rubberband region on-demand
Instead of storing the active items as we go, compute the affected items whenever the rubberband changes and in particular when the rubberband ends. That way, the rubberband is guaranteed to select a rectangle even after scrolling very far. This is achieved by having a get_items_in_rect() vfunc that selects all the items in the rubberbanded rectangle and returns them as a bitset.
Diffstat (limited to 'gtk/gtkgridview.c')
-rw-r--r--gtk/gtkgridview.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/gtk/gtkgridview.c b/gtk/gtkgridview.c
index ac3d49cdda..3a1b96098e 100644
--- a/gtk/gtkgridview.c
+++ b/gtk/gtkgridview.c
@@ -21,6 +21,7 @@
#include "gtkgridview.h"
+#include "gtkbitset.h"
#include "gtkintl.h"
#include "gtklistbaseprivate.h"
#include "gtklistitemfactory.h"
@@ -452,6 +453,36 @@ gtk_grid_view_get_position_from_allocation (GtkListBase *base,
return TRUE;
}
+static GtkBitset *
+gtk_grid_view_get_items_in_rect (GtkListBase *base,
+ const GdkRectangle *rect)
+{
+ GtkGridView *self = GTK_GRID_VIEW (base);
+ guint first_row, last_row, first_column, last_column, n_items;
+ GtkBitset *result;
+
+ result = gtk_bitset_new_empty ();
+
+ n_items = gtk_list_base_get_n_items (base);
+ if (n_items == 0)
+ return result;
+
+ first_column = floor (rect->x / self->column_width);
+ last_column = floor ((rect->x + rect->width) / self->column_width);
+ if (!gtk_grid_view_get_cell_at_y (self, rect->y, &first_row, NULL, NULL))
+ first_row = rect->y < 0 ? 0 : n_items - 1;
+ if (!gtk_grid_view_get_cell_at_y (self, rect->y + rect->height, &last_row, NULL, NULL))
+ last_row = rect->y < 0 ? 0 : n_items - 1;
+
+ gtk_bitset_add_rectangle (result,
+ first_row + first_column,
+ last_column - first_column + 1,
+ (last_row - first_row) / self->n_columns + 1,
+ self->n_columns);
+
+ return result;
+}
+
static guint
gtk_grid_view_move_focus_along (GtkListBase *base,
guint pos,
@@ -1000,6 +1031,7 @@ gtk_grid_view_class_init (GtkGridViewClass *klass)
list_base_class->list_item_augment_func = cell_augment;
list_base_class->get_allocation_along = gtk_grid_view_get_allocation_along;
list_base_class->get_allocation_across = gtk_grid_view_get_allocation_across;
+ list_base_class->get_items_in_rect = gtk_grid_view_get_items_in_rect;
list_base_class->get_position_from_allocation = gtk_grid_view_get_position_from_allocation;
list_base_class->move_focus_along = gtk_grid_view_move_focus_along;
list_base_class->move_focus_across = gtk_grid_view_move_focus_across;