mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
stats: make number of z-levels dynamic
Other users of the qtquick code might have different needs for z-levels. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
4c43764b36
commit
533cff96f3
5 changed files with 50 additions and 44 deletions
|
@ -19,7 +19,7 @@ static int round_up(double f)
|
|||
return static_cast<int>(ceil(f));
|
||||
}
|
||||
|
||||
ChartItem::ChartItem(StatsView &v, ChartZValue z) :
|
||||
ChartItem::ChartItem(StatsView &v, size_t z) :
|
||||
dirty(false), prev(nullptr), next(nullptr),
|
||||
zValue(z), view(v)
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ void ChartItem::markDirty()
|
|||
view.registerDirtyChartItem(*this);
|
||||
}
|
||||
|
||||
ChartPixmapItem::ChartPixmapItem(StatsView &v, ChartZValue z) : HideableChartItem(v, z),
|
||||
ChartPixmapItem::ChartPixmapItem(StatsView &v, size_t z) : HideableChartItem(v, z),
|
||||
positionDirty(false), textureDirty(false)
|
||||
{
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ QRectF ChartPixmapItem::getRect() const
|
|||
static const int scatterItemDiameter = 10;
|
||||
static const int scatterItemBorder = 1;
|
||||
|
||||
ChartScatterItem::ChartScatterItem(StatsView &v, ChartZValue z, const StatsTheme &theme, bool selected) : HideableChartItem(v, z),
|
||||
ChartScatterItem::ChartScatterItem(StatsView &v, size_t z, const StatsTheme &theme, bool selected) : HideableChartItem(v, z),
|
||||
theme(theme),
|
||||
positionDirty(false), textureDirty(false),
|
||||
highlight(selected ? Highlight::Selected : Highlight::Unselected)
|
||||
|
@ -214,7 +214,7 @@ QRectF ChartScatterItem::getRect() const
|
|||
return rect;
|
||||
}
|
||||
|
||||
ChartRectItem::ChartRectItem(StatsView &v, ChartZValue z,
|
||||
ChartRectItem::ChartRectItem(StatsView &v, size_t z,
|
||||
const QPen &pen, const QBrush &brush, double radius) : ChartPixmapItem(v, z),
|
||||
pen(pen), brush(brush), radius(radius)
|
||||
{
|
||||
|
@ -236,7 +236,7 @@ void ChartRectItem::resize(QSizeF size)
|
|||
painter->drawRoundedRect(rect, radius, radius, Qt::AbsoluteSize);
|
||||
}
|
||||
|
||||
ChartTextItem::ChartTextItem(StatsView &v, ChartZValue z, const QFont &f, const std::vector<QString> &text, bool center) :
|
||||
ChartTextItem::ChartTextItem(StatsView &v, size_t z, const QFont &f, const std::vector<QString> &text, bool center) :
|
||||
ChartPixmapItem(v, z), f(f), center(center)
|
||||
{
|
||||
QFontMetrics fm(f);
|
||||
|
@ -254,7 +254,7 @@ ChartTextItem::ChartTextItem(StatsView &v, ChartZValue z, const QFont &f, const
|
|||
resize(QSizeF(totalWidth, totalHeight));
|
||||
}
|
||||
|
||||
ChartTextItem::ChartTextItem(StatsView &v, ChartZValue z, const QFont &f, const QString &text) :
|
||||
ChartTextItem::ChartTextItem(StatsView &v, size_t z, const QFont &f, const QString &text) :
|
||||
ChartTextItem(v, z, f, std::vector<QString>({ text }), true)
|
||||
{
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ void ChartTextItem::setColor(const QColor &c, const QColor &background)
|
|||
setTextureDirty();
|
||||
}
|
||||
|
||||
ChartPieItem::ChartPieItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth) : ChartPixmapItem(v, z),
|
||||
ChartPieItem::ChartPieItem(StatsView &v, size_t z, const StatsTheme &theme, double borderWidth) : ChartPixmapItem(v, z),
|
||||
theme(theme),
|
||||
borderWidth(borderWidth)
|
||||
{
|
||||
|
@ -322,7 +322,7 @@ void ChartPieItem::resize(QSizeF size)
|
|||
img->fill(Qt::transparent);
|
||||
}
|
||||
|
||||
ChartLineItemBase::ChartLineItemBase(StatsView &v, ChartZValue z, QColor color, double width) : HideableChartItem(v, z),
|
||||
ChartLineItemBase::ChartLineItemBase(StatsView &v, size_t z, QColor color, double width) : HideableChartItem(v, z),
|
||||
color(color), width(width), positionDirty(false), materialDirty(false)
|
||||
{
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ void ChartRectLineItem::render()
|
|||
positionDirty = materialDirty = false;
|
||||
}
|
||||
|
||||
ChartBarItem::ChartBarItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth) : HideableChartItem(v, z),
|
||||
ChartBarItem::ChartBarItem(StatsView &v, size_t z, const StatsTheme &theme, double borderWidth) : HideableChartItem(v, z),
|
||||
theme(theme),
|
||||
borderWidth(borderWidth), selected(false),
|
||||
positionDirty(false), colorDirty(false), selectedDirty(false)
|
||||
|
@ -548,7 +548,7 @@ QRectF ChartBarItem::getRect() const
|
|||
return rect;
|
||||
}
|
||||
|
||||
ChartBoxItem::ChartBoxItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth) :
|
||||
ChartBoxItem::ChartBoxItem(StatsView &v, size_t z, const StatsTheme &theme, double borderWidth) :
|
||||
ChartBarItem(v, z, theme, borderWidth)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ class QSGTexture;
|
|||
class QSGTextureMaterial;
|
||||
class StatsTheme;
|
||||
class StatsView;
|
||||
enum class ChartZValue : int;
|
||||
|
||||
class ChartItem {
|
||||
public:
|
||||
|
@ -26,10 +25,10 @@ public:
|
|||
virtual void render() = 0;
|
||||
bool dirty; // If true, call render() when rebuilding the scene
|
||||
ChartItem *prev, *next; // Double linked list of items
|
||||
const ChartZValue zValue;
|
||||
const size_t zValue;
|
||||
virtual ~ChartItem(); // Attention: must only be called by render thread.
|
||||
protected:
|
||||
ChartItem(StatsView &v, ChartZValue z);
|
||||
ChartItem(StatsView &v, size_t z);
|
||||
QSizeF sceneSize() const;
|
||||
StatsView &view;
|
||||
void markDirty();
|
||||
|
@ -38,7 +37,7 @@ protected:
|
|||
template <typename Node>
|
||||
class HideableChartItem : public ChartItem {
|
||||
protected:
|
||||
HideableChartItem(StatsView &v, ChartZValue z);
|
||||
HideableChartItem(StatsView &v, size_t z);
|
||||
std::unique_ptr<Node> node;
|
||||
bool visible;
|
||||
bool visibleChanged;
|
||||
|
@ -56,7 +55,7 @@ using HideableChartProxyItem = HideableChartItem<HideableQSGNode<QSGProxyNode<No
|
|||
// A chart item that blits a precalculated pixmap onto the scene.
|
||||
class ChartPixmapItem : public HideableChartProxyItem<QSGImageNode> {
|
||||
public:
|
||||
ChartPixmapItem(StatsView &v, ChartZValue z);
|
||||
ChartPixmapItem(StatsView &v, size_t z);
|
||||
~ChartPixmapItem();
|
||||
|
||||
void setPos(QPointF pos);
|
||||
|
@ -78,7 +77,7 @@ private:
|
|||
// Draw a rectangular background after resize. Children are responsible for calling update().
|
||||
class ChartRectItem : public ChartPixmapItem {
|
||||
public:
|
||||
ChartRectItem(StatsView &v, ChartZValue z, const QPen &pen, const QBrush &brush, double radius);
|
||||
ChartRectItem(StatsView &v, size_t z, const QPen &pen, const QBrush &brush, double radius);
|
||||
~ChartRectItem();
|
||||
void resize(QSizeF size);
|
||||
private:
|
||||
|
@ -90,8 +89,8 @@ private:
|
|||
// Attention: text is only drawn after calling setColor()!
|
||||
class ChartTextItem : public ChartPixmapItem {
|
||||
public:
|
||||
ChartTextItem(StatsView &v, ChartZValue z, const QFont &f, const std::vector<QString> &text, bool center);
|
||||
ChartTextItem(StatsView &v, ChartZValue z, const QFont &f, const QString &text);
|
||||
ChartTextItem(StatsView &v, size_t z, const QFont &f, const std::vector<QString> &text, bool center);
|
||||
ChartTextItem(StatsView &v, size_t z, const QFont &f, const QString &text);
|
||||
void setColor(const QColor &color); // Draw on transparent background
|
||||
void setColor(const QColor &color, const QColor &background); // Fill rectangle with given background color
|
||||
private:
|
||||
|
@ -108,7 +107,7 @@ private:
|
|||
// A pie chart item: draws disk segments onto a pixmap.
|
||||
class ChartPieItem : public ChartPixmapItem {
|
||||
public:
|
||||
ChartPieItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth);
|
||||
ChartPieItem(StatsView &v, size_t z, const StatsTheme &theme, double borderWidth);
|
||||
void drawSegment(double from, double to, QColor fill, QColor border, bool selected); // from and to are relative (0-1 is full disk).
|
||||
void resize(QSizeF size); // As in base class, but clears the canvas
|
||||
private:
|
||||
|
@ -119,7 +118,7 @@ private:
|
|||
// Common data for line and rect items. Both are represented by two points.
|
||||
class ChartLineItemBase : public HideableChartItem<HideableQSGNode<QSGGeometryNode>> {
|
||||
public:
|
||||
ChartLineItemBase(StatsView &v, ChartZValue z, QColor color, double width);
|
||||
ChartLineItemBase(StatsView &v, size_t z, QColor color, double width);
|
||||
~ChartLineItemBase();
|
||||
void setLine(QPointF from, QPointF to);
|
||||
protected:
|
||||
|
@ -148,7 +147,7 @@ public:
|
|||
// A bar in a bar chart: a rectangle bordered by lines.
|
||||
class ChartBarItem : public HideableChartProxyItem<QSGRectangleNode> {
|
||||
public:
|
||||
ChartBarItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth);
|
||||
ChartBarItem(StatsView &v, size_t z, const StatsTheme &theme, double borderWidth);
|
||||
~ChartBarItem();
|
||||
void setColor(QColor color, QColor borderColor);
|
||||
void setRect(const QRectF &rect);
|
||||
|
@ -178,7 +177,7 @@ private:
|
|||
// A box-and-whiskers item. This is a bit lazy: derive from the bar item and add whiskers.
|
||||
class ChartBoxItem : public ChartBarItem {
|
||||
public:
|
||||
ChartBoxItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth);
|
||||
ChartBoxItem(StatsView &v, size_t z, const StatsTheme &theme, double borderWidth);
|
||||
~ChartBoxItem();
|
||||
void setBox(const QRectF &rect, double min, double max, double median); // The rect describes Q1, Q3.
|
||||
QRectF getRect() const; // Note: this extends the center rectangle to include the whiskers.
|
||||
|
@ -196,7 +195,7 @@ private:
|
|||
// scatter item here, but so it is for now.
|
||||
class ChartScatterItem : public HideableChartProxyItem<QSGImageNode> {
|
||||
public:
|
||||
ChartScatterItem(StatsView &v, ChartZValue z, const StatsTheme &theme, bool selected);
|
||||
ChartScatterItem(StatsView &v, size_t z, const StatsTheme &theme, bool selected);
|
||||
~ChartScatterItem();
|
||||
|
||||
// Currently, there is no highlighted and selected status.
|
||||
|
@ -240,7 +239,7 @@ void HideableChartItem<Node>::createNode(Args&&... args)
|
|||
}
|
||||
|
||||
template <typename Node>
|
||||
HideableChartItem<Node>::HideableChartItem(StatsView &v, ChartZValue z) : ChartItem(v, z),
|
||||
HideableChartItem<Node>::HideableChartItem(StatsView &v, size_t z) : ChartItem(v, z),
|
||||
visible(true), visibleChanged(false)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "core/selection.h"
|
||||
#include "core/trip.h"
|
||||
|
||||
#include <array> // for std::array
|
||||
#include <cmath>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
|
@ -35,6 +34,7 @@ static const double titleBorder = 2.0; // Border between title and chart
|
|||
static const double selectionLassoWidth = 2.0; // Border between title and chart
|
||||
|
||||
StatsView::StatsView(QQuickItem *parent) : QQuickItem(parent),
|
||||
maxZ(ChartZValue::Count),
|
||||
backgroundDirty(true),
|
||||
currentTheme(&getStatsTheme(false)),
|
||||
backgroundColor(currentTheme->backgroundColor),
|
||||
|
@ -129,16 +129,18 @@ using ZNode = HideableQSGNode<QSGNode>;
|
|||
class RootNode : public QSGNode
|
||||
{
|
||||
public:
|
||||
RootNode(StatsView &view, QColor backgroundColor);
|
||||
RootNode(StatsView &view, QColor backgroundColor, size_t maxZ);
|
||||
~RootNode();
|
||||
StatsView &view;
|
||||
std::unique_ptr<QSGRectangleNode> backgroundNode; // solid background
|
||||
// We entertain one node per Z-level.
|
||||
std::array<std::unique_ptr<ZNode>, (size_t)ChartZValue::Count> zNodes;
|
||||
std::vector<std::unique_ptr<ZNode>> zNodes;
|
||||
};
|
||||
|
||||
RootNode::RootNode(StatsView &view, QColor backgroundColor) : view(view)
|
||||
RootNode::RootNode(StatsView &view, QColor backgroundColor, size_t maxZ) : view(view)
|
||||
{
|
||||
zNodes.resize(maxZ);
|
||||
|
||||
// Add a background rectangle with a solid color. This could
|
||||
// also be done on the widget level, but would have to be done
|
||||
// separately for desktop and mobile, so do it here.
|
||||
|
@ -172,7 +174,7 @@ QSGNode *StatsView::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNod
|
|||
// This is just a copy of what is found in Qt's documentation.
|
||||
RootNode *n = static_cast<RootNode *>(oldNode);
|
||||
if (!n)
|
||||
n = rootNode = new RootNode(*this, backgroundColor);
|
||||
n = rootNode = new RootNode(*this, backgroundColor, maxZ);
|
||||
|
||||
// Delete all chart items that are marked for deletion.
|
||||
freeDeletedChartItems();
|
||||
|
@ -217,9 +219,9 @@ void StatsView::emergencyShutdown()
|
|||
rootNode = nullptr;
|
||||
}
|
||||
|
||||
void StatsView::addQSGNode(QSGNode *node, ChartZValue z)
|
||||
void StatsView::addQSGNode(QSGNode *node, size_t z)
|
||||
{
|
||||
int idx = std::clamp((int)z, 0, (int)ChartZValue::Count - 1);
|
||||
size_t idx = std::clamp(z, (size_t)0, maxZ);
|
||||
rootNode->zNodes[idx]->appendChildNode(node);
|
||||
}
|
||||
|
||||
|
@ -617,7 +619,7 @@ void StatsView::updateFeatures()
|
|||
|
||||
// For labels, we are brutal: simply show/hide the whole z-level with the labels
|
||||
if (rootNode)
|
||||
rootNode->zNodes[(int)ChartZValue::SeriesLabels]->setVisible(state.labels);
|
||||
rootNode->zNodes[ChartZValue::SeriesLabels]->setVisible(state.labels);
|
||||
|
||||
if (meanMarker)
|
||||
meanMarker->setVisible(state.mean);
|
||||
|
|
|
@ -34,7 +34,6 @@ class QSGTexture;
|
|||
class RootNode; // Internal implementation detail
|
||||
|
||||
enum class ChartSubType : int;
|
||||
enum class ChartZValue : int;
|
||||
enum class StatsOperation : int;
|
||||
enum class ChartSortMode : int;
|
||||
|
||||
|
@ -56,7 +55,7 @@ public:
|
|||
void setBackgroundColor(QColor color); // Chart must be replot for color to become effective.
|
||||
void setTheme(bool dark); // Chart must be replot for theme to become effective.
|
||||
const StatsTheme &getCurrentTheme() const;
|
||||
void addQSGNode(QSGNode *node, ChartZValue z); // Must only be called in render thread!
|
||||
void addQSGNode(QSGNode *node, size_t z); // Must only be called in render thread!
|
||||
void registerChartItem(ChartItem &item);
|
||||
void registerDirtyChartItem(ChartItem &item);
|
||||
void emergencyShutdown(); // Called when QQuick decides to delete our root node.
|
||||
|
@ -76,6 +75,7 @@ private slots:
|
|||
void divesSelected(const QVector<dive *> &dives);
|
||||
private:
|
||||
// QtQuick related things
|
||||
size_t maxZ;
|
||||
bool backgroundDirty;
|
||||
QRectF plotRect;
|
||||
QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override;
|
||||
|
|
|
@ -5,16 +5,21 @@
|
|||
// drawn in order of addition to the scene.
|
||||
#ifndef ZVALUES_H
|
||||
|
||||
enum class ChartZValue {
|
||||
Grid = 0,
|
||||
Series,
|
||||
Axes,
|
||||
SeriesLabels,
|
||||
ChartFeatures, // quartile markers and regression lines
|
||||
Selection,
|
||||
InformationBox,
|
||||
Legend,
|
||||
Count
|
||||
// Encapsulating an enum in a struct is stupid, but allows us
|
||||
// to not poison the namespace and yet autoconvert to int
|
||||
// (in constrast to enum class). enum is so broken!
|
||||
struct ChartZValue {
|
||||
enum ZValues {
|
||||
Grid = 0,
|
||||
Series,
|
||||
Axes,
|
||||
SeriesLabels,
|
||||
ChartFeatures, // quartile markers and regression lines
|
||||
Selection,
|
||||
InformationBox,
|
||||
Legend,
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue