diff --git a/Components/ColorArcPicker.qml b/Components/ColorArcPicker.qml index c909511..4ecf3c8 100644 --- a/Components/ColorArcPicker.qml +++ b/Components/ColorArcPicker.qml @@ -91,6 +91,14 @@ Item { implicitHeight: 180 implicitWidth: 220 + Behavior on currentHue { + enabled: !root.dragActive + + Anim { + type: Anim.StandardLarge + } + } + Component.onCompleted: syncFromPenColor() onCurrentHueChanged: canvas.requestPaint() onDrawingChanged: syncFromPenColor() diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 9415ace..862b5bb 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -123,7 +123,7 @@ Item { property bool setInitialPoint: false acceptedButtons: Qt.LeftButton | Qt.RightButton - enabled: root.visibilities.isDrawing + enabled: root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, hoverHandler.point.position.x, hoverHandler.point.position.y) grabPermissions: PointerHandler.CanTakeOverFromAnything | PointerHandler.TakeOverForbidden onActiveChanged: { @@ -135,15 +135,15 @@ Item { } } onPointChanged: { - if (point.pressedButtons & Qt.RightButton) { - root.drawing.clear(); - return; - } - const x = point.position.x; const y = point.position.y; const origX = point.pressPosition.x; const origY = point.pressPosition.y; + + if (point.pressedButtons & Qt.RightButton) { + root.drawing.clear(); + return; + } if (x === 0 && y === 0 && origX === 0 && origY === 0) return; diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index 4b28e86..30db34c 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -370,6 +370,33 @@ CustomWindow { sourceComponent: Drawing { id: drawing + + layer.enabled: true + + layer.effect: MultiEffect { + maskEnabled: true + maskInverted: true + maskSource: maskSource + } + } + } + + Item { + id: maskSource + + anchors.fill: parent + layer.enabled: true + visible: false + + CustomRect { + readonly property int extraWidth: radius + + color: "white" + implicitHeight: panels.drawing.height + implicitWidth: panels.drawing.width + extraWidth + radius: drawingBg.radius + x: -extraWidth + root.borderThickness + panels.drawing.x + y: panels.drawing.y + bar.implicitHeight } } diff --git a/Modules/Drawing/Content.qml b/Modules/Drawing/Content.qml index 71b9acd..ebc392d 100644 --- a/Modules/Drawing/Content.qml +++ b/Modules/Drawing/Content.qml @@ -2,13 +2,15 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts +import ZShell.Components import qs.Config import qs.Components Item { id: root - readonly property var colors: ["#ef4444", "#f97316", "#eab308", "#22c55e", "#06b6d4", "#3b82f6", "#a855f7", "#ec4899", "#ffffff", "#000000"] + readonly property var colors1: ["#ef4444", "#f97316", "#eab308", "#22c55e", "#06b6d4"] + readonly property var colors2: ["#3b82f6", "#a855f7", "#ec4899", "#ffffff", "#000000"] required property var drawing required property var visibilities @@ -58,13 +60,14 @@ Item { GradientSlider { id: saturationSlider + anchors.left: parent.left + anchors.right: parent.right brightness: brightnessSlider.value channel: "saturation" from: 0 hue: huePicker.currentHue icon: "\ue40a" implicitHeight: 30 - implicitWidth: palette.width orientation: Qt.Horizontal to: 1 @@ -74,12 +77,13 @@ Item { GradientSlider { id: brightnessSlider + anchors.left: parent.left + anchors.right: parent.right channel: "brightness" from: 0 hue: huePicker.currentHue icon: "\ue1ac" implicitHeight: 30 - implicitWidth: palette.width orientation: Qt.Horizontal saturation: saturationSlider.value to: 1 @@ -87,59 +91,38 @@ Item { onMoved: root.updatePenColorFromHsv() } - GridLayout { - id: palette - + ButtonRow { anchors.left: parent.left anchors.right: parent.right - columns: 5 - rowSpacing: 8 - rows: 2 + spacing: Appearance.spacing.normal Repeater { - model: root.colors + model: root.colors1 - delegate: Item { - id: colorCircle + delegate: ColorButton { + } + } + } - required property color modelData - readonly property bool selected: Qt.colorEqual(root.drawing.penColor, modelData) + ButtonRow { + anchors.left: parent.left + anchors.right: parent.right + spacing: Appearance.spacing.normal - Layout.fillWidth: true - height: 28 + Repeater { + model: root.colors2 - CustomRect { - anchors.centerIn: parent - border.color: Qt.rgba(0, 0, 0, 0.25) - border.width: Qt.colorEqual(modelData, "#ffffff") ? 1 : 0 - color: colorCircle.modelData - height: 20 - radius: width / 2 - width: 20 - } - - CustomRect { - anchors.centerIn: parent - border.color: selected ? "#ffffff" : Qt.rgba(1, 1, 1, 0.28) - border.width: selected ? 3 : 1 - color: "transparent" - height: parent.height - radius: width / 2 - width: parent.height - - StateLayer { - onClicked: root.drawing.penColor = colorCircle.modelData - } - } + delegate: ColorButton { } } } FilledSlider { + anchors.left: parent.left + anchors.right: parent.right from: 1 icon: "border_color" implicitHeight: 30 - implicitWidth: palette.width multiplier: 1 orientation: Qt.Horizontal to: 45 @@ -148,4 +131,21 @@ Item { onMoved: root.drawing.penWidth = value } } + + component ColorButton: IconButton { + id: colorButton + + required property color modelData + + fillWidth: false + icon: "" + inactiveColor: modelData + inactiveOnColor: DynamicColors.on(modelData) + isRound: true + padding: Appearance.padding.extraSmall + shapeMorph: true + shapeMorphExpansion: pressed ? 12 : 0 + + onClicked: root.drawing.penColor = modelData + } } diff --git a/Plugins/ZShell/Internal/strokecanvasitem.cpp b/Plugins/ZShell/Internal/strokecanvasitem.cpp index a8854a4..1993e9d 100644 --- a/Plugins/ZShell/Internal/strokecanvasitem.cpp +++ b/Plugins/ZShell/Internal/strokecanvasitem.cpp @@ -13,6 +13,20 @@ QCanvasPainterItemRenderer *StrokeCanvasItem::createItemRenderer() const { return new StrokeCanvasRenderer; } +static bool shouldAddPoint( + const QVector &points, + const QPointF &p, + qreal minDistance) +{ + if (points.isEmpty()) + return true; + + const QPointF delta = p - points.last(); + + return QPointF::dotProduct(delta, delta) + >= minDistance * minDistance; +} + void StrokeCanvasItem::setPenColor(const QColor &color) { if (m_penColor == color) return; @@ -44,7 +58,9 @@ void StrokeCanvasItem::beginStroke(qreal x, qreal y) { } void StrokeCanvasItem::appendPoint(qreal x, qreal y) { - m_currentStroke.points.append({x, y}); + if (shouldAddPoint(m_currentStroke.points, {x, y}, 2.0)) + m_currentStroke.points.append({x, y}); + update(); } diff --git a/Plugins/ZShell/Internal/strokecanvasrenderer.cpp b/Plugins/ZShell/Internal/strokecanvasrenderer.cpp index ae2e4a5..98c0880 100644 --- a/Plugins/ZShell/Internal/strokecanvasrenderer.cpp +++ b/Plugins/ZShell/Internal/strokecanvasrenderer.cpp @@ -28,8 +28,11 @@ static void drawStroke( painter->beginPath(); painter->moveTo(points[0]); - for (qsizetype i = 1; i < points.size(); ++i) - painter->lineTo(points[i]); + for (int i = 1; i < points.size() - 1; ++i) { + QPointF mid = (points[i] + points [i + 1]) / 2; + painter->quadraticCurveTo(points[i], mid); + } + painter->lineTo(points.last()); painter->stroke(); }