mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
d85b321784
commit
e38b78b2aa
10 changed files with 40 additions and 12 deletions
|
@ -406,7 +406,7 @@ void BarSeries::unhighlight()
|
||||||
highlighted = Index();
|
highlighted = Index();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BarSeries::selectItemsUnderMouse(const QPointF &pos)
|
void BarSeries::selectItemsUnderMouse(const QPointF &pos, bool)
|
||||||
{
|
{
|
||||||
Index index = getItemUnderMouse(pos);
|
Index index = getItemUnderMouse(pos);
|
||||||
if (index.bar < 0)
|
if (index.bar < 0)
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
void updatePositions() override;
|
void updatePositions() override;
|
||||||
bool hover(QPointF pos) override;
|
bool hover(QPointF pos) override;
|
||||||
void unhighlight() override;
|
void unhighlight() override;
|
||||||
void selectItemsUnderMouse(const QPointF &point) override;
|
void selectItemsUnderMouse(const QPointF &point, bool shiftPressed) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BarSeries(StatsView &view, StatsAxis *xAxis, StatsAxis *yAxis,
|
BarSeries(StatsView &view, StatsAxis *xAxis, StatsAxis *yAxis,
|
||||||
|
|
|
@ -143,7 +143,7 @@ void BoxSeries::unhighlight()
|
||||||
highlighted = -1;
|
highlighted = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxSeries::selectItemsUnderMouse(const QPointF &pos)
|
void BoxSeries::selectItemsUnderMouse(const QPointF &pos, bool)
|
||||||
{
|
{
|
||||||
int index = getItemUnderMouse(pos);
|
int index = getItemUnderMouse(pos);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
void updatePositions() override;
|
void updatePositions() override;
|
||||||
bool hover(QPointF pos) override;
|
bool hover(QPointF pos) override;
|
||||||
void unhighlight() 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
|
// Note: this expects that all items are added with increasing pos
|
||||||
// and that no bar is inside another bar, i.e. lowerBound and upperBound
|
// and that no bar is inside another bar, i.e. lowerBound and upperBound
|
||||||
|
|
|
@ -265,7 +265,7 @@ void PieSeries::unhighlight()
|
||||||
highlighted = -1;
|
highlighted = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PieSeries::selectItemsUnderMouse(const QPointF &pos)
|
void PieSeries::selectItemsUnderMouse(const QPointF &pos, bool)
|
||||||
{
|
{
|
||||||
int index = getItemUnderMouse(pos);
|
int index = getItemUnderMouse(pos);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
void updatePositions() override;
|
void updatePositions() override;
|
||||||
bool hover(QPointF pos) override;
|
bool hover(QPointF pos) override;
|
||||||
void unhighlight() override;
|
void unhighlight() override;
|
||||||
void selectItemsUnderMouse(const QPointF &point) override;
|
void selectItemsUnderMouse(const QPointF &point, bool shiftPressed) override;
|
||||||
|
|
||||||
std::vector<QString> binNames();
|
std::vector<QString> binNames();
|
||||||
|
|
||||||
|
|
|
@ -78,12 +78,39 @@ std::vector<int> ScatterSeries::getItemsUnderMouse(const QPointF &point) const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScatterSeries::selectItemsUnderMouse(const QPointF &point)
|
void ScatterSeries::selectItemsUnderMouse(const QPointF &point, bool shiftPressed)
|
||||||
{
|
{
|
||||||
std::vector<struct dive *> selected;
|
std::vector<struct dive *> selected;
|
||||||
|
std::vector<int> indices = getItemsUnderMouse(point);
|
||||||
|
|
||||||
for(int idx: getItemsUnderMouse(point))
|
if (shiftPressed) {
|
||||||
selected.push_back(items[idx].d);
|
// 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());
|
setSelection(selected, selected.empty() ? nullptr : selected.front());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
|
|
||||||
// Note: this expects that all items are added with increasing pos!
|
// Note: this expects that all items are added with increasing pos!
|
||||||
void append(dive *d, double pos, double value);
|
void append(dive *d, double pos, double value);
|
||||||
void selectItemsUnderMouse(const QPointF &point) override;
|
void selectItemsUnderMouse(const QPointF &point, bool shiftPressed) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Get items under mouse.
|
// Get items under mouse.
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
virtual void updatePositions() = 0; // Called if chart geometry changes.
|
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 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 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);
|
virtual void divesSelected(const QVector<dive *> &dives);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -81,8 +81,9 @@ void StatsView::mousePressEvent(QMouseEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool shiftPressed = event->modifiers() & Qt::ShiftModifier;
|
||||||
for (auto &series: series)
|
for (auto &series: series)
|
||||||
series->selectItemsUnderMouse(pos);
|
series->selectItemsUnderMouse(pos, shiftPressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatsView::mouseReleaseEvent(QMouseEvent *)
|
void StatsView::mouseReleaseEvent(QMouseEvent *)
|
||||||
|
|
Loading…
Add table
Reference in a new issue