diff options
-rw-r--r-- | Libraries/LibGUI/GItemView.cpp | 41 | ||||
-rw-r--r-- | Libraries/LibGUI/GItemView.h | 6 |
2 files changed, 47 insertions, 0 deletions
diff --git a/Libraries/LibGUI/GItemView.cpp b/Libraries/LibGUI/GItemView.cpp index 31c69d3299..364c72f579 100644 --- a/Libraries/LibGUI/GItemView.cpp +++ b/Libraries/LibGUI/GItemView.cpp @@ -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()); diff --git a/Libraries/LibGUI/GItemView.h b/Libraries/LibGUI/GItemView.h index 7650775d06..7e8851acac 100644 --- a/Libraries/LibGUI/GItemView.h +++ b/Libraries/LibGUI/GItemView.h @@ -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; }; |