#pragma once #include #include #include #include #include #include #include #include "internal/circularbuffer.hpp" class QSGGeometryNode; class QSGTransformNode; namespace ZShell::components { class SparklineSceneItem : public QQuickItem { Q_OBJECT QML_ELEMENT Q_PROPERTY( internal::CircularBuffer* line1 READ line1 WRITE setLine1 NOTIFY line1Changed) Q_PROPERTY( internal::CircularBuffer* line2 READ line2 WRITE setLine2 NOTIFY line2Changed) Q_PROPERTY( QColor line1Color READ line1Color WRITE setLine1Color NOTIFY line1ColorChanged) Q_PROPERTY( QColor line2Color READ line2Color WRITE setLine2Color NOTIFY line2ColorChanged) Q_PROPERTY( qreal line1FillAlpha READ line1FillAlpha WRITE setLine1FillAlpha NOTIFY line1FillAlphaChanged) Q_PROPERTY( qreal line2FillAlpha READ line2FillAlpha WRITE setLine2FillAlpha NOTIFY line2FillAlphaChanged) Q_PROPERTY( qreal maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged) Q_PROPERTY( qreal slideProgress READ slideProgress WRITE setSlideProgress NOTIFY slideProgressChanged) Q_PROPERTY( int historyLength READ historyLength WRITE setHistoryLength NOTIFY historyLengthChanged) Q_PROPERTY( qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged) Q_PROPERTY(bool sliding READ sliding WRITE setSliding NOTIFY slidingChanged) Q_PROPERTY( qreal smoothing READ smoothing WRITE setSmoothing NOTIFY smoothingChanged) Q_PROPERTY( bool curveSmoothing READ curveSmoothing WRITE setCurveSmoothing NOTIFY curveSmoothingChanged) public: explicit SparklineSceneItem(QQuickItem* parent = nullptr); [[nodiscard]] internal::CircularBuffer* line1() const; void setLine1(internal::CircularBuffer* buffer); [[nodiscard]] internal::CircularBuffer* line2() const; void setLine2(internal::CircularBuffer* buffer); [[nodiscard]] QColor line1Color() const; void setLine1Color(const QColor& color); [[nodiscard]] QColor line2Color() const; void setLine2Color(const QColor& color); [[nodiscard]] qreal line1FillAlpha() const; void setLine1FillAlpha(qreal alpha); [[nodiscard]] qreal line2FillAlpha() const; void setLine2FillAlpha(qreal alpha); [[nodiscard]] qreal maxValue() const; void setMaxValue(qreal value); [[nodiscard]] qreal slideProgress() const; void setSlideProgress(qreal progress); [[nodiscard]] int historyLength() const; void setHistoryLength(int length); [[nodiscard]] qreal lineWidth() const; void setLineWidth(qreal width); [[nodiscard]] bool sliding() const; void setSliding(bool sliding); [[nodiscard]] qreal smoothing() const; void setSmoothing(qreal smoothing); [[nodiscard]] bool curveSmoothing() const; void setCurveSmoothing(bool curveSmoothing); signals: void line1Changed(); void line2Changed(); void line1ColorChanged(); void line2ColorChanged(); void line1FillAlphaChanged(); void line2FillAlphaChanged(); void maxValueChanged(); void slideProgressChanged(); void historyLengthChanged(); void lineWidthChanged(); void slidingChanged(); void smoothingChanged(); void curveSmoothingChanged(); protected: QSGNode* updatePaintNode(QSGNode* node, UpdatePaintNodeData* data) override; void geometryChange( const QRectF& newGeometry, const QRectF& oldGeometry) override; private: struct LineSample { QVector polyline; // local coords, slideProgress baked to 0 qreal fillBottom = 0.0; bool hasData = false; }; void connectBuffer(internal::CircularBuffer* buffer); void invalidateGeometry(); void applySmoothingRadius(internal::CircularBuffer* buffer) const; [[nodiscard]] qreal stepX() const; [[nodiscard]] LineSample buildSample(internal::CircularBuffer* buffer) const; static void writeFillGeometry( QSGGeometryNode* node, const LineSample& sample); static void writeStrokeGeometry( QSGGeometryNode* node, const LineSample& sample, qreal lineWidth); static void setMaterialColor( QSGGeometryNode* node, const QColor& color, qreal alpha); internal::CircularBuffer* m_line1 = nullptr; internal::CircularBuffer* m_line2 = nullptr; QColor m_line1Color; QColor m_line2Color; qreal m_line1FillAlpha = 0.15; qreal m_line2FillAlpha = 0.2; qreal m_maxValue = 1024.0; qreal m_slideProgress = 0.0; int m_historyLength = 30; qreal m_lineWidth = 2.0; bool m_sliding = true; qreal m_smoothing = 0.0; bool m_curveSmoothing = false; LineSample m_sample1; LineSample m_sample2; bool m_geometryDirty = true; bool m_colorsDirty = true; QSGTransformNode* m_transformNode = nullptr; QSGGeometryNode* m_line1FillNode = nullptr; QSGGeometryNode* m_line1StrokeNode = nullptr; QSGGeometryNode* m_line2FillNode = nullptr; QSGGeometryNode* m_line2StrokeNode = nullptr; }; } // namespace ZShell::components