mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 14:31:10 +00:00
listview: Implement extending selections
Shift-clicking to extend selections now also works, imitating the behavior of normal clicking and Windows Explorer (but not treeview): 1. We track the last selected item (normally, not via extend-clicking). 2. When shift-selecting, we modify the range from the last selected item to this item the same way we modify the regular item when not using shift: 2a. If Ctrl is not pressed, we select the range and unselect everything else. 2b. If Ctrl is pressed, we make the range have the same selection state as the last selected item: - If the last selected item is selected, select the range. - If the last selected item is not selected, unselect the range.
This commit is contained in:
parent
f57fca7a00
commit
cfcf0a7a8a
@ -68,6 +68,8 @@ struct _GtkListView
|
||||
|
||||
GtkListItemTracker *anchor;
|
||||
double anchor_align;
|
||||
/* the last item that was selected - basically the location to extend selections from */
|
||||
GtkListItemTracker *selected;
|
||||
};
|
||||
|
||||
struct _ListRow
|
||||
@ -567,6 +569,11 @@ gtk_list_view_dispose (GObject *object)
|
||||
gtk_list_item_tracker_free (self->item_manager, self->anchor);
|
||||
self->anchor = NULL;
|
||||
}
|
||||
if (self->selected)
|
||||
{
|
||||
gtk_list_item_tracker_free (self->item_manager, self->selected);
|
||||
self->selected = NULL;
|
||||
}
|
||||
g_clear_object (&self->item_manager);
|
||||
|
||||
G_OBJECT_CLASS (gtk_list_view_parent_class)->dispose (object);
|
||||
@ -712,22 +719,66 @@ gtk_list_view_select_item (GtkWidget *widget,
|
||||
GtkSelectionModel *selection_model;
|
||||
guint pos;
|
||||
gboolean modify, extend;
|
||||
gboolean success = FALSE;
|
||||
|
||||
selection_model = gtk_list_item_manager_get_model (self->item_manager);
|
||||
g_variant_get (parameter, "(ubb)", &pos, &modify, &extend);
|
||||
|
||||
/* XXX: handle extend by tracking the item to extend from */
|
||||
if (extend)
|
||||
{
|
||||
guint start_pos = gtk_list_item_tracker_get_position (self->item_manager, self->selected);
|
||||
if (start_pos != GTK_INVALID_LIST_POSITION)
|
||||
{
|
||||
guint max = MAX (start_pos, pos);
|
||||
guint min = MIN (start_pos, pos);
|
||||
if (modify)
|
||||
{
|
||||
if (gtk_selection_model_is_selected (selection_model, start_pos))
|
||||
{
|
||||
success = gtk_selection_model_select_range (selection_model,
|
||||
min,
|
||||
max - min + 1,
|
||||
FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = gtk_selection_model_unselect_range (selection_model,
|
||||
min,
|
||||
max - min + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = gtk_selection_model_select_range (selection_model,
|
||||
min,
|
||||
max - min + 1,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
/* If there's no range to select or selecting ranges isn't supported
|
||||
* by the model, fall through to normal setting.
|
||||
*/
|
||||
}
|
||||
if (success)
|
||||
return;
|
||||
|
||||
if (modify)
|
||||
{
|
||||
if (gtk_selection_model_is_selected (selection_model, pos))
|
||||
gtk_selection_model_unselect_item (selection_model, pos);
|
||||
success = gtk_selection_model_unselect_item (selection_model, pos);
|
||||
else
|
||||
gtk_selection_model_select_item (selection_model, pos, FALSE);
|
||||
success = gtk_selection_model_select_item (selection_model, pos, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_selection_model_select_item (selection_model, pos, TRUE);
|
||||
success = gtk_selection_model_select_item (selection_model, pos, TRUE);
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
gtk_list_item_tracker_set_position (self->item_manager,
|
||||
self->selected,
|
||||
pos,
|
||||
0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -872,6 +923,7 @@ gtk_list_view_init (GtkListView *self)
|
||||
{
|
||||
self->item_manager = gtk_list_item_manager_new (GTK_WIDGET (self), ListRow, ListRowAugment, list_row_augment);
|
||||
self->anchor = gtk_list_item_tracker_new (self->item_manager);
|
||||
self->selected = gtk_list_item_tracker_new (self->item_manager);
|
||||
|
||||
self->adjustment[GTK_ORIENTATION_HORIZONTAL] = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
self->adjustment[GTK_ORIENTATION_VERTICAL] = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
|
Loading…
Reference in New Issue
Block a user