// SPDX-License-Identifier: GPL-2.0 // Wrappers around QSGImageNode that allow painting onto an image // and then turning that into a texture to be displayed in a QQuickItem. #ifndef CHART_ITEM_H #define CHART_ITEM_H #include "chartitem_ptr.h" #include "chartitemhelper.h" #include #include class ChartView; class QSGGeometry; class QSGGeometryNode; class QSGFlatColorMaterial; class QSGImageNode; class QSGRectangleNode; class QSGTexture; class QSGTextureMaterial; class ChartItem { public: // Only call on render thread! virtual void render() = 0; bool dirty; // If true, call render() when rebuilding the scene ChartItem *prev, *next; // Double linked list of items const size_t zValue; virtual ~ChartItem(); // Attention: must only be called by render thread. protected: ChartItem(ChartView &v, size_t z); QSizeF sceneSize() const; ChartView &view; void markDirty(); }; template class HideableChartItem : public ChartItem { protected: HideableChartItem(ChartView &v, size_t z); std::unique_ptr node; bool visible; bool visibleChanged; template void createNode(Args&&... args); // Call to create node with visibility flag. void updateVisible(); // Must be called by child class to update visibility flag! public: void setVisible(bool visible); }; // A shortcut for ChartItems based on a hideable proxy item template using HideableChartProxyItem = HideableChartItem>>; // A chart item that blits a precalculated pixmap onto the scene. class ChartPixmapItem : public HideableChartProxyItem { public: ChartPixmapItem(ChartView &v, size_t z); ~ChartPixmapItem(); void setPos(QPointF pos); void render() override; QRectF getRect() const; protected: void resize(QSizeF size); // Resets the canvas. Attention: image is *unitialized*. std::unique_ptr painter; std::unique_ptr img; void setTextureDirty(); void setPositionDirty(); QRectF rect; private: bool positionDirty; // true if the position changed since last render bool textureDirty; // true if the pixmap changed since last render std::unique_ptr texture; }; // Draw a rectangular background after resize. Children are responsible for calling update(). class ChartRectItem : public ChartPixmapItem { public: ChartRectItem(ChartView &v, size_t z, const QPen &pen, const QBrush &brush, double radius); ~ChartRectItem(); void resize(QSizeF size); private: QPen pen; QBrush brush; double radius; }; // Attention: text is only drawn after calling setColor()! class ChartTextItem : public ChartPixmapItem { public: ChartTextItem(ChartView &v, size_t z, const QFont &f, const std::vector &text, bool center); ChartTextItem(ChartView &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: const QFont &f; double fontHeight; bool center; struct Item { QString s; double width; }; std::vector items; }; // Common data for line and rect items. Both are represented by two points. class ChartLineItemBase : public HideableChartItem> { public: ChartLineItemBase(ChartView &v, size_t z, QColor color, double width); ~ChartLineItemBase(); void setLine(QPointF from, QPointF to); protected: QPointF from, to; QColor color; double width; bool positionDirty; bool materialDirty; std::unique_ptr material; std::unique_ptr geometry; }; class ChartLineItem : public ChartLineItemBase { public: using ChartLineItemBase::ChartLineItemBase; void render() override; }; // A simple rectangle without fill. Specified by any two opposing vertices. class ChartRectLineItem : public ChartLineItemBase { public: using ChartLineItemBase::ChartLineItemBase; void render() override; }; // Implementation detail of templates - move to serparate header file template void HideableChartItem::setVisible(bool visibleIn) { if (visible == visibleIn) return; visible = visibleIn; visibleChanged = true; markDirty(); } template template void HideableChartItem::createNode(Args&&... args) { node.reset(new Node(visible, std::forward(args)...)); visibleChanged = false; } template HideableChartItem::HideableChartItem(ChartView &v, size_t z) : ChartItem(v, z), visible(true), visibleChanged(false) { } template void HideableChartItem::updateVisible() { if (visibleChanged) node->setVisible(visible); visibleChanged = false; } #endif