229 lines
7.1 KiB
QML
229 lines
7.1 KiB
QML
// Copyright (C) 2021 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import QtQuick.Shapes
|
|
|
|
pragma ComponentBehavior: Bound
|
|
|
|
Rectangle {
|
|
id: root
|
|
width: 1024
|
|
height: 768
|
|
color: palette.window
|
|
|
|
RowLayout {
|
|
id: topRow
|
|
x: 20
|
|
y: 10
|
|
spacing: 20
|
|
|
|
ButtonGroup {
|
|
id: toolButtons
|
|
buttons: drawingTools.children
|
|
}
|
|
|
|
RowLayout {
|
|
id: drawingTools
|
|
ToolButton {
|
|
text: qsTr("Line")
|
|
checkable: true
|
|
checked: true
|
|
|
|
property Component shapeType: Component {
|
|
ShapePath {
|
|
id: lineShapePath
|
|
strokeColor: root.palette.windowText
|
|
strokeWidth: widthSlider.value
|
|
fillColor: "transparent"
|
|
PathLine {
|
|
id: pathSegment
|
|
x: lineShapePath.startX + 1
|
|
y: lineShapePath.startY + 1
|
|
}
|
|
function finishCreation() {
|
|
createStartEndHandles(this, pathSegment);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ToolButton {
|
|
text: qsTr("Quadratic")
|
|
checkable: true
|
|
|
|
property Component shapeType: Component {
|
|
ShapePath {
|
|
id: quadShapePath
|
|
strokeColor: root.palette.windowText
|
|
strokeWidth: widthSlider.value
|
|
fillColor: fillSwitch.checked ? "green" : "transparent"
|
|
PathQuad {
|
|
id: pathSegment
|
|
x: quadShapePath.startX + 1
|
|
y: quadShapePath.startY + 1
|
|
controlX: quadShapePath.startX + 50
|
|
controlY: quadShapePath.startY + 50
|
|
}
|
|
function finishCreation() {
|
|
createStartEndHandles(this, pathSegment);
|
|
pointDragHandle.createObject(canvas, {
|
|
idleColor: "blue",
|
|
target: pathSegment, xprop: "controlX", yprop: "controlY"
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ToolButton {
|
|
text: qsTr("Cubic")
|
|
checkable: true
|
|
|
|
property Component shapeType: Component {
|
|
ShapePath {
|
|
id: cubicShapePath
|
|
strokeColor: root.palette.windowText
|
|
strokeWidth: widthSlider.value
|
|
fillColor: fillSwitch.checked ? "green" : "transparent"
|
|
PathCubic {
|
|
id: pathSegment
|
|
x: cubicShapePath.startX + 1
|
|
y: cubicShapePath.startY + 1
|
|
control1X: cubicShapePath.startX + 50;
|
|
control1Y: cubicShapePath.startY + 50;
|
|
control2X: cubicShapePath.startX + 150;
|
|
control2Y: cubicShapePath.startY + 50;
|
|
}
|
|
function finishCreation() {
|
|
createStartEndHandles(this, pathSegment);
|
|
pointDragHandle.createObject(canvas, {
|
|
idleColor: "blue",
|
|
target: pathSegment, xprop: "control1X", yprop: "control1Y"
|
|
});
|
|
pointDragHandle.createObject(canvas, {
|
|
idleColor: "lightBlue",
|
|
target: pathSegment, xprop: "control2X", yprop: "control2Y"
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
text: qsTr("Width")
|
|
}
|
|
Slider {
|
|
id: widthSlider
|
|
from: 1
|
|
to: 60
|
|
value: 4
|
|
}
|
|
|
|
Switch {
|
|
id: showHandlesSwitch
|
|
text: qsTr("Handles")
|
|
}
|
|
|
|
Switch {
|
|
id: fillSwitch
|
|
text: qsTr("Fill")
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: pointDragHandle
|
|
|
|
Rectangle {
|
|
id: rect
|
|
property variant target
|
|
property string xprop
|
|
property string yprop
|
|
property color idleColor: "red"
|
|
|
|
width: 20
|
|
height: width
|
|
visible: showHandlesSwitch.checked
|
|
color: hh.hovered ? "yellow" : idleColor
|
|
border.color: "grey"
|
|
|
|
property real halfWidth: width / 2
|
|
property bool complete: false
|
|
Binding {
|
|
target: rect.target
|
|
property: rect.xprop
|
|
value: rect.x + rect.halfWidth
|
|
when: rect.complete
|
|
}
|
|
Binding {
|
|
target: rect.target
|
|
property: rect.yprop
|
|
value: rect.y + rect.halfWidth
|
|
when: rect.complete
|
|
}
|
|
|
|
DragHandler { }
|
|
|
|
HoverHandler {
|
|
id: hh
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
x = target[xprop] - halfWidth;
|
|
y = target[yprop] - halfWidth;
|
|
complete = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function createStartEndHandles(shapePath, pathSegment) {
|
|
pointDragHandle.createObject(canvas, {
|
|
idleColor: "red",
|
|
target: shapePath, xprop: "startX", yprop: "startY"
|
|
});
|
|
pointDragHandle.createObject(canvas, {
|
|
idleColor: "red",
|
|
target: pathSegment, xprop: "x", yprop: "y"
|
|
});
|
|
}
|
|
|
|
Rectangle {
|
|
id: canvas
|
|
color: palette.base
|
|
width: root.width - 40
|
|
height: root.height - y - 20
|
|
x: 20
|
|
anchors.top: topRow.bottom
|
|
anchors.topMargin: 20
|
|
|
|
DragHandler {
|
|
target: null
|
|
grabPermissions: DragHandler.TakeOverForbidden
|
|
property ShapePath activePath: null
|
|
onActiveChanged: {
|
|
const tool = toolButtons.checkedButton;
|
|
if (active) {
|
|
activePath = tool.shapeType.createObject(root, {
|
|
startX: centroid.position.x, startY: centroid.position.y
|
|
});
|
|
shape.data.push(activePath);
|
|
} else {
|
|
activePath.finishCreation();
|
|
activePath = null;
|
|
}
|
|
}
|
|
onCentroidChanged: if (activePath) {
|
|
var pathObj = activePath.pathElements[0];
|
|
pathObj.x = centroid.position.x;
|
|
pathObj.y = centroid.position.y;
|
|
}
|
|
}
|
|
|
|
Shape {
|
|
id: shape
|
|
anchors.fill: parent
|
|
}
|
|
}
|
|
}
|