aboutsummaryrefslogtreecommitdiffstats
path: root/stats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2021-01-31 20:48:12 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2021-02-13 13:02:54 -0800
commitd85b3217840656bf371cd64264ee472a68c3141a (patch)
tree8f5a9ffb3e956c1b262b3a36e88e0b0895b09878 /stats
parent5c098eea29fdb1cd663b78db4e430a1c76c2209a (diff)
downloadsubsurface-d85b3217840656bf371cd64264ee472a68c3141a.tar.gz
statistics: show selected dives in scatter plot
As a visual feedback, show the selected dives in the scatter plot. React to application-wide selection changes. Currently, the dive list is deactivated while in statistics mode, but that may change. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'stats')
-rw-r--r--stats/chartitem.cpp25
-rw-r--r--stats/chartitem.h11
-rw-r--r--stats/scatterseries.cpp19
-rw-r--r--stats/scatterseries.h2
-rw-r--r--stats/statscolors.h2
-rw-r--r--stats/statsseries.cpp4
-rw-r--r--stats/statsseries.h2
-rw-r--r--stats/statsview.cpp10
-rw-r--r--stats/statsview.h1
9 files changed, 68 insertions, 8 deletions
diff --git a/stats/chartitem.cpp b/stats/chartitem.cpp
index c8bdd130e..93f374e14 100644
--- a/stats/chartitem.cpp
+++ b/stats/chartitem.cpp
@@ -108,7 +108,7 @@ static const int scatterItemDiameter = 10;
static const int scatterItemBorder = 1;
ChartScatterItem::ChartScatterItem(StatsView &v, ChartZValue z) : HideableChartItem(v, z),
- positionDirty(false), textureDirty(false), highlighted(false)
+ positionDirty(false), textureDirty(false), highlight(Highlight::Unselected)
{
rect.setSize(QSizeF(static_cast<double>(scatterItemDiameter), static_cast<double>(scatterItemDiameter)));
}
@@ -138,12 +138,27 @@ static QSGTexture *createScatterTexture(StatsView &view, const QColor &color, co
// QApplication finished its thread leads to crashes. Therefore, these
// are now normal pointers and the texture objects are leaked.
static QSGTexture *scatterItemTexture = nullptr;
+static QSGTexture *scatterItemSelectedTexture = nullptr;
static QSGTexture *scatterItemHighlightedTexture = nullptr;
+QSGTexture *ChartScatterItem::getTexture() const
+{
+ switch (highlight) {
+ default:
+ case Highlight::Unselected:
+ return scatterItemTexture;
+ case Highlight::Selected:
+ return scatterItemSelectedTexture;
+ case Highlight::Highlighted:
+ return scatterItemHighlightedTexture;
+ }
+}
+
void ChartScatterItem::render()
{
if (!scatterItemTexture) {
scatterItemTexture = createScatterTexture(view, fillColor, borderColor);
+ scatterItemSelectedTexture = createScatterTexture(view, selectedColor, selectedBorderColor);
scatterItemHighlightedTexture = createScatterTexture(view, highlightedColor, highlightedBorderColor);
}
if (!node) {
@@ -153,7 +168,7 @@ void ChartScatterItem::render()
}
updateVisible();
if (textureDirty) {
- node->node->setTexture(highlighted ? scatterItemHighlightedTexture : scatterItemTexture);
+ node->node->setTexture(getTexture());
textureDirty = false;
}
if (positionDirty) {
@@ -181,11 +196,11 @@ bool ChartScatterItem::contains(QPointF point) const
return squareDist(point, rect.center()) <= (scatterItemDiameter / 2.0) * (scatterItemDiameter / 2.0);
}
-void ChartScatterItem::setHighlight(bool highlightedIn)
+void ChartScatterItem::setHighlight(Highlight highlightIn)
{
- if (highlighted == highlightedIn)
+ if (highlight == highlightIn)
return;
- highlighted = highlightedIn;
+ highlight = highlightIn;
textureDirty = true;
markDirty();
}
diff --git a/stats/chartitem.h b/stats/chartitem.h
index cf20f55a8..c700cb421 100644
--- a/stats/chartitem.h
+++ b/stats/chartitem.h
@@ -174,16 +174,23 @@ public:
ChartScatterItem(StatsView &v, ChartZValue z);
~ChartScatterItem();
+ // Currently, there is no highlighted and selected status.
+ enum class Highlight {
+ Unselected,
+ Selected,
+ Highlighted
+ };
void setPos(QPointF pos); // Specifies the *center* of the item.
- void setHighlight(bool highlight); // In the future, support different kinds of scatter items.
+ void setHighlight(Highlight highlight); // In the future, support different kinds of scatter items.
void render() override; // Only call on render thread!
QRectF getRect() const;
bool contains(QPointF point) const;
private:
+ QSGTexture *getTexture() const;
QRectF rect;
QSizeF textureSize;
bool positionDirty, textureDirty;
- bool highlighted;
+ Highlight highlight;
};
// Implementation detail of templates - move to serparate header file
diff --git a/stats/scatterseries.cpp b/stats/scatterseries.cpp
index d5bf69ebb..f88837288 100644
--- a/stats/scatterseries.cpp
+++ b/stats/scatterseries.cpp
@@ -27,6 +27,7 @@ ScatterSeries::~ScatterSeries()
ScatterSeries::Item::Item(StatsView &view, ScatterSeries *series, dive *d, double pos, double value) :
item(view.createChartItem<ChartScatterItem>(ChartZValue::Series)),
d(d),
+ selected(d->selected),
pos(pos),
value(value)
{
@@ -40,7 +41,11 @@ void ScatterSeries::Item::updatePosition(ScatterSeries *series)
void ScatterSeries::Item::highlight(bool highlight)
{
- item->setHighlight(highlight);
+ ChartScatterItem::Highlight status = d->selected ?
+ ChartScatterItem::Highlight::Selected : ChartScatterItem::Highlight::Unselected;
+ if (highlight)
+ status = ChartScatterItem::Highlight::Highlighted;
+ item->setHighlight(status);
}
void ScatterSeries::append(dive *d, double pos, double value)
@@ -164,3 +169,15 @@ void ScatterSeries::unhighlight()
items[idx].highlight(false);
highlighted.clear();
}
+
+void ScatterSeries::divesSelected(const QVector<dive *> &)
+{
+ for (Item &item: items) {
+ if (item.selected != item.d->selected) {
+ item.selected = item.d->selected;
+ int idx = &item - &items[0];
+ bool highlight = std::find(highlighted.begin(), highlighted.end(), idx) != highlighted.end();
+ item.highlight(highlight);
+ }
+ }
+}
diff --git a/stats/scatterseries.h b/stats/scatterseries.h
index a0dbcd82e..6f24c58e5 100644
--- a/stats/scatterseries.h
+++ b/stats/scatterseries.h
@@ -36,6 +36,7 @@ private:
struct Item {
ChartItemPtr<ChartScatterItem> item;
dive *d;
+ bool selected;
double pos, value;
Item(StatsView &view, ScatterSeries *series, dive *d, double pos, double value);
void updatePosition(ScatterSeries *series);
@@ -47,6 +48,7 @@ private:
std::vector<int> highlighted;
const StatsVariable &varX;
const StatsVariable &varY;
+ void divesSelected(const QVector<dive *> &) override;
};
#endif
diff --git a/stats/statscolors.h b/stats/statscolors.h
index e1800b550..d8198911c 100644
--- a/stats/statscolors.h
+++ b/stats/statscolors.h
@@ -8,6 +8,8 @@
inline const QColor backgroundColor(Qt::white);
inline const QColor fillColor(0x44, 0x76, 0xaa);
inline const QColor borderColor(0x66, 0xb2, 0xff);
+inline const QColor selectedColor(0xaa, 0x76, 0x44);
+inline const QColor selectedBorderColor(0xff, 0xb2, 0x66);
inline const QColor highlightedColor(Qt::yellow);
inline const QColor highlightedBorderColor(0xaa, 0xaa, 0x22);
inline const QColor darkLabelColor(Qt::black);
diff --git a/stats/statsseries.cpp b/stats/statsseries.cpp
index 60e54e127..18fc0a3ff 100644
--- a/stats/statsseries.cpp
+++ b/stats/statsseries.cpp
@@ -16,3 +16,7 @@ QPointF StatsSeries::toScreen(QPointF p)
return xAxis && yAxis ? QPointF(xAxis->toScreen(p.x()), yAxis->toScreen(p.y()))
: QPointF(0.0, 0.0);
}
+
+void StatsSeries::divesSelected(const QVector<dive *> &)
+{
+}
diff --git a/stats/statsseries.h b/stats/statsseries.h
index 5a29118fb..8a4003550 100644
--- a/stats/statsseries.h
+++ b/stats/statsseries.h
@@ -8,6 +8,7 @@
class StatsAxis;
class StatsView;
+struct dive;
class StatsSeries {
public:
@@ -17,6 +18,7 @@ public:
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 divesSelected(const QVector<dive *> &dives);
protected:
StatsView &view;
diff --git a/stats/statsview.cpp b/stats/statsview.cpp
index 61d9db4a6..bf4ecdc6a 100644
--- a/stats/statsview.cpp
+++ b/stats/statsview.cpp
@@ -46,6 +46,7 @@ StatsView::StatsView(QQuickItem *parent) : QQuickItem(parent),
connect(&diveListNotifier, &DiveListNotifier::divesDeleted, this, &StatsView::replotIfVisible);
connect(&diveListNotifier, &DiveListNotifier::dataReset, this, &StatsView::replotIfVisible);
connect(&diveListNotifier, &DiveListNotifier::settingsChanged, this, &StatsView::replotIfVisible);
+ connect(&diveListNotifier, &DiveListNotifier::divesSelected, this, &StatsView::divesSelected);
setAcceptHoverEvents(true);
setAcceptedMouseButtons(Qt::LeftButton);
@@ -345,6 +346,15 @@ void StatsView::replotIfVisible()
plot(state);
}
+void StatsView::divesSelected(const QVector<dive *> &dives)
+{
+ if (isVisible()) {
+ for (auto &series: series)
+ series->divesSelected(dives);
+ }
+ update();
+}
+
void StatsView::mouseMoveEvent(QMouseEvent *event)
{
if (!draggedItem)
diff --git a/stats/statsview.h b/stats/statsview.h
index cc497792b..87dcdad29 100644
--- a/stats/statsview.h
+++ b/stats/statsview.h
@@ -64,6 +64,7 @@ public:
void deleteChartItem(ChartItemPtr<T> &item);
private slots:
void replotIfVisible();
+ void divesSelected(const QVector<dive *> &dives);
private:
// QtQuick related things
bool backgroundDirty;