Warning, /graphics/washipad/src/Sketch.qml is written in an unsupported language. File is not indexed.
0001 // This file is part of Washi Pad
0002 // SPDX-FileCopyrightText: 2018 Kevin Ottens <ervin@kde.org>
0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004
0005 import QtQuick 2.0
0006 import QtQuick.Window 2.0
0007 import QtQuick.Controls 2.15
0008
0009
0010 import WashiPad 1.0
0011
0012 Item {
0013 id: root
0014 readonly property size size: Qt.size(sketchContent.width, sketchContent.height)
0015 readonly property point cursorPos: Qt.point(handler.point.x, handler.point.y)
0016
0017 property SketchModel model
0018 property color penColor: "black"
0019 readonly property var penType: (penColor === Qt.rgba(0, 0, 0, 1)) ? Stroke.Outline : Stroke.Fill
0020 property alias isMouseSupportEnabled: mouseArea.enabled
0021
0022 Flickable {
0023 id: flickable
0024
0025 anchors.fill: parent
0026
0027 clip: true
0028 topMargin: contentHeight * 0.1
0029 bottomMargin: topMargin
0030 rightMargin: contentWidth * 0.1
0031 leftMargin: rightMargin
0032
0033 interactive: !mouseArea.isPress
0034
0035 contentWidth: sketchContent.width
0036 contentHeight: sketchContent.height
0037
0038 PaintingCanvas {
0039 id: sketchContent
0040
0041 StrokeListItem {
0042 id: fillStrokes
0043 anchors.fill: parent
0044 z: 0
0045 type: Stroke.Fill
0046 model: root.model
0047 }
0048
0049 StrokeListItem {
0050 id: outlineStrokes
0051 anchors.fill: parent
0052 z: 1
0053 type: Stroke.Outline
0054 model: root.model
0055 }
0056
0057 StrokeItem {
0058 id: currentStroke
0059 anchors.fill: parent
0060 z: stroke.type === Stroke.Outline ? 1 : 0
0061 }
0062 }
0063
0064 ScrollBar.vertical: ScrollBar {anchors.right: flickable.right}
0065 ScrollBar.horizontal: ScrollBar {anchors.bottom: flickable.bottom}
0066
0067 MouseArea {
0068 id: mouseArea
0069
0070 property bool isPress: false
0071 property var lastButton
0072
0073 anchors.fill: parent
0074 acceptedButtons: Qt.LeftButton | Qt.RightButton
0075
0076 onPressed: {
0077 if (!isPress) {
0078 isPress = true
0079 lastButton = mouse.button
0080
0081 handler.pressed = isPress
0082 }
0083 }
0084
0085 onReleased: {
0086 if (mouse.button === lastButton) {
0087 isPress = false
0088
0089 handler.pressed = isPress
0090 }
0091 }
0092
0093 onPositionChanged: {
0094 handler.mouseMoved(mouse.x - flickable.contentX, mouse.y - flickable.contentY, lastButton)
0095 }
0096 }
0097 }
0098
0099 SketchViewHandler {
0100 id: handler
0101
0102 function isEraser() {
0103 return point.pointer === TabletEvent.Eraser
0104 }
0105
0106 function isEmpty(rect) {
0107 return rect.left === rect.right
0108 && rect.top === rect.bottom
0109 }
0110
0111 function createPoint() {
0112 return Qt.vector2d(point.x + flickable.contentX,
0113 point.y + flickable.contentY)
0114 }
0115
0116 function addSample() {
0117 var sample = createSample(createPoint(), pressureEquation.width)
0118 currentStroke.addSample(sample)
0119 }
0120
0121 function eraseSamples() {
0122 var point = createPoint()
0123 var radius = cursor.height / 2
0124
0125 outlineStrokes.eraseArea(point, radius)
0126 fillStrokes.eraseArea(point, radius)
0127 }
0128
0129 onPressedChanged: {
0130 if (isEraser())
0131 return
0132
0133 if (!pressed && !isEmpty(currentStroke.stroke.boundingRect())) {
0134 addSample()
0135 if (currentStroke.stroke.type === Stroke.Outline)
0136 outlineStrokes.addStroke(currentStroke.stroke)
0137 else
0138 fillStrokes.addStroke(currentStroke.stroke)
0139 currentStroke.stroke = createStroke(penType, root.penColor)
0140 return
0141 }
0142
0143 currentStroke.stroke = createStroke(penType, root.penColor)
0144 }
0145
0146 onPointChanged: {
0147 if (!pressed)
0148 return
0149
0150 if (!isEraser())
0151 addSample()
0152 else
0153 eraseSamples()
0154 }
0155 }
0156
0157 PressureEquation {
0158 id: pressureEquation
0159 readonly property real minOutlineWidth: 2
0160 readonly property real maxOutlineWidth: 10
0161
0162 readonly property real minFillWidth: minOutlineWidth * 2
0163 readonly property real maxFillWidth: maxOutlineWidth * 2
0164
0165 readonly property real minEraserWidth: minOutlineWidth * 4
0166 readonly property real maxEraserWidth: maxOutlineWidth * 8
0167
0168 pressure: handler.point.pressure
0169 minWidth: handler.isEraser() ? minEraserWidth
0170 : root.penType === Stroke.Fill ? minFillWidth
0171 : minOutlineWidth
0172 maxWidth: handler.isEraser() ? maxEraserWidth
0173 : root.penType === Stroke.Fill ? maxFillWidth
0174 : maxOutlineWidth
0175 }
0176
0177 Rectangle {
0178 id: cursor
0179
0180 color: "transparent"
0181 border.color: handler.isEraser() ? Qt.rgba(1, 0, 0, 0.75) : Qt.rgba(0, 0, 1, 0.75)
0182 border.width: 2
0183 x: handler.point.x - width / 2
0184 y: handler.point.y - height / 2
0185 width: height
0186 height: pressureEquation.width * 1.5
0187 radius: height / 2
0188 }
0189 }