drawing reworked into c++ plugin, moved input handler to Interactions.qml as a PointHandler
This commit is contained in:
@@ -51,6 +51,7 @@ MouseArea {
|
||||
|
||||
anchors.fill: parent
|
||||
cursorShape: !enabled ? undefined : Qt.PointingHandCursor
|
||||
enabled: parent.enabled
|
||||
hoverEnabled: true
|
||||
|
||||
Behavior on stateOpacity {
|
||||
|
||||
+4
-31
@@ -1,36 +1,9 @@
|
||||
import QtQuick
|
||||
import ZShell.Internal
|
||||
|
||||
Canvas {
|
||||
StrokeCanvas {
|
||||
id: root
|
||||
|
||||
property color penColor: "white"
|
||||
property real penWidth: 4
|
||||
property var points: []
|
||||
|
||||
function clear(): void {
|
||||
var ctx = getContext('2d');
|
||||
root.points = [];
|
||||
ctx.reset();
|
||||
root.requestPaint();
|
||||
}
|
||||
|
||||
renderStrategy: Canvas.Cooperative
|
||||
|
||||
onPaint: {
|
||||
if (points.length < 2)
|
||||
return;
|
||||
var ctx = root.getContext('2d');
|
||||
ctx.save();
|
||||
ctx.lineWidth = root.penWidth;
|
||||
ctx.strokeStyle = root.penColor;
|
||||
ctx.lineJoin = "round";
|
||||
ctx.lineCap = "round";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(points[0].x, points[0].y);
|
||||
for (var i = 1; i < points.length; i++)
|
||||
ctx.lineTo(points[i].x, points[i].y);
|
||||
ctx.stroke();
|
||||
points = points.slice(points.length - 2);
|
||||
ctx.restore();
|
||||
}
|
||||
penColor: "white"
|
||||
penWidth: 4
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
|
||||
CustomMouseArea {
|
||||
id: root
|
||||
|
||||
required property var bar
|
||||
required property Drawing drawing
|
||||
required property Panels panels
|
||||
required property var popout
|
||||
required property PersistentProperties visibilities
|
||||
|
||||
function inLeftPanel(panel: Item, x: real, y: real): bool {
|
||||
return x < panel.x + panel.width + Config.barConfig.border && withinPanelHeight(panel, x, y);
|
||||
}
|
||||
|
||||
function withinPanelHeight(panel: Item, x: real, y: real): bool {
|
||||
const panelY = panel.y + bar.implicitHeight;
|
||||
return y >= panelY && y <= panelY + panel.height;
|
||||
}
|
||||
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
enabled: z > 0
|
||||
hoverEnabled: true
|
||||
visible: root.visibilities.isDrawing
|
||||
|
||||
onPositionChanged: event => {
|
||||
const x = event.x;
|
||||
const y = event.y;
|
||||
if (root.visibilities.isDrawing && (event.buttons & Qt.LeftButton)) {
|
||||
root.drawing.points.push(Qt.point(x, y));
|
||||
root.drawing.requestPaint();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.buttons & Qt.LeftButton) && root.inLeftPanel(root.popout, x, y)) {
|
||||
root.z = -2;
|
||||
root.panels.drawing.expanded = true;
|
||||
}
|
||||
}
|
||||
onPressed: event => {
|
||||
const x = event.x;
|
||||
const y = event.y;
|
||||
|
||||
if (root.visibilities.isDrawing && (event.buttons & Qt.LeftButton)) {
|
||||
root.panels.drawing.expanded = false;
|
||||
root.drawing.points.push(Qt.point(x, y));
|
||||
root.drawing.requestPaint();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.buttons & Qt.RightButton)
|
||||
root.drawing.clear();
|
||||
}
|
||||
onReleased: {
|
||||
root.drawing.points = [];
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ Item {
|
||||
required property real borderThickness
|
||||
property bool dashboardShortcutActive
|
||||
required property Drawing drawing
|
||||
required property DrawingInput input
|
||||
property bool osdShortcutActive
|
||||
required property Panels panels
|
||||
required property BarPopouts.Wrapper popouts
|
||||
@@ -60,6 +59,7 @@ Item {
|
||||
|
||||
cursorShape: (active && centroid.pressPosition.y < root.bar.implicitHeight) ? Qt.ClosedHandCursor : undefined
|
||||
dragThreshold: 0
|
||||
enabled: !root.visibilities.isDrawing
|
||||
grabPermissions: PointerHandler.CanTakeOverFromHandlersOfSameType | PointerHandler.ApprovesTakeOverByAnything
|
||||
maximumPointCount: 1
|
||||
minimumPointCount: 1
|
||||
@@ -117,6 +117,40 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
PointHandler {
|
||||
id: drawingHandler
|
||||
|
||||
property bool setInitialPoint: false
|
||||
|
||||
enabled: root.visibilities.isDrawing
|
||||
|
||||
onActiveChanged: {
|
||||
console.log(active);
|
||||
if (!active) {
|
||||
setInitialPoint = false;
|
||||
root.drawing.endStroke();
|
||||
} else {
|
||||
root.panels.drawing.expanded = false;
|
||||
}
|
||||
}
|
||||
onPointChanged: {
|
||||
const x = point.position.x;
|
||||
const y = point.position.y;
|
||||
const origX = point.pressPosition.x;
|
||||
const origY = point.pressPosition.y;
|
||||
if (x === 0 && y === 0 && origX === 0 && origY === 0)
|
||||
return;
|
||||
|
||||
if (!setInitialPoint) {
|
||||
setInitialPoint = true;
|
||||
root.drawing.beginStroke(origX, origY);
|
||||
return;
|
||||
}
|
||||
|
||||
root.drawing.appendPoint(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
|
||||
@@ -139,9 +173,10 @@ Item {
|
||||
const x = point.position.x;
|
||||
const y = point.position.y;
|
||||
|
||||
if (root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, x, y)) {
|
||||
root.input.z = 2;
|
||||
root.panels.drawing.expanded = false;
|
||||
if (root.visibilities.isDrawing) {
|
||||
if (root.inLeftPanel(root.panels.drawing, x, y))
|
||||
root.panels.drawing.expanded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!root.visibilities.bar && Config.barConfig.autoHide && y < root.bar.implicitHeight)
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ Item {
|
||||
readonly property alias dashboardWrapper: dashboardWrapper
|
||||
readonly property alias dock: dock
|
||||
readonly property alias drawing: drawing
|
||||
required property Canvas drawingItem
|
||||
required property var drawingItem
|
||||
readonly property alias launcher: launcher
|
||||
readonly property alias notifications: notifications
|
||||
readonly property alias osd: osd
|
||||
|
||||
+4
-19
@@ -195,6 +195,8 @@ CustomWindow {
|
||||
}
|
||||
|
||||
Item {
|
||||
id: surface
|
||||
|
||||
anchors.fill: parent
|
||||
layer.enabled: true
|
||||
opacity: root.surfaceColor.a
|
||||
@@ -364,30 +366,13 @@ CustomWindow {
|
||||
|
||||
active: visibilities.isDrawing
|
||||
anchors.fill: parent
|
||||
z: 2
|
||||
|
||||
sourceComponent: Drawing {
|
||||
id: drawing
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: inputLoader
|
||||
|
||||
active: visibilities.isDrawing
|
||||
anchors.fill: parent
|
||||
z: 2
|
||||
|
||||
sourceComponent: DrawingInput {
|
||||
id: input
|
||||
|
||||
bar: bar
|
||||
drawing: drawingLoader.item
|
||||
panels: panels
|
||||
popout: panels.drawing
|
||||
visibilities: visibilities
|
||||
}
|
||||
}
|
||||
|
||||
Interactions {
|
||||
id: interactions
|
||||
|
||||
@@ -396,7 +381,6 @@ CustomWindow {
|
||||
borderThickness: root.borderLayoutThickness
|
||||
drawing: drawingLoader.item
|
||||
enabled: true
|
||||
input: inputLoader.item
|
||||
panels: panels
|
||||
popouts: panels.popouts
|
||||
screen: root.screen
|
||||
@@ -451,6 +435,7 @@ CustomWindow {
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
enabled: !visibilities.isDrawing
|
||||
fullscreen: root.hasFullscreen
|
||||
popouts: panels.popouts
|
||||
popoutsWrapper: panels.popoutsWrapper
|
||||
|
||||
@@ -9,7 +9,7 @@ Item {
|
||||
id: root
|
||||
|
||||
readonly property var colors: ["#ef4444", "#f97316", "#eab308", "#22c55e", "#06b6d4", "#3b82f6", "#a855f7", "#ec4899", "#ffffff", "#000000"]
|
||||
required property Canvas drawing
|
||||
required property var drawing
|
||||
required property var visibilities
|
||||
|
||||
function syncFromPenColor() {
|
||||
|
||||
@@ -10,7 +10,7 @@ import qs.Daemons
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property Canvas drawing
|
||||
required property var drawing
|
||||
property bool expanded: true
|
||||
property real offsetScale: shouldBeActive ? 0 : 1
|
||||
required property ShellScreen screen
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user