drawing reworked into c++ plugin, moved input handler to Interactions.qml as a PointHandler
Lint & Format (JS/TS) / lint-format (pull_request) Successful in 11s
Python / lint-format (pull_request) Successful in 16s
Python / test (pull_request) Successful in 31s
Lint & Format (Rust) / lint-format (pull_request) Successful in 1m17s

This commit is contained in:
2026-06-18 13:48:58 +02:00
parent fbadcbb717
commit c102d0e38f
15 changed files with 281 additions and 118 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
find_package(Qt6 REQUIRED COMPONENTS ShaderTools Core Qml Gui Quick Concurrent Sql Network DBus)
find_package(Qt6 REQUIRED COMPONENTS ShaderTools Core Qml Gui Quick Concurrent Sql Network DBus CanvasPainter)
find_package(PkgConfig REQUIRED)
find_library(SENSORS_LIBRARY NAMES sensors REQUIRED)
find_path(SENSORS_INCLUDE_DIR NAMES sensors/sensors.h REQUIRED)
+3
View File
@@ -12,6 +12,8 @@ qml_module(ZShell-internal
lidwatcher.hpp lidwatcher.cpp
visualizerbars.hpp visualizerbars.cpp
linearindicatormanager.hpp linearindicatormanager.cpp
strokecanvasitem.hpp strokecanvasitem.cpp
strokecanvasrenderer.hpp strokecanvasrenderer.cpp
LIBRARIES
Qt::Gui
Qt::Quick
@@ -19,4 +21,5 @@ qml_module(ZShell-internal
Qt::Core
Qt::Network
Qt::DBus
Qt::CanvasPainter
)
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <QColor>
#include <QPointF>
#include <QVector>
namespace ZShell::internal {
struct Stroke {
QVector<QPointF> points;
QColor color;
float width;
};
};
@@ -0,0 +1,68 @@
#include "strokecanvasitem.hpp"
#include "strokecanvasrenderer.hpp"
#include <qnamespace.h>
namespace ZShell::internal {
StrokeCanvasItem::StrokeCanvasItem(QQuickItem *parent) : QCanvasPainterItem(parent) {
setFillColor(Qt::transparent);
setAlphaBlending(true);
}
QCanvasPainterItemRenderer *StrokeCanvasItem::createItemRenderer() const {
return new StrokeCanvasRenderer;
}
void StrokeCanvasItem::setPenColor(const QColor &color) {
if (m_penColor == color)
return;
m_penColor = color;
update();
emit penColorChanged();
}
void StrokeCanvasItem::setPenWidth(float width) {
if (qFuzzyCompare(m_penWidth, width))
return;
m_penWidth = width;
update();
emit penWidthChanged();
}
void StrokeCanvasItem::beginStroke(qreal x, qreal y) {
m_currentStroke.points.clear();
m_currentStroke.points.append({x, y});
m_currentStroke.color = m_penColor;
m_currentStroke.width = m_penWidth;
update();
}
void StrokeCanvasItem::appendPoint(qreal x, qreal y) {
m_currentStroke.points.append({x, y});
update();
}
void StrokeCanvasItem::endStroke() {
if (m_currentStroke.points.isEmpty())
return;
m_strokes.append(m_currentStroke);
m_currentStroke.points.clear();
update();
}
void StrokeCanvasItem::clear() {
m_strokes.clear();
m_currentStroke.points.clear();
update();
}
};
@@ -0,0 +1,59 @@
#pragma once
#include <QCanvasPainterItem>
#include <QColor>
#include <QPointF>
#include <QVector>
#include <qcolor.h>
#include <qcontainerfwd.h>
#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(qreal penWidth READ penWidth WRITE setPenWidth NOTIFY penWidthChanged)
public:
explicit StrokeCanvasItem(QQuickItem *parent = nullptr);
[[nodiscard]] QColor penColor() const {
return m_penColor;
}
[[nodiscard]] float penWidth() const {
return m_penWidth;
}
void setPenColor(const QColor &color);
void setPenWidth(float width);
Q_INVOKABLE void clear();
Q_INVOKABLE void beginStroke(qreal x, qreal y);
Q_INVOKABLE void appendPoint(qreal x, qreal y);
Q_INVOKABLE void endStroke();
signals:
void penColorChanged();
void penWidthChanged();
protected:
[[nodiscard]] QCanvasPainterItemRenderer *createItemRenderer() const override;
private:
friend class StrokeCanvasRenderer;
QColor m_penColor = Qt::white;
float m_penWidth = 4.f;
QVector<Stroke> m_strokes;
Stroke m_currentStroke;
};
};
@@ -0,0 +1,61 @@
#include "strokecanvasrenderer.hpp"
#include "strokecanvasitem.hpp"
namespace ZShell::internal {
static void drawStroke(
QCanvasPainter *painter,
const QVector<QPointF> &points,
const QColor &color,
float width) {
if (points.isEmpty())
return;
painter->setStrokeStyle(color);
painter->setFillStyle(color);
painter->setLineWidth(width);
painter->setLineCap(QCanvasPainter::LineCap::Round);
painter->setLineJoin(QCanvasPainter::LineJoin::Round);
if (points.size() == 1) {
painter->beginPath();
painter->circle(points.front(), width * 0.5f);
painter->fill();
return;
}
painter->beginPath();
painter->moveTo(points[0]);
for (qsizetype i = 1; i < points.size(); ++i)
painter->lineTo(points[i]);
painter->stroke();
}
void StrokeCanvasRenderer::synchronizeData(QCanvasPainterItem *item) {
auto *canvas = static_cast<StrokeCanvasItem *>(item);
m_penColor = canvas->m_penColor;
m_penWidth = canvas->m_penWidth;
m_strokes = canvas->m_strokes;
m_currentStroke = canvas->m_currentStroke;
}
void StrokeCanvasRenderer::paint(QCanvasPainter *painter) {
painter->clearRect(0, 0, width(), height());
for (const auto &stroke : m_strokes)
drawStroke(painter, stroke.points, stroke.color, stroke.width);
drawStroke(
painter,
m_currentStroke.points,
m_currentStroke.color,
m_currentStroke.width
);
}
};
@@ -0,0 +1,23 @@
#pragma once
#include <QCanvasPainterItemRenderer>
#include "stroke.hpp"
namespace ZShell::internal {
class StrokeCanvasRenderer final : public QCanvasPainterItemRenderer {
public:
void synchronizeData(QCanvasPainterItem *item) override;
void paint(QCanvasPainter *painter) override;
private:
QColor m_penColor;
float m_penWidth = 4.f;
QVector<Stroke> m_strokes;
Stroke m_currentStroke;
};
};