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 }