From 4c43764b362f166b1c65ff21aedbaaa8c11f86e3 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 16 Apr 2023 12:19:56 +0200 Subject: [PATCH] stats: don't pass StatsTheme in ChartItem::render To make the qt-quick code of the statistics module more general, don't pass the StatsTheme in render calls to ChartItems. Items that need it, may just store a reference to the theme. Signed-off-by: Berthold Stoeger --- stats/barseries.cpp | 2 +- stats/boxseries.cpp | 2 +- stats/chartitem.cpp | 37 ++++++++++++++++++++----------------- stats/chartitem.h | 31 +++++++++++++++++-------------- stats/pieseries.cpp | 4 ++-- stats/scatterseries.cpp | 6 +++--- stats/scatterseries.h | 2 +- stats/statsview.cpp | 2 +- 8 files changed, 46 insertions(+), 40 deletions(-) diff --git a/stats/barseries.cpp b/stats/barseries.cpp index e34013b35..0b9897531 100644 --- a/stats/barseries.cpp +++ b/stats/barseries.cpp @@ -266,7 +266,7 @@ std::vector BarSeries::makeSubItems(std::vector for (auto &[v, dives, label]: items) { if (v > 0.0) { bool selected = allDivesSelected(dives); - res.push_back({ view.createChartItem(ChartZValue::Series, barBorderWidth), + res.push_back({ view.createChartItem(ChartZValue::Series, theme, barBorderWidth), std::move(dives), {}, from, from + v, bin_nr, selected }); if (!label.empty()) diff --git a/stats/boxseries.cpp b/stats/boxseries.cpp index 3e752d336..66a8e3f8d 100644 --- a/stats/boxseries.cpp +++ b/stats/boxseries.cpp @@ -32,7 +32,7 @@ BoxSeries::Item::Item(StatsView &view, BoxSeries *series, double lowerBound, dou binName(binName), selected(allDivesSelected(q.dives)) { - item = view.createChartItem(ChartZValue::Series, boxBorderWidth); + item = view.createChartItem(ChartZValue::Series, theme, boxBorderWidth); highlight(false, theme); updatePosition(series); } diff --git a/stats/chartitem.cpp b/stats/chartitem.cpp index 58724a3b4..77fc0eac4 100644 --- a/stats/chartitem.cpp +++ b/stats/chartitem.cpp @@ -64,7 +64,7 @@ void ChartPixmapItem::setPositionDirty() markDirty(); } -void ChartPixmapItem::render(const StatsTheme &) +void ChartPixmapItem::render() { if (!node) { createNode(view.w()->createImageNode()); @@ -111,7 +111,8 @@ QRectF ChartPixmapItem::getRect() const static const int scatterItemDiameter = 10; static const int scatterItemBorder = 1; -ChartScatterItem::ChartScatterItem(StatsView &v, ChartZValue z, bool selected) : HideableChartItem(v, z), +ChartScatterItem::ChartScatterItem(StatsView &v, ChartZValue z, const StatsTheme &theme, bool selected) : HideableChartItem(v, z), + theme(theme), positionDirty(false), textureDirty(false), highlight(selected ? Highlight::Selected : Highlight::Unselected) { @@ -138,7 +139,7 @@ static QSGTexture *createScatterTexture(StatsView &view, const QColor &color, co return view.w()->createTextureFromImage(img, QQuickWindow::TextureHasAlphaChannel); } -QSGTexture *ChartScatterItem::getTexture(const StatsTheme &theme) const +QSGTexture *ChartScatterItem::getTexture() const { switch (highlight) { default: @@ -151,7 +152,7 @@ QSGTexture *ChartScatterItem::getTexture(const StatsTheme &theme) const } } -void ChartScatterItem::render(const StatsTheme &theme) +void ChartScatterItem::render() { if (!theme.scatterItemTexture) { theme.scatterItemTexture = register_global(createScatterTexture(view, theme.fillColor, theme.borderColor)); @@ -165,7 +166,7 @@ void ChartScatterItem::render(const StatsTheme &theme) } updateVisible(); if (textureDirty) { - node->node->setTexture(getTexture(theme)); + node->node->setTexture(getTexture()); textureDirty = false; } if (positionDirty) { @@ -279,7 +280,8 @@ void ChartTextItem::setColor(const QColor &c, const QColor &background) setTextureDirty(); } -ChartPieItem::ChartPieItem(StatsView &v, ChartZValue z, double borderWidth) : ChartPixmapItem(v, z), +ChartPieItem::ChartPieItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth) : ChartPixmapItem(v, z), + theme(theme), borderWidth(borderWidth) { } @@ -300,7 +302,7 @@ static QBrush makeBrush(QColor fill, bool selected, const StatsTheme &theme) return QBrush(img); } -void ChartPieItem::drawSegment(double from, double to, QColor fill, QColor border, bool selected, const StatsTheme &theme) +void ChartPieItem::drawSegment(double from, double to, QColor fill, QColor border, bool selected) { painter->setPen(QPen(border, borderWidth)); painter->setBrush(makeBrush(fill, selected, theme)); @@ -349,7 +351,7 @@ void setPoint(QSGGeometry::TexturedPoint2D &v, const QPointF &p, const QPointF & static_cast(t.x()), static_cast(t.y())); } -void ChartLineItem::render(const StatsTheme &) +void ChartLineItem::render() { if (!node) { geometry.reset(new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2)); @@ -380,7 +382,7 @@ void ChartLineItem::render(const StatsTheme &) positionDirty = materialDirty = false; } -void ChartRectLineItem::render(const StatsTheme &) +void ChartRectLineItem::render() { if (!node) { geometry.reset(new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 5)); @@ -414,7 +416,8 @@ void ChartRectLineItem::render(const StatsTheme &) positionDirty = materialDirty = false; } -ChartBarItem::ChartBarItem(StatsView &v, ChartZValue z, double borderWidth) : HideableChartItem(v, z), +ChartBarItem::ChartBarItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth) : HideableChartItem(v, z), + theme(theme), borderWidth(borderWidth), selected(false), positionDirty(false), colorDirty(false), selectedDirty(false) { @@ -424,7 +427,7 @@ ChartBarItem::~ChartBarItem() { } -QSGTexture *ChartBarItem::getSelectedTexture(const StatsTheme &theme) const +QSGTexture *ChartBarItem::getSelectedTexture() const { if (!theme.selectedTexture) { QImage img(2, 2, QImage::Format_ARGB32); @@ -436,7 +439,7 @@ QSGTexture *ChartBarItem::getSelectedTexture(const StatsTheme &theme) const return theme.selectedTexture; } -void ChartBarItem::render(const StatsTheme &theme) +void ChartBarItem::render() { if (!node) { createNode(view.w()->createRectangleNode()); @@ -481,7 +484,7 @@ void ChartBarItem::render(const StatsTheme &theme) selectionGeometry.reset(new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)); selectionGeometry->setDrawingMode(QSGGeometry::DrawTriangleStrip); selectionMaterial.reset(new QSGTextureMaterial); - selectionMaterial->setTexture(getSelectedTexture(theme)); + selectionMaterial->setTexture(getSelectedTexture()); selectionMaterial->setHorizontalWrapMode(QSGTexture::Repeat); selectionMaterial->setVerticalWrapMode(QSGTexture::Repeat); selectionNode.reset(new QSGGeometryNode); @@ -545,8 +548,8 @@ QRectF ChartBarItem::getRect() const return rect; } -ChartBoxItem::ChartBoxItem(StatsView &v, ChartZValue z, double borderWidth) : - ChartBarItem(v, z, borderWidth) +ChartBoxItem::ChartBoxItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth) : + ChartBarItem(v, z, theme, borderWidth) { } @@ -554,12 +557,12 @@ ChartBoxItem::~ChartBoxItem() { } -void ChartBoxItem::render(const StatsTheme &theme) +void ChartBoxItem::render() { // Remember old dirty values, since ChartBarItem::render() will clear them bool oldPositionDirty = positionDirty; bool oldColorDirty = colorDirty; - ChartBarItem::render(theme); // This will create the base node, so no need to check for that. + ChartBarItem::render(); // This will create the base node, so no need to check for that. if (!whiskersNode) { whiskersGeometry.reset(new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 10)); whiskersGeometry->setDrawingMode(QSGGeometry::DrawLines); diff --git a/stats/chartitem.h b/stats/chartitem.h index f8fd4134c..7baea1fe9 100644 --- a/stats/chartitem.h +++ b/stats/chartitem.h @@ -23,7 +23,7 @@ enum class ChartZValue : int; class ChartItem { public: // Only call on render thread! - virtual void render(const StatsTheme &theme) = 0; + 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; @@ -60,7 +60,7 @@ public: ~ChartPixmapItem(); void setPos(QPointF pos); - void render(const StatsTheme &theme) override; + void render() override; QRectF getRect() const; protected: void resize(QSizeF size); // Resets the canvas. Attention: image is *unitialized*. @@ -108,10 +108,11 @@ private: // A pie chart item: draws disk segments onto a pixmap. class ChartPieItem : public ChartPixmapItem { public: - ChartPieItem(StatsView &v, ChartZValue z, double borderWidth); - void drawSegment(double from, double to, QColor fill, QColor border, bool selected, const StatsTheme &theme); // from and to are relative (0-1 is full disk). + ChartPieItem(StatsView &v, ChartZValue 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: + const StatsTheme &theme; double borderWidth; }; @@ -134,27 +135,28 @@ protected: class ChartLineItem : public ChartLineItemBase { public: using ChartLineItemBase::ChartLineItemBase; - void render(const StatsTheme &theme) override; + void render() override; }; // A simple rectangle without fill. Specified by any two opposing vertices. class ChartRectLineItem : public ChartLineItemBase { public: using ChartLineItemBase::ChartLineItemBase; - void render(const StatsTheme &theme) override; + void render() override; }; // A bar in a bar chart: a rectangle bordered by lines. class ChartBarItem : public HideableChartProxyItem { public: - ChartBarItem(StatsView &v, ChartZValue z, double borderWidth); + ChartBarItem(StatsView &v, ChartZValue z, const StatsTheme &theme, double borderWidth); ~ChartBarItem(); void setColor(QColor color, QColor borderColor); void setRect(const QRectF &rect); void setSelected(bool selected); QRectF getRect() const; - void render(const StatsTheme &theme) override; + void render() override; protected: + const StatsTheme &theme; QColor color, borderColor; double borderWidth; QRectF rect; @@ -170,17 +172,17 @@ private: std::unique_ptr selectionNode; std::unique_ptr selectionMaterial; std::unique_ptr selectionGeometry; - QSGTexture *getSelectedTexture(const StatsTheme &theme) const; + QSGTexture *getSelectedTexture() const; }; // 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, double borderWidth); + ChartBoxItem(StatsView &v, ChartZValue 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. - void render(const StatsTheme &theme) override; + void render() override; private: double min, max, median; std::unique_ptr whiskersNode; @@ -194,7 +196,7 @@ private: // scatter item here, but so it is for now. class ChartScatterItem : public HideableChartProxyItem { public: - ChartScatterItem(StatsView &v, ChartZValue z, bool selected); + ChartScatterItem(StatsView &v, ChartZValue z, const StatsTheme &theme, bool selected); ~ChartScatterItem(); // Currently, there is no highlighted and selected status. @@ -205,12 +207,13 @@ public: }; void setPos(QPointF pos); // Specifies the *center* of the item. void setHighlight(Highlight highlight); // In the future, support different kinds of scatter items. - void render(const StatsTheme &theme) override; + void render() override; QRectF getRect() const; bool contains(QPointF point) const; bool inRect(const QRectF &rect) const; private: - QSGTexture *getTexture(const StatsTheme &theme) const; + const StatsTheme &theme; + QSGTexture *getTexture() const; QRectF rect; QSizeF textureSize; bool positionDirty, textureDirty; diff --git a/stats/pieseries.cpp b/stats/pieseries.cpp index 3f246d6f6..9403e426f 100644 --- a/stats/pieseries.cpp +++ b/stats/pieseries.cpp @@ -78,13 +78,13 @@ void PieSeries::Item::highlight(ChartPieItem &item, int bin_nr, bool highlight, QColor border = highlight ? theme.highlightedBorderColor : theme.borderColor; if (innerLabel) innerLabel->setColor(highlight ? theme.darkLabelColor : theme.labelColor(bin_nr, numBins), fill); - item.drawSegment(angleFrom, angleTo, fill, border, selected, theme); + item.drawSegment(angleFrom, angleTo, fill, border, selected); } PieSeries::PieSeries(StatsView &view, StatsAxis *xAxis, StatsAxis *yAxis, const QString &categoryName, std::vector>> data, ChartSortMode sortMode) : StatsSeries(view, xAxis, yAxis), - item(view.createChartItem(ChartZValue::Series, pieBorderWidth)), + item(view.createChartItem(ChartZValue::Series, theme, pieBorderWidth)), categoryName(categoryName), radius(0), highlighted(-1), diff --git a/stats/scatterseries.cpp b/stats/scatterseries.cpp index 6858a8fa3..0cf097855 100644 --- a/stats/scatterseries.cpp +++ b/stats/scatterseries.cpp @@ -24,8 +24,8 @@ ScatterSeries::~ScatterSeries() { } -ScatterSeries::Item::Item(StatsView &view, ScatterSeries *series, dive *d, double pos, double value) : - item(view.createChartItem(ChartZValue::Series, d->selected)), +ScatterSeries::Item::Item(StatsView &view, ScatterSeries *series, const StatsTheme &theme, dive *d, double pos, double value) : + item(view.createChartItem(ChartZValue::Series, theme, d->selected)), d(d), selected(d->selected), pos(pos), @@ -50,7 +50,7 @@ void ScatterSeries::Item::highlight(bool highlight) void ScatterSeries::append(dive *d, double pos, double value) { - items.emplace_back(view, this, d, pos, value); + items.emplace_back(view, this, theme, d, pos, value); } void ScatterSeries::updatePositions() diff --git a/stats/scatterseries.h b/stats/scatterseries.h index eeb28415b..d4a43d224 100644 --- a/stats/scatterseries.h +++ b/stats/scatterseries.h @@ -41,7 +41,7 @@ private: dive *d; bool selected; double pos, value; - Item(StatsView &view, ScatterSeries *series, dive *d, double pos, double value); + Item(StatsView &view, ScatterSeries *series, const StatsTheme &theme, dive *d, double pos, double value); void updatePosition(ScatterSeries *series); void highlight(bool highlight); }; diff --git a/stats/statsview.cpp b/stats/statsview.cpp index 9eaa93768..130f3895a 100644 --- a/stats/statsview.cpp +++ b/stats/statsview.cpp @@ -183,7 +183,7 @@ QSGNode *StatsView::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNod } for (ChartItem *item = dirtyItems.first; item; item = item->next) { - item->render(*currentTheme); + item->render(); item->dirty = false; } dirtyItems.splice(cleanItems);