1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:58:12 +00:00

LibGUI: Track selection starting index in AbstractView (#6515)

Modifying the selection while holding the shift button and selecting
with the mouse or the arrow keys no longer results in broken selections.

Fixes #6279.
This commit is contained in:
iCristalrope 2021-04-21 17:09:04 +02:00 committed by GitHub
parent fd43ee09e1
commit 8bb4409a5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 13 deletions

View file

@ -91,6 +91,7 @@ void AbstractView::model_did_update(unsigned int flags)
m_drop_candidate_index = {};
selection().remove_matching([this](auto& index) { return !model()->is_valid(index); });
}
m_selection_start_index = {};
}
void AbstractView::clear_selection()
@ -103,6 +104,11 @@ void AbstractView::set_selection(const ModelIndex& new_index)
m_selection.set(new_index);
}
void AbstractView::set_selection_start_index(const ModelIndex& new_index)
{
m_selection_start_index = new_index;
}
void AbstractView::add_selection(const ModelIndex& new_index)
{
m_selection.add(new_index);
@ -341,9 +347,10 @@ void AbstractView::mouseup_event(MouseEvent& event)
// in mousedown_event(), because we could be seeing a start of a drag.
// Since we're here, it was not that; so fix up the selection now.
auto index = index_at_event_position(event.position());
if (index.is_valid())
if (index.is_valid()) {
set_selection(index);
else
set_selection_start_index(index);
} else
clear_selection();
m_might_drag = false;
update();
@ -450,20 +457,21 @@ void AbstractView::set_cursor(ModelIndex index, SelectionUpdate selection_update
selection_update = SelectionUpdate::Set;
if (model()->is_valid(index)) {
if (selection_update == SelectionUpdate::Set)
if (selection_update == SelectionUpdate::Set) {
set_selection(index);
else if (selection_update == SelectionUpdate::Ctrl)
set_selection_start_index(index);
} else if (selection_update == SelectionUpdate::Ctrl) {
toggle_selection(index);
else if (selection_update == SelectionUpdate::ClearIfNotSelected) {
} else if (selection_update == SelectionUpdate::ClearIfNotSelected) {
if (!m_selection.contains(index))
clear_selection();
} else if (selection_update == SelectionUpdate::Shift) {
// Toggle all from cursor to new index.
auto min_row = min(cursor_index().row(), index.row());
auto max_row = max(cursor_index().row(), index.row());
auto min_column = min(cursor_index().column(), index.column());
auto max_column = max(cursor_index().column(), index.column());
auto min_row = min(selection_start_index().row(), index.row());
auto max_row = max(selection_start_index().row(), index.row());
auto min_column = min(selection_start_index().column(), index.column());
auto max_column = max(selection_start_index().column(), index.column());
clear_selection();
for (auto row = min_row; row <= max_row; ++row) {
for (auto column = min_column; column <= max_column; ++column) {
auto new_index = model()->index(row, column);
@ -471,9 +479,6 @@ void AbstractView::set_cursor(ModelIndex index, SelectionUpdate selection_update
toggle_selection(new_index);
}
}
// Finally toggle the cursor index again to make it go back to its current state.
toggle_selection(cursor_index());
}
// FIXME: Support the other SelectionUpdate types