Merge branch 'gridview' into 'main'
Gridview fix rubberbanding issues Closes #3462 and #3445 See merge request GNOME/gtk!4688
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user