mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
5c098eea29
commit
d85b321784
9 changed files with 68 additions and 8 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *> &)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue