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 <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2023-04-16 12:19:56 +02:00
parent 7aefd704c2
commit 4c43764b36
8 changed files with 46 additions and 40 deletions

View file

@ -266,7 +266,7 @@ std::vector<BarSeries::SubItem> BarSeries::makeSubItems(std::vector<SubItemDesc>
for (auto &[v, dives, label]: items) {
if (v > 0.0) {
bool selected = allDivesSelected(dives);
res.push_back({ view.createChartItem<ChartBarItem>(ChartZValue::Series, barBorderWidth),
res.push_back({ view.createChartItem<ChartBarItem>(ChartZValue::Series, theme, barBorderWidth),
std::move(dives),
{}, from, from + v, bin_nr, selected });
if (!label.empty())

View file

@ -32,7 +32,7 @@ BoxSeries::Item::Item(StatsView &view, BoxSeries *series, double lowerBound, dou
binName(binName),
selected(allDivesSelected(q.dives))
{
item = view.createChartItem<ChartBoxItem>(ChartZValue::Series, boxBorderWidth);
item = view.createChartItem<ChartBoxItem>(ChartZValue::Series, theme, boxBorderWidth);
highlight(false, theme);
updatePosition(series);
}

View file

@ -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<float>(t.x()), static_cast<float>(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);

View file

@ -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<QSGRectangleNode> {
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<QSGGeometryNode> selectionNode;
std::unique_ptr<QSGTextureMaterial> selectionMaterial;
std::unique_ptr<QSGGeometry> 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<QSGGeometryNode> whiskersNode;
@ -194,7 +196,7 @@ private:
// scatter item here, but so it is for now.
class ChartScatterItem : public HideableChartProxyItem<QSGImageNode> {
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;

View file

@ -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<std::pair<QString, std::vector<dive *>>> data, ChartSortMode sortMode) :
StatsSeries(view, xAxis, yAxis),
item(view.createChartItem<ChartPieItem>(ChartZValue::Series, pieBorderWidth)),
item(view.createChartItem<ChartPieItem>(ChartZValue::Series, theme, pieBorderWidth)),
categoryName(categoryName),
radius(0),
highlighted(-1),

View file

@ -24,8 +24,8 @@ ScatterSeries::~ScatterSeries()
{
}
ScatterSeries::Item::Item(StatsView &view, ScatterSeries *series, dive *d, double pos, double value) :
item(view.createChartItem<ChartScatterItem>(ChartZValue::Series, d->selected)),
ScatterSeries::Item::Item(StatsView &view, ScatterSeries *series, const StatsTheme &theme, dive *d, double pos, double value) :
item(view.createChartItem<ChartScatterItem>(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()

View file

@ -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);
};

View file

@ -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);