#pragma once #include #include #include #include #include #include #include "stroke.hpp" namespace ZShell::internal { class StrokeCanvasRenderer; class StrokeCanvasItem : public QCanvasPainterItem { Q_OBJECT QML_NAMED_ELEMENT(StrokeCanvas) Q_PROPERTY( QColor penColor READ penColor WRITE setPenColor NOTIFY penColorChanged) Q_PROPERTY( bool hoverVisible READ hoverVisible WRITE setHoverVisible NOTIFY hoverVisibleChanged) Q_PROPERTY( QPointF hoverPoint READ hoverPoint WRITE setHoverPoint NOTIFY hoverPointChanged) Q_PROPERTY( qreal penWidth READ penWidth WRITE setPenWidth NOTIFY penWidthChanged) public: explicit StrokeCanvasItem(QQuickItem* parent = nullptr); [[nodiscard]] bool hoverVisible() const { return m_hoverVisible; } [[nodiscard]] QPointF hoverPoint() const { return m_hoverPoint; } void setHoverVisible(bool visible); void setHoverPoint(const QPointF& point); Q_INVOKABLE void showHover(qreal x, qreal y); Q_INVOKABLE void hideHover(); Q_INVOKABLE void undoLastGroup(); [[nodiscard]] QColor penColor() const { return m_penColor; } [[nodiscard]] qreal penWidth() const { return m_penWidth; } void setPenColor(const QColor& color); void setPenWidth(qreal width); Q_INVOKABLE void clear(); Q_INVOKABLE void beginStroke(qreal x, qreal y, bool polyline = false); Q_INVOKABLE void appendPoint(qreal x, qreal y); Q_INVOKABLE void endStroke(); signals: void penColorChanged(); void penWidthChanged(); void hoverVisibleChanged(); void hoverPointChanged(); protected: [[nodiscard]] QCanvasPainterItemRenderer* createItemRenderer() const override; private: friend class StrokeCanvasRenderer; bool m_hoverVisible = false; QPointF m_hoverPoint; QColor m_penColor = Qt::white; qreal m_penWidth = 4.0; bool m_isDrawing = false; int m_nextGroupId = 0; QVector m_strokes; Stroke m_currentStroke; }; }; // namespace ZShell::internal