1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-09 17:44:56 +09:00

LibGUI: Implement basic rubber band selections in ColumnsView

This patch adds the ability to select multiple entries in a column using
a rubber band selection. Currently the implementation is lacking support
for expanding a selection using the ctrl modifier.
This commit is contained in:
networkException 2022-09-04 16:48:44 +02:00 committed by Linus Groh
parent f0a20fc902
commit 9b6fab264f
Notes: sideshowbarker 2024-07-17 07:31:20 +09:00
2 changed files with 80 additions and 0 deletions

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
* Copyright (c) 2022, the SerenityOS developers.
* Copyright (c) 2022, Jakob-Niklas See <git@nwex.de>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -57,6 +58,29 @@ void ColumnsView::select_all()
}
}
void ColumnsView::second_paint_event(PaintEvent& event)
{
if (!m_rubber_banding)
return;
Painter painter(*this);
painter.add_clip_rect(event.rect());
painter.add_clip_rect(widget_inner_rect());
painter.translate(frame_thickness(), frame_thickness());
painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value());
int column_x = 0;
for (auto const& column : m_columns) {
if (m_rubber_band_origin_column.parent_index == column.parent_index)
break;
column_x += column.width + 1;
}
auto rubber_band_rect = Gfx::IntRect::from_two_points({ column_x, m_rubber_band_origin }, { column_x + m_rubber_band_origin_column.width, m_rubber_band_current });
painter.fill_rect(rubber_band_rect, palette().rubber_band_fill());
painter.draw_rect(rubber_band_rect, palette().rubber_band_border());
}
void ColumnsView::paint_event(PaintEvent& event)
{
AbstractView::paint_event(event);
@ -280,6 +304,54 @@ void ColumnsView::mousedown_event(MouseEvent& event)
if (index.is_valid() && !(event.modifiers() & Mod_Ctrl)) {
if (model()->row_count(index))
push_column(index);
return;
}
if (selection_mode() == SelectionMode::MultiSelection) {
m_rubber_banding = true;
m_rubber_band_origin_column = *column;
m_rubber_band_origin = event.position().y();
m_rubber_band_current = event.position().y();
}
}
void ColumnsView::mousemove_event(MouseEvent& event)
{
if (m_rubber_banding) {
m_rubber_band_current = AK::clamp(event.position().y(), 0, widget_inner_rect().height());
auto parent = m_rubber_band_origin_column.parent_index;
int row_count = model()->row_count(parent);
clear_selection();
set_suppress_update_on_selection_change(true);
for (int row = 0; row < row_count; row++) {
auto index = model()->index(row, m_model_column, parent);
VERIFY(index.is_valid());
int row_top = row * item_height();
int row_bottom = row * item_height() + item_height();
if ((m_rubber_band_origin > row_top && m_rubber_band_current < row_top) || (m_rubber_band_origin > row_bottom && m_rubber_band_current < row_bottom)) {
add_selection(index);
}
}
set_suppress_update_on_selection_change(false);
update();
}
AbstractView::mousemove_event(event);
}
void ColumnsView::mouseup_event(MouseEvent& event)
{
if (m_rubber_banding && event.button() == MouseButton::Primary) {
m_rubber_banding = false;
update();
}
}

View file

@ -34,8 +34,11 @@ private:
int text_padding() const { return 2; }
virtual void model_did_update(unsigned flags) override;
virtual void second_paint_event(PaintEvent&) override;
virtual void paint_event(PaintEvent&) override;
virtual void mousedown_event(MouseEvent& event) override;
virtual void mousemove_event(MouseEvent&) override;
virtual void mouseup_event(MouseEvent&) override;
virtual void select_range(ModelIndex const&) override;
@ -51,6 +54,11 @@ private:
Optional<Column> column_at_event_position(Gfx::IntPoint const&) const;
ModelIndex index_at_event_position_in_column(Gfx::IntPoint const&, Column const&) const;
bool m_rubber_banding { false };
int m_rubber_band_origin { 0 };
Column m_rubber_band_origin_column;
int m_rubber_band_current { 0 };
Vector<Column> m_columns;
int m_model_column { 0 };
};