summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2020-01-04 21:18:48 +0100
committerAndreas Kling <awesomekling@gmail.com>2020-01-04 21:18:48 +0100
commit6e21d5c432eb3fb81541535d0998c8b7c0975e60 (patch)
tree5c318838e111443bea3e997d31e60570665658d4
parentd4761762f2628a239deb1a598eac09ea66774fb7 (diff)
downloadserenity-6e21d5c432eb3fb81541535d0998c8b7c0975e60.zip
LibGUI: Add basic rubber band selection in GItemView
-rw-r--r--Libraries/LibGUI/GItemView.cpp41
-rw-r--r--Libraries/LibGUI/GItemView.h6
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;
};