LibGUI: Add basic rubber band selection in GItemView

This commit is contained in:
Andreas Kling 2020-01-04 21:18:48 +01:00
parent d4761762f2
commit 6e21d5c432
Notes: sideshowbarker 2024-07-19 10:21:48 +09:00
2 changed files with 47 additions and 0 deletions

View file

@ -91,6 +91,9 @@ void GItemView::mousedown_event(GMouseEvent& event)
m_left_mousedown_position = event.position();
if (item_index == -1) {
selection().clear();
m_rubber_banding = true;
m_rubber_band_origin = event.position();
m_rubber_band_current = event.position();
} else {
auto index = model()->index(item_index, m_model_column);
if (event.modifiers() & Mod_Ctrl)
@ -103,11 +106,36 @@ void GItemView::mousedown_event(GMouseEvent& event)
GAbstractView::mousedown_event(event);
}
void GItemView::mouseup_event(GMouseEvent& event)
{
if (m_rubber_banding && event.button() == GMouseButton::Left) {
m_rubber_banding = false;
update();
return;
}
GAbstractView::mouseup_event(event);
}
void GItemView::mousemove_event(GMouseEvent& event)
{
if (!model())
return GAbstractView::mousemove_event(event);
if (m_rubber_banding) {
if (m_rubber_band_current != event.position()) {
m_rubber_band_current = event.position();
auto rubber_band_rect = Rect::from_two_points(m_rubber_band_origin, m_rubber_band_current);
selection().clear();
for (int row_index = 0, row_count = model()->row_count(); row_index < row_count; ++row_index) {
auto item_rect = this->item_rect(row_index);
if (item_rect.intersects(rubber_band_rect))
selection().add(model()->index(row_index, model_column()));
}
update();
return;
}
}
if (event.buttons() & GMouseButton::Left && !selection().is_empty()) {
auto diff = event.position() - m_left_mousedown_position;
auto distance_travelled_squared = diff.x() * diff.x() + diff.y() * diff.y();
@ -187,6 +215,19 @@ void GItemView::doubleclick_event(GMouseEvent& event)
}
}
void GItemView::second_paint_event(GPaintEvent& event)
{
if (!m_rubber_banding)
return;
GPainter painter(*this);
painter.add_clip_rect(event.rect());
auto rubber_band_rect = Rect::from_two_points(m_rubber_band_origin, m_rubber_band_current);
painter.fill_rect(rubber_band_rect, Color(244, 202, 158, 60));
painter.draw_rect(rubber_band_rect, Color(110, 34, 9));
}
void GItemView::paint_event(GPaintEvent& event)
{
Color widget_background_color = palette().color(background_role());

View file

@ -27,9 +27,11 @@ private:
virtual void did_update_model() override;
virtual void paint_event(GPaintEvent&) override;
virtual void second_paint_event(GPaintEvent&) override;
virtual void resize_event(GResizeEvent&) override;
virtual void mousedown_event(GMouseEvent&) override;
virtual void mousemove_event(GMouseEvent&) override;
virtual void mouseup_event(GMouseEvent&) override;
virtual void keydown_event(GKeyEvent&) override;
virtual void doubleclick_event(GMouseEvent&) override;
virtual void context_menu_event(GContextMenuEvent&) override;
@ -47,4 +49,8 @@ private:
Point m_left_mousedown_position;
Size m_effective_item_size { 80, 80 };
bool m_rubber_banding { false };
Point m_rubber_band_origin;
Point m_rubber_band_current;
};