summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2021-01-31 21:30:51 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2021-02-13 13:02:54 -0800
commite38b78b2aa787e3d1de97fb737601dc30a7fad6b (patch)
treeedac9dafd1bdb94acc184ae767ec9afb80cd808e
parentd85b3217840656bf371cd64264ee472a68c3141a (diff)
downloadsubsurface-e38b78b2aa787e3d1de97fb737601dc30a7fad6b.tar.gz
statistics: select multiple dives in scatter-plot by shift-clicking
Somewhat improve selection mechanics in the scatter-plot by allowing additional selections with shift-clicking. When the dives under the mouse are already selected, then deselect them. This appears to be a rather common UI idiom in desktop applications. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r--stats/barseries.cpp2
-rw-r--r--stats/barseries.h2
-rw-r--r--stats/boxseries.cpp2
-rw-r--r--stats/boxseries.h2
-rw-r--r--stats/pieseries.cpp2
-rw-r--r--stats/pieseries.h2
-rw-r--r--stats/scatterseries.cpp35
-rw-r--r--stats/scatterseries.h2
-rw-r--r--stats/statsseries.h2
-rw-r--r--stats/statsview.cpp3
10 files changed, 41 insertions, 13 deletions
diff --git a/stats/barseries.cpp b/stats/barseries.cpp
index a501ddea9..ad956c454 100644
--- a/stats/barseries.cpp
+++ b/stats/barseries.cpp
@@ -406,7 +406,7 @@ void BarSeries::unhighlight()
highlighted = Index();
}
-void BarSeries::selectItemsUnderMouse(const QPointF &pos)
+void BarSeries::selectItemsUnderMouse(const QPointF &pos, bool)
{
Index index = getItemUnderMouse(pos);
if (index.bar < 0)
diff --git a/stats/barseries.h b/stats/barseries.h
index 9e0eec355..190efe19d 100644
--- a/stats/barseries.h
+++ b/stats/barseries.h
@@ -69,7 +69,7 @@ public:
void updatePositions() override;
bool hover(QPointF pos) override;
void unhighlight() override;
- void selectItemsUnderMouse(const QPointF &point) override;
+ void selectItemsUnderMouse(const QPointF &point, bool shiftPressed) override;
private:
BarSeries(StatsView &view, StatsAxis *xAxis, StatsAxis *yAxis,
diff --git a/stats/boxseries.cpp b/stats/boxseries.cpp
index 564842001..3d2de0e82 100644
--- a/stats/boxseries.cpp
+++ b/stats/boxseries.cpp
@@ -143,7 +143,7 @@ void BoxSeries::unhighlight()
highlighted = -1;
}
-void BoxSeries::selectItemsUnderMouse(const QPointF &pos)
+void BoxSeries::selectItemsUnderMouse(const QPointF &pos, bool)
{
int index = getItemUnderMouse(pos);
if (index < 0)
diff --git a/stats/boxseries.h b/stats/boxseries.h
index ccf8b9883..d4ec09ac8 100644
--- a/stats/boxseries.h
+++ b/stats/boxseries.h
@@ -23,7 +23,7 @@ public:
void updatePositions() override;
bool hover(QPointF pos) override;
void unhighlight() override;
- void selectItemsUnderMouse(const QPointF &point) override;
+ void selectItemsUnderMouse(const QPointF &point, bool shiftPressed) override;
// Note: this expects that all items are added with increasing pos
// and that no bar is inside another bar, i.e. lowerBound and upperBound
diff --git a/stats/pieseries.cpp b/stats/pieseries.cpp
index ff0690bb8..9f55d41d2 100644
--- a/stats/pieseries.cpp
+++ b/stats/pieseries.cpp
@@ -265,7 +265,7 @@ void PieSeries::unhighlight()
highlighted = -1;
}
-void PieSeries::selectItemsUnderMouse(const QPointF &pos)
+void PieSeries::selectItemsUnderMouse(const QPointF &pos, bool)
{
int index = getItemUnderMouse(pos);
if (index < 0)
diff --git a/stats/pieseries.h b/stats/pieseries.h
index 2706fbb41..d41469029 100644
--- a/stats/pieseries.h
+++ b/stats/pieseries.h
@@ -28,7 +28,7 @@ public:
void updatePositions() override;
bool hover(QPointF pos) override;
void unhighlight() override;
- void selectItemsUnderMouse(const QPointF &point) override;
+ void selectItemsUnderMouse(const QPointF &point, bool shiftPressed) override;
std::vector<QString> binNames();
diff --git a/stats/scatterseries.cpp b/stats/scatterseries.cpp
index f88837288..fe9889d33 100644
--- a/stats/scatterseries.cpp
+++ b/stats/scatterseries.cpp
@@ -78,12 +78,39 @@ std::vector<int> ScatterSeries::getItemsUnderMouse(const QPointF &point) const
return res;
}
-void ScatterSeries::selectItemsUnderMouse(const QPointF &point)
+void ScatterSeries::selectItemsUnderMouse(const QPointF &point, bool shiftPressed)
{
std::vector<struct dive *> selected;
-
- for(int idx: getItemsUnderMouse(point))
- selected.push_back(items[idx].d);
+ std::vector<int> indices = getItemsUnderMouse(point);
+
+ if (shiftPressed) {
+ // When shift is pressed, add the items under the mouse to the selection
+ // or, if all items under the mouse are selected, remove them.
+ selected = getDiveSelection();
+ bool allSelected = std::all_of(indices.begin(), indices.end(),
+ [this] (int idx) { return items[idx].d->selected; });
+ if (allSelected) {
+ // Remove items under cursor from selection. This could be made more efficient.
+ for (int idx: indices) {
+ auto it = std::find(selected.begin(), selected.end(), items[idx].d);
+ if (it != selected.end()) {
+ // Move last element to deselected element. If this already was
+ // the last element, this is a no-op. Then, chop off last element.
+ *it = selected.back();
+ selected.pop_back();
+ }
+ }
+ } else {
+ // Add items under cursor to selection
+ for (int idx: indices) {
+ if (std::find(selected.begin(), selected.end(), items[idx].d) == selected.end())
+ selected.push_back(items[idx].d);
+ }
+ }
+ } else {
+ for(int idx: indices)
+ selected.push_back(items[idx].d);
+ }
setSelection(selected, selected.empty() ? nullptr : selected.front());
}
diff --git a/stats/scatterseries.h b/stats/scatterseries.h
index 6f24c58e5..35526dfc0 100644
--- a/stats/scatterseries.h
+++ b/stats/scatterseries.h
@@ -27,7 +27,7 @@ public:
// Note: this expects that all items are added with increasing pos!
void append(dive *d, double pos, double value);
- void selectItemsUnderMouse(const QPointF &point) override;
+ void selectItemsUnderMouse(const QPointF &point, bool shiftPressed) override;
private:
// Get items under mouse.
diff --git a/stats/statsseries.h b/stats/statsseries.h
index 8a4003550..cee2ec0a8 100644
--- a/stats/statsseries.h
+++ b/stats/statsseries.h
@@ -17,7 +17,7 @@ public:
virtual void updatePositions() = 0; // Called if chart geometry changes.
virtual bool hover(QPointF pos) = 0; // Called on mouse movement. Return true if an item of this series is highlighted.
virtual void unhighlight() = 0; // Unhighlight any highlighted item.
- virtual void selectItemsUnderMouse(const QPointF &pos) = 0;
+ virtual void selectItemsUnderMouse(const QPointF &pos, bool shiftPressed) = 0;
virtual void divesSelected(const QVector<dive *> &dives);
protected:
diff --git a/stats/statsview.cpp b/stats/statsview.cpp
index bf4ecdc6a..9ee0f0e44 100644
--- a/stats/statsview.cpp
+++ b/stats/statsview.cpp
@@ -81,8 +81,9 @@ void StatsView::mousePressEvent(QMouseEvent *event)
}
}
+ bool shiftPressed = event->modifiers() & Qt::ShiftModifier;
for (auto &series: series)
- series->selectItemsUnderMouse(pos);
+ series->selectItemsUnderMouse(pos, shiftPressed);
}
void StatsView::mouseReleaseEvent(QMouseEvent *)