Merge branch 'gridview' into 'main'

Gridview fix rubberbanding issues

Closes #3462 and #3445

See merge request GNOME/gtk!4688
This commit is contained in:
Benjamin Otte
2022-07-26 01:08:08 +00:00
3 changed files with 45 additions and 33 deletions

View File

@@ -204,7 +204,7 @@ cell_augment (GtkRbTree *tree,
* index of the returned row
* @offset: (out caller-allocates) (optional): stores the offset
* in pixels between y and top of cell.
* @offset: (out caller-allocates) (optional): stores the height
* @size: (out caller-allocates) (optional): stores the height
* of the cell
*
* Gets the Cell that occupies the leftmost position in the row at offset
@@ -413,6 +413,19 @@ gtk_grid_view_get_allocation_across (GtkListBase *base,
return TRUE;
}
static int
gtk_grid_view_compute_total_height (GtkGridView *self)
{
Cell *cell;
CellAugment *aug;
cell = gtk_list_item_manager_get_root (self->item_manager);
if (cell == NULL)
return 0;
aug = gtk_list_item_manager_get_item_augment (self->item_manager, cell);
return aug->size;
}
static gboolean
gtk_grid_view_get_position_from_allocation (GtkListBase *base,
int across,
@@ -428,6 +441,7 @@ gtk_grid_view_get_position_from_allocation (GtkListBase *base,
return FALSE;
n_items = gtk_list_base_get_n_items (base);
along = CLAMP (along, 0, gtk_grid_view_compute_total_height (self) - 1);
if (!gtk_grid_view_get_cell_at_y (self,
along,
&pos,
@@ -467,16 +481,19 @@ gtk_grid_view_get_items_in_rect (GtkListBase *base,
result = gtk_bitset_new_empty ();
if (rect->y >= gtk_grid_view_compute_total_height (self))
return result;
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);
first_column = fmax (floor (rect->x / self->column_width), 0);
last_column = fmin (floor ((rect->x + rect->width) / self->column_width), self->n_columns - 1);
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;
last_row = rect->y + rect->height < 0 ? 0 : n_items - 1;
gtk_bitset_add_rectangle (result,
first_row + first_column,
@@ -722,19 +739,6 @@ cell_set_size (Cell *cell,
gtk_rb_tree_node_mark_dirty (cell);
}
static int
gtk_grid_view_compute_total_height (GtkGridView *self)
{
Cell *cell;
CellAugment *aug;
cell = gtk_list_item_manager_get_root (self->item_manager);
if (cell == NULL)
return 0;
aug = gtk_list_item_manager_get_item_augment (self->item_manager, cell);
return aug->size;
}
static void
gtk_grid_view_size_allocate (GtkWidget *widget,
int width,

View File

@@ -1583,25 +1583,28 @@ gtk_list_base_stop_rubberband (GtkListBase *self,
return;
rubberband_selection = gtk_list_base_get_items_in_rect (self, &rect);
if (gtk_bitset_is_empty (rubberband_selection))
{
gtk_bitset_unref (rubberband_selection);
return;
}
if (modify && extend) /* Ctrl + Shift */
{
GtkBitset *current;
guint min = gtk_bitset_get_minimum (rubberband_selection);
guint max = gtk_bitset_get_maximum (rubberband_selection);
/* toggle the rubberband, keep the rest */
current = gtk_selection_model_get_selection_in_range (model, min, max - min + 1);
selected = gtk_bitset_copy (current);
gtk_bitset_unref (current);
gtk_bitset_intersect (selected, rubberband_selection);
gtk_bitset_difference (selected, rubberband_selection);
if (gtk_bitset_is_empty (rubberband_selection))
{
selected = gtk_bitset_ref (rubberband_selection);
mask = gtk_bitset_ref (rubberband_selection);
}
else
{
GtkBitset *current;
guint min = gtk_bitset_get_minimum (rubberband_selection);
guint max = gtk_bitset_get_maximum (rubberband_selection);
/* toggle the rubberband, keep the rest */
current = gtk_selection_model_get_selection_in_range (model, min, max - min + 1);
selected = gtk_bitset_copy (current);
gtk_bitset_unref (current);
gtk_bitset_intersect (selected, rubberband_selection);
gtk_bitset_difference (selected, rubberband_selection);
mask = gtk_bitset_ref (rubberband_selection);
mask = gtk_bitset_ref (rubberband_selection);
}
}
else if (modify) /* Ctrl */
{

View File

@@ -377,6 +377,9 @@ gtk_list_view_get_items_in_rect (GtkListBase *base,
result = gtk_bitset_new_empty ();
if (rect->y >= gtk_list_view_get_list_height (self))
return result;
n_items = gtk_list_base_get_n_items (base);
if (n_items == 0)
return result;
@@ -390,7 +393,7 @@ gtk_list_view_get_items_in_rect (GtkListBase *base,
if (row)
last = gtk_list_item_manager_get_item_position (self->item_manager, row);
else
last = rect->y < 0 ? 0 : n_items - 1;
last = rect->y + rect->height < 0 ? 0 : n_items - 1;
gtk_bitset_add_range_closed (result, first, last);
return result;
@@ -425,6 +428,8 @@ gtk_list_view_get_position_from_allocation (GtkListBase *base,
if (across >= self->list_width)
return FALSE;
along = CLAMP (along, 0, gtk_list_view_get_list_height (self) - 1);
row = gtk_list_view_get_row_at_y (self, along, &remaining);
if (row == NULL)
return FALSE;