diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index b9d79ec..6051d5a 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -123,7 +123,6 @@ Item { property bool setInitialPoint: false acceptedButtons: Qt.LeftButton | Qt.RightButton - cursorShape: Qt.BlankCursor enabled: root.visibilities.isDrawing && (!root.inLeftPanel(root.panels.drawing, hoverHandler.point.position.x, hoverHandler.point.position.y) || !root.panels.drawing.expanded) onActiveChanged: { @@ -162,7 +161,7 @@ Item { HoverHandler { id: hoverHandler - cursorShape: root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, point.position.x, point.position.y) ? Qt.CrossCursor : undefined + cursorShape: root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, point.position.x, point.position.y) ? Qt.BlankCursor : undefined onHoveredChanged: { if (!hovered) { diff --git a/Plugins/ZShell/Internal/stroke.hpp b/Plugins/ZShell/Internal/stroke.hpp index 132e3cf..8f9bd1d 100644 --- a/Plugins/ZShell/Internal/stroke.hpp +++ b/Plugins/ZShell/Internal/stroke.hpp @@ -13,6 +13,7 @@ struct Stroke { QColor color; float width; int groupId = -1; + bool isSinglePoint = false; }; }; diff --git a/Plugins/ZShell/Internal/strokecanvasitem.cpp b/Plugins/ZShell/Internal/strokecanvasitem.cpp index 6036bd9..41295c8 100644 --- a/Plugins/ZShell/Internal/strokecanvasitem.cpp +++ b/Plugins/ZShell/Internal/strokecanvasitem.cpp @@ -2,6 +2,7 @@ #include "strokecanvasrenderer.hpp" #include #include +#include namespace ZShell::internal { @@ -28,12 +29,11 @@ static bool shouldAddPoint( >= minDistance * minDistance; } -static QCanvasPath buildStrokePath(const QVector &points) { +static QCanvasPath buildStrokePath(const QVector &points, float width) { QCanvasPath path; if (points.size() == 1) { - // Single point — store as a tiny circle so the group can still be cached - path.circle(points[0], 0); // radius 0; actual width applied at draw time + path.circle(points[0], width * 0.5f); return path; } @@ -95,12 +95,18 @@ void StrokeCanvasItem::setHoverPoint(const QPointF &point) { } void StrokeCanvasItem::showHover(qreal x, qreal y) { - m_hoverPoint = {x, y}; - m_hoverVisible = true; - update(); + const QPointF newPoint{x, y}; + const bool pointChanged = (m_hoverPoint != newPoint); + const bool visibleChanged = !m_hoverVisible; - emit hoverPointChanged(); - emit hoverVisibleChanged(); + + if (pointChanged || visibleChanged) { + m_hoverVisible = true; + m_hoverPoint = newPoint; + if (pointChanged) emit hoverPointChanged(); + if (visibleChanged) emit hoverVisibleChanged(); + update(); + } } void StrokeCanvasItem::hideHover() { @@ -124,6 +130,7 @@ void StrokeCanvasItem::setPenWidth(float width) { } void StrokeCanvasItem::beginStroke(qreal x, qreal y) { + m_isDrawing = true; m_currentStroke.points.clear(); m_currentStroke.points.append({x, y}); @@ -163,13 +170,14 @@ void StrokeCanvasItem::appendPoint(qreal x, qreal y) { } void StrokeCanvasItem::endStroke() { + m_isDrawing = false; if (m_currentStroke.points.isEmpty()) return; - m_currentStroke.path = buildStrokePath(m_currentStroke.points); + m_currentStroke.isSinglePoint = (m_currentStroke.points.size() == 1); + m_currentStroke.path = buildStrokePath(m_currentStroke.points, m_currentStroke.width); m_currentStroke.groupId = m_nextGroupId++; m_currentStroke.points.clear(); - m_strokes.append(m_currentStroke); m_currentStroke = {}; diff --git a/Plugins/ZShell/Internal/strokecanvasitem.hpp b/Plugins/ZShell/Internal/strokecanvasitem.hpp index ed70f62..cf40da7 100644 --- a/Plugins/ZShell/Internal/strokecanvasitem.hpp +++ b/Plugins/ZShell/Internal/strokecanvasitem.hpp @@ -70,6 +70,7 @@ bool m_hoverVisible = false; QPointF m_hoverPoint; QColor m_penColor = Qt::white; float m_penWidth = 4.f; +bool m_isDrawing = false; int m_nextGroupId = 0; QVector m_strokes; diff --git a/Plugins/ZShell/Internal/strokecanvasrenderer.cpp b/Plugins/ZShell/Internal/strokecanvasrenderer.cpp index 4edfa7d..a648f9a 100644 --- a/Plugins/ZShell/Internal/strokecanvasrenderer.cpp +++ b/Plugins/ZShell/Internal/strokecanvasrenderer.cpp @@ -1,5 +1,6 @@ #include "strokecanvasrenderer.hpp" #include "strokecanvasitem.hpp" +#include namespace ZShell::internal { @@ -54,17 +55,79 @@ static void drawStroke( painter->stroke(); } -static void drawDot( +static void drawHoverCursor( QCanvasPainter *painter, const QPointF &point, - const QColor &color, - float width) + float penWidth, + QColor penColor, + bool isDrawing) { - painter->setFillStyle(color); + const float radius = penWidth * 0.5f; - painter->beginPath(); - painter->circle(point, width * 0.5f); - painter->fill(); + if (isDrawing) { + painter->setFillStyle(penColor); + painter->beginPath(); + painter->circle(point, radius); + painter->fill(); + } + + const float lineWidth = 1.5f; + const float crosshairSize = 6.0f; + const bool useDashes = penWidth > 10.0f; + + auto drawOutline = [&](const QColor &color, float width) { + painter->setStrokeStyle(color); + painter->setLineWidth(width); + painter->setLineCap(QCanvasPainter::LineCap::Round); + + + if (useDashes) { + const int dashCount = 12; + const float fullAngle = 2.0f * M_PI; + const float dashAngle = fullAngle / dashCount * 0.5f; + const float gapAngle = fullAngle / dashCount * 0.5f; + + float angle = 0.0f; + for (int i = 0; i < dashCount; ++i) { + painter->beginPath(); + painter->arc(point, radius, angle, angle + dashAngle, + QCanvasPainter::PathWinding::ClockWise, + QCanvasPainter::PathConnection::NotConnected); + painter->stroke(); + angle += dashAngle + gapAngle; + } + } else { + painter->beginPath(); + painter->circle(point, radius); + painter->stroke(); + } + }; + + auto drawCrosshair = [&](const QColor &color, float width) { + painter->setStrokeStyle(color); + painter->setLineWidth(width); + painter->setLineCap(QCanvasPainter::LineCap::Round); + + const float inner = radius + 3.0f; + const float outer = radius + 3.0f + crosshairSize; + + painter->beginPath(); + painter->moveTo(point + QPointF(0, -outer)); + painter->lineTo(point + QPointF(0, -inner)); + painter->moveTo(point + QPointF(0, outer)); + painter->lineTo(point + QPointF(0, inner)); + painter->moveTo(point + QPointF(-outer, 0)); + painter->lineTo(point + QPointF(-inner, 0)); + painter->moveTo(point + QPointF( outer, 0)); + painter->lineTo(point + QPointF( inner, 0)); + painter->stroke(); + }; + + drawOutline(QColor(0, 0, 0, 160), lineWidth + 1.0f); + drawCrosshair(QColor(0, 0, 0, 160), lineWidth + 1.0f); + + drawOutline(QColor(255, 255, 255, 220), lineWidth); + drawCrosshair(QColor(255, 255, 255, 220), lineWidth); } void StrokeCanvasRenderer::synchronizeData(QCanvasPainterItem *item) { @@ -73,11 +136,9 @@ void StrokeCanvasRenderer::synchronizeData(QCanvasPainterItem *item) { m_penColor = canvas->m_penColor; m_penWidth = canvas->m_penWidth; - // Only copy strokes the renderer hasn't seen yet while (m_strokes.size() < canvas->m_strokes.size()) m_strokes.append(canvas->m_strokes[m_strokes.size()]); - // Handle clear() if (canvas->m_strokes.isEmpty() && !m_strokes.isEmpty()) { for (const auto &stroke : m_strokes) if (stroke.groupId >= 0) @@ -89,6 +150,7 @@ void StrokeCanvasRenderer::synchronizeData(QCanvasPainterItem *item) { m_hoverVisible = canvas->m_hoverVisible; m_hoverPoint = canvas->m_hoverPoint; + m_isDrawing = canvas->m_isDrawing; } void StrokeCanvasRenderer::paint(QCanvasPainter *painter) { @@ -105,7 +167,7 @@ void StrokeCanvasRenderer::paint(QCanvasPainter *painter) { painter->setLineCap(QCanvasPainter::LineCap::Round); painter->setLineJoin(QCanvasPainter::LineJoin::Round); - if (stroke.path.commandsSize() == 1) { + if (stroke.isSinglePoint) { painter->fill(stroke.path, stroke.groupId); } else { painter->stroke(stroke.path, stroke.groupId); @@ -115,7 +177,7 @@ void StrokeCanvasRenderer::paint(QCanvasPainter *painter) { drawStroke(painter, m_currentStroke.points, m_currentStroke.color, m_currentStroke.width); if (m_hoverVisible) - drawDot(painter, m_hoverPoint, m_penColor, m_penWidth); + drawHoverCursor(painter, m_hoverPoint, m_penWidth, m_penColor, m_isDrawing); } }; diff --git a/Plugins/ZShell/Internal/strokecanvasrenderer.hpp b/Plugins/ZShell/Internal/strokecanvasrenderer.hpp index 83c74b9..74ff1f6 100644 --- a/Plugins/ZShell/Internal/strokecanvasrenderer.hpp +++ b/Plugins/ZShell/Internal/strokecanvasrenderer.hpp @@ -17,6 +17,7 @@ QColor m_penColor; float m_penWidth = 4.f; bool m_hoverVisible = false; QPointF m_hoverPoint; +bool m_isDrawing = false; QVector m_strokes; Stroke m_currentStroke;