From 19a74ba56e58e007449486b0f545be7415a9f95b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 29 Jan 2020 12:14:20 +0100 Subject: Fix vertical position of PathText The PathText would always translate to y=0, regardless of what y was set to. We should obviously get the y coordinate of the shape *before* translating it into position to find the distance from the baseline. This change also updates the example, which had not been updated to the changed origin of the PathText, and it adds a Lancelot test for keeping track of the PathText shape rendering. Change-Id: I940ac956af5229842739f8d8751a1f13bb86b8e7 Reviewed-by: Eirik Aavitsland --- .../scenegraph_lancelot/data/shape/shape_text.qml | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/manual/scenegraph_lancelot/data/shape/shape_text.qml (limited to 'tests/manual') diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_text.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_text.qml new file mode 100644 index 0000000000..37367054b5 --- /dev/null +++ b/tests/manual/scenegraph_lancelot/data/shape/shape_text.qml @@ -0,0 +1,91 @@ +import QtQuick 2.15 +import QtQuick.Shapes 1.0 + +Item { + width: 320 + height: 480 + + Column { + Item { + width: 200 + height: 160 + + Shape { + anchors.fill: parent + vendorExtensionsEnabled: false + + ShapePath { + fillColor: "transparent" + strokeColor: "blue" + strokeStyle: ShapePath.DashLine + strokeWidth: 4 + + PathText { + x: 96 + y: 10 + font.pixelSize: 120 + text: "Qt" + } + } + } + } + + Item { + width: 200 + height: 160 + + Rectangle { + anchors.fill: parent + color: "blue" + } + + Shape { + anchors.fill: parent + vendorExtensionsEnabled: false + + ShapePath { + fillColor: "red" + strokeColor: "blue" + strokeStyle: ShapePath.DashLine + capStyle: ShapePath.RoundCap + strokeWidth: 8 + + PathText { + x: 96; y: 10 + font.pixelSize: 150 + text: "Qt" + } + } + } + } + + Item { + width: 200 + height: 160 + + Shape { + anchors.fill: parent + vendorExtensionsEnabled: false + + ShapePath { + fillGradient: LinearGradient { + x1: 0; x2: 200; y1: 0; y2: 160 + spread: ShapeGradient.PadSpread + GradientStop { position: 0.0; color: "red"; } + GradientStop { position: 1.0; color: "green"; } + } + strokeColor: "blue" + strokeStyle: ShapePath.DashLine + joinStyle: ShapePath.RoundJoin + strokeWidth: 4 + + PathText { + x: 96; y: 10 + font.pixelSize: 150 + text: "Qt" + } + } + } + } + } +} -- cgit v1.2.3 From f7647d5adaaed4c651cb2e65c7ce66d7ef6639f1 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 23 Dec 2019 08:39:26 +0100 Subject: Add Image.sourceClipRect property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we set sourceSize, we expect to use that coordinate system in sourceClipRect too. Therefore we use QImageReader::setScaledClipRect(), not setClipRect(). [ChangeLog][QtQuick][Image] Image now has a sourceClipRect property to render a clipped image from a region of the sourceSize. Change-Id: If08277df772c2ab1063dd88572e49de41b97bca4 Reviewed-by: Jan Arve Sæther --- tests/manual/tableview/imagetiling/imageTiling.qml | 90 +++++++++++++++++++++ tests/manual/tableview/imagetiling/map.pdf | Bin 0 -> 31904 bytes tests/manual/tableview/imagetiling/map.png | Bin 0 -> 21101 bytes tests/manual/tableview/imagetiling/map.svgz | Bin 0 -> 27956 bytes 4 files changed, 90 insertions(+) create mode 100644 tests/manual/tableview/imagetiling/imageTiling.qml create mode 100644 tests/manual/tableview/imagetiling/map.pdf create mode 100644 tests/manual/tableview/imagetiling/map.png create mode 100644 tests/manual/tableview/imagetiling/map.svgz (limited to 'tests/manual') diff --git a/tests/manual/tableview/imagetiling/imageTiling.qml b/tests/manual/tableview/imagetiling/imageTiling.qml new file mode 100644 index 0000000000..5c9cdb9888 --- /dev/null +++ b/tests/manual/tableview/imagetiling/imageTiling.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.15 +import Qt.labs.qmlmodels 1.0 + +TableView { + id: root + width: 1024 + height: 200 + property int tileSize: 1024 / 8 + rowSpacing: 1; columnSpacing: 1 + model: TableModel { + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + TableModelColumn {} + columns: [0, 1, 2, 3, 4, 5, 6, 7] + rows: [0, 1, 2, 3] + } + delegate: Image { + id: image +// source: "map.png" // unscaled because png doesn't support QImageIOHandler::ScaledClipRect +// source: "map.svgz" // tiles offset incorrectly: see QTBUG-81044 + source: "map.pdf" // ok if the qtpdf plugin is installed + fillMode: Image.Pad + sourceSize.width: 1024 + sourceClipRect: Qt.rect(model.column * tileSize, model.row * tileSize, tileSize, tileSize) + cache: true + asynchronous: true + Text { + text: image.sourceClipRect.width + "x" + image.sourceClipRect.height + + " " + image.sourceClipRect.x + "," + image.sourceClipRect.y + + "\nfrom " + image.sourceSize.toString() + // inconsistency: if we don't set sourceSize, it ends up being sourceClipRect.size + "\nimplicit " + image.implicitWidth + "x" + image.implicitHeight + } + } + columnWidthProvider: function (c) { return tileSize } // workaround for QTBUG-81045 + rowHeightProvider: function (r) { return tileSize } +} diff --git a/tests/manual/tableview/imagetiling/map.pdf b/tests/manual/tableview/imagetiling/map.pdf new file mode 100644 index 0000000000..31e7b5225e Binary files /dev/null and b/tests/manual/tableview/imagetiling/map.pdf differ diff --git a/tests/manual/tableview/imagetiling/map.png b/tests/manual/tableview/imagetiling/map.png new file mode 100644 index 0000000000..23a8342818 Binary files /dev/null and b/tests/manual/tableview/imagetiling/map.png differ diff --git a/tests/manual/tableview/imagetiling/map.svgz b/tests/manual/tableview/imagetiling/map.svgz new file mode 100644 index 0000000000..64d509c106 Binary files /dev/null and b/tests/manual/tableview/imagetiling/map.svgz differ -- cgit v1.2.3 From 1c44804600ad3dbeb60d1f5209ce9cf937d30ab3 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 16 Jan 2020 13:45:15 +0100 Subject: Add PointerHandler.cursorShape property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, QQuickItemPrivate::setHasCursorInChild() was unable to check the QQuickItemPrivate::hasCursor variable, because the function argument hasCursor was shadowing that, even though the comment "nope! sorry, I have a cursor myself" hints that the intention was to check that. So this change exposed a problem there, and we have to fix that too, in order to keep the tst_qquickwindow::cursor() test passing. [ChangeLog][Event Handlers] Pointer Handlers now have a cursorShape property to set the cursor when the handler is active and the mouse is hovering, and restore to the previous cursor when the mouse leaves. Fixes: QTBUG-68073 Change-Id: Ib5c66bd59c4691c4210ee5465e1c95e7bdcf5ae1 Reviewed-by: Jan Arve Sæther --- tests/manual/pointer/sidebar.qml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tests/manual') diff --git a/tests/manual/pointer/sidebar.qml b/tests/manual/pointer/sidebar.qml index 827dbd1980..b7370a4fb7 100644 --- a/tests/manual/pointer/sidebar.qml +++ b/tests/manual/pointer/sidebar.qml @@ -26,7 +26,7 @@ ** ****************************************************************************/ -import QtQuick 2.12 +import QtQuick 2.15 import "content" Rectangle { @@ -53,6 +53,7 @@ Rectangle { id: buttonMA objectName: "buttonMA" hoverEnabled: true + cursorShape: Qt.UpArrowCursor anchors.fill: parent onClicked: console.log("clicked MA") } @@ -75,9 +76,11 @@ Rectangle { id: buttonHH objectName: "buttonHH" acceptedDevices: PointerDevice.AllDevices + cursorShape: tapHandler.pressed ? Qt.BusyCursor : Qt.PointingHandCursor } TapHandler { + id: tapHandler onTapped: tapFlash.start() } @@ -148,6 +151,7 @@ Rectangle { HoverHandler { id: topSidebarHH objectName: "topSidebarHH" + cursorShape: Qt.OpenHandCursor } Loader { @@ -173,6 +177,7 @@ Rectangle { id: bottomSidebarMA objectName: "bottomSidebarMA" hoverEnabled: true + cursorShape: Qt.ClosedHandCursor anchors.fill: parent } -- cgit v1.2.3 From 32dffb917536c6fb4af2986abaa6b0c7f35daed7 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 23 Jan 2020 13:07:22 +0100 Subject: Further RHI adaptation of shaders in lancelot test scenes In the recent commit that added RHI shaders, a couple of the test scenes were overlooked. The attributes.qml test file is simply removed as it adds no significant test coverage. Change-Id: Ic3af7b4447da322323f67faa1cf93c160c5043e8 Reviewed-by: Laszlo Agocs --- .../data/shaders/gridmesh/attributes.qml | 65 ---------------------- .../data/shaders/source/switch_3.qml | 9 +-- 2 files changed, 1 insertion(+), 73 deletions(-) delete mode 100644 tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml (limited to 'tests/manual') diff --git a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml b/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml deleted file mode 100644 index 17d9aadf95..0000000000 --- a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/attributes.qml +++ /dev/null @@ -1,65 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 320 - height: 480 - - Text { - id: text - font.pixelSize: 80 - text: "Shaderz!" - } - - ShaderEffectSource { - id: source - sourceItem: text - hideSource: true - smooth: true - } - Column { - ShaderEffect { - width: 320 - height: 160 - property variant source: source - vertexShader: " - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - varying highp vec2 qt_TexCoord0; - void main() { - gl_Position = qt_Matrix * qt_Vertex; - qt_TexCoord0 = qt_MultiTexCoord0; - }" - } - ShaderEffect { - width: 320 - height: 160 - property variant source: source - vertexShader: " - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - varying highp vec2 qt_TexCoord0; - void main() { - gl_Position = qt_Matrix * qt_Vertex; - qt_TexCoord0 = qt_MultiTexCoord0; - }" - } - ShaderEffect { - width: 320 - height: 160 - property variant source: source - vertexShader: " - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - varying highp vec2 qt_TexCoord0; - uniform highp float width; - uniform highp float height; - void main() { - gl_Position = qt_Matrix * qt_Vertex; - qt_TexCoord0 = qt_Vertex.xy / vec2(width, height); - }" - } - } -} diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml b/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml index 0d3c1fc4ee..c02dfba9e2 100644 --- a/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml +++ b/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml @@ -47,14 +47,7 @@ Item { property variant source: source - fragmentShader: " - uniform lowp sampler2D source; - varying highp vec2 qt_TexCoord0; - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = vec4(qt_TexCoord0.x, qt_TexCoord0.y, 1, 1) * texture2D(source, qt_TexCoord0).a; - } - " + fragmentShader: "qrc:shaders/gradient.frag" } -- cgit v1.2.3 From 8e822e981d91e688799c8670f11dfdf6aaf9e0d1 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Sat, 14 Dec 2019 16:02:21 +0100 Subject: Deliver QTabletEvents to pointer handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At this time, there are not yet any specialized handlers to do anything specifically with tablet events; but we demonstrate how to use HoverHandler to detect the type of stylus in use, and how to use PointHandler to draw on a Canvas. Unfortunately, events of types TabletEnterProximity and TabletLeaveProximity are not delivered to the window, only to QGuiApplication. So HoverHandler can detect when the stylus is moved out of its parent Item (as long as it's still hovering over the tablet surface), but cannot detect when the stylus leaves the tablet completely. In Qt 5 that would require a custom application subclass (see qtbase/examples/widgets/widgets/tablet/tabletapplication.cpp). Fixes: QTBUG-79660 Change-Id: I81fdb99082dc41c0455085e6b6d3952402bf8742 Reviewed-by: Qt CI Bot Reviewed-by: Jan Arve Sæther --- tests/manual/pointer/main.qml | 3 +- tests/manual/pointer/qml.qrc | 5 + tests/manual/pointer/resources/cursor-airbrush.png | Bin 0 -> 823 bytes tests/manual/pointer/resources/cursor-eraser.png | Bin 0 -> 1454 bytes .../pointer/resources/cursor-felt-marker.png | Bin 0 -> 513 bytes tests/manual/pointer/resources/cursor-pencil.png | Bin 0 -> 1307 bytes tests/manual/pointer/tabletCanvasDrawing.qml | 242 +++++++++++++++++++++ 7 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 tests/manual/pointer/resources/cursor-airbrush.png create mode 100644 tests/manual/pointer/resources/cursor-eraser.png create mode 100644 tests/manual/pointer/resources/cursor-felt-marker.png create mode 100644 tests/manual/pointer/resources/cursor-pencil.png create mode 100644 tests/manual/pointer/tabletCanvasDrawing.qml (limited to 'tests/manual') diff --git a/tests/manual/pointer/main.qml b/tests/manual/pointer/main.qml index d382d8b23d..83e1d3b2ba 100644 --- a/tests/manual/pointer/main.qml +++ b/tests/manual/pointer/main.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the manual tests of the Qt Toolkit. @@ -57,6 +57,7 @@ Window { addExample("multibuttons", "TapHandler: gesturePolicy (99 red balloons)", Qt.resolvedUrl("multibuttons.qml")) addExample("flickable with Handlers", "Flickable with buttons, sliders etc. implemented in various ways", Qt.resolvedUrl("flickableWithHandlers.qml")) addExample("tap and drag", "Flickable with all possible combinations of TapHandler and DragHandler children", Qt.resolvedUrl("pointerDrag.qml")) + addExample("tablet canvas", "PointHandler and HoverHandler with a tablet: detect the stylus, and draw", Qt.resolvedUrl("tabletCanvasDrawing.qml")) } } Item { diff --git a/tests/manual/pointer/qml.qrc b/tests/manual/pointer/qml.qrc index 95bece180a..20956fcbac 100644 --- a/tests/manual/pointer/qml.qrc +++ b/tests/manual/pointer/qml.qrc @@ -13,6 +13,7 @@ pointerDrag.qml singlePointHandlerProperties.qml sidebar.qml + tabletCanvasDrawing.qml tapHandler.qml content/CheckBox.qml content/FakeFlickable.qml @@ -30,6 +31,10 @@ content/TouchpointFeedbackSprite.qml resources/arrowhead.png resources/balloon.png + resources/cursor-airbrush.png + resources/cursor-eraser.png + resources/cursor-felt-marker.png + resources/cursor-pencil.png resources/fighter.png resources/fingersprite.png resources/grabbing-location.svg diff --git a/tests/manual/pointer/resources/cursor-airbrush.png b/tests/manual/pointer/resources/cursor-airbrush.png new file mode 100644 index 0000000000..bea756ed6f Binary files /dev/null and b/tests/manual/pointer/resources/cursor-airbrush.png differ diff --git a/tests/manual/pointer/resources/cursor-eraser.png b/tests/manual/pointer/resources/cursor-eraser.png new file mode 100644 index 0000000000..e5488a89f2 Binary files /dev/null and b/tests/manual/pointer/resources/cursor-eraser.png differ diff --git a/tests/manual/pointer/resources/cursor-felt-marker.png b/tests/manual/pointer/resources/cursor-felt-marker.png new file mode 100644 index 0000000000..132f09aa39 Binary files /dev/null and b/tests/manual/pointer/resources/cursor-felt-marker.png differ diff --git a/tests/manual/pointer/resources/cursor-pencil.png b/tests/manual/pointer/resources/cursor-pencil.png new file mode 100644 index 0000000000..cc2f447d02 Binary files /dev/null and b/tests/manual/pointer/resources/cursor-pencil.png differ diff --git a/tests/manual/pointer/tabletCanvasDrawing.qml b/tests/manual/pointer/tabletCanvasDrawing.qml new file mode 100644 index 0000000000..c340dee5f4 --- /dev/null +++ b/tests/manual/pointer/tabletCanvasDrawing.qml @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import "content" + +Rectangle { + width: 1024 + height: 1024 + color: "#444" + + ColumnLayout { + x: -15; width: 80 + height: parent.height + Slider { + id: hueSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "hue" + Rectangle { + color: "beige" + width: 30 + height: 25 + anchors.bottom: parent.bottom + anchors.bottomMargin: 2 + anchors.horizontalCenter: parent.horizontalCenter + Rectangle { + border.color: "white" + color: canvas.drawingColor + anchors.fill: parent + } + } + } + Slider { + id: saturationSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "sat" + } + Slider { + id: lightnessSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "light" + } + } + + ColumnLayout { + x: parent.width - 65; width: 80 + height: parent.height + Slider { + id: widthSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "width" + } + Slider { + id: alphaSlider + width: 80; height: 200 + Layout.fillHeight: true + label: "alpha" + } + } + + Rectangle { + id: rect + width: 640 + height: 480 + color: "beige" + anchors { + fill: parent + margins: 10 + leftMargin: 50 + rightMargin: 50 + } + + Canvas { + id: canvas + anchors.fill: parent + antialiasing: true + renderTarget: Canvas.FramebufferObject + property color drawingColor: Qt.hsla(hueSlider.value / 100.0, + saturationSlider.value / 100.0, + lightnessSlider.value / 100.0, + alphaSlider.value / 100.0) + property var points: [] + property var pressures: [] + property var pointerType: PointerDevice.Pen + onPaint: { + if (points.length < 2) + return + var ctx = canvas.getContext('2d'); + ctx.save() + ctx.strokeStyle = pointerType === PointerDevice.Pen ? drawingColor : "beige" + ctx.lineCap = "round" + if (pressures.length === points.length) { + for (var i = 1; i < points.length; i++) { + ctx.lineWidth = pressures[i] * widthSlider.value + ctx.beginPath() + ctx.moveTo(points[i - 1].x, points[i - 1].y) + ctx.lineTo(points[i].x, points[i].y) + ctx.stroke() + } + points = points.slice(points.length - 2, 1) + pressures = pressures.slice(pressures.length - 2, 1) + } else { + 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.lineWidth = widthSlider + ctx.stroke() + points = points.slice(points.length - 2, 1) + pressures = [] + } + ctx.restore() + } + } + + PointHandler { + acceptedPointerTypes: PointerDevice.Pen + onActiveChanged: + if (active) { + canvas.pointerType = PointerDevice.Pen + } else { + canvas.points = [] + canvas.pressures = [] + } + onPointChanged: + if (active) { + canvas.points.push(point.position) + canvas.pressures.push(point.pressure) + canvas.requestPaint() + } + } + + PointHandler { + acceptedPointerTypes: PointerDevice.Eraser + onActiveChanged: + if (active) { + canvas.pointerType = PointerDevice.Eraser + } else { + canvas.points = [] + canvas.pressures = [] + } + onPointChanged: + if (active) { + canvas.points.push(point.position) + canvas.pressures.push(point.pressure) + canvas.requestPaint() + } + } + + HoverHandler { + id: stylusHandler + acceptedDevices: PointerDevice.Stylus + acceptedPointerTypes: PointerDevice.Pen + target: Image { + parent: rect + source: stylusHandler.point.rotation === 0 ? + "resources/cursor-pencil.png" : "resources/cursor-felt-marker.png" + visible: stylusHandler.hovered + rotation: stylusHandler.point.rotation + x: stylusHandler.point.position.x + y: stylusHandler.point.position.y + } + } + + HoverHandler { + id: airbrushHandler + acceptedDevices: PointerDevice.Airbrush + acceptedPointerTypes: PointerDevice.Pen + target: Image { + parent: rect + source: "resources/cursor-airbrush.png" + visible: airbrushHandler.hovered + x: airbrushHandler.point.position.x + y: airbrushHandler.point.position.y + } + } + + HoverHandler { + id: eraserHandler + acceptedPointerTypes: PointerDevice.Eraser + target: Image { + parent: rect + source: "resources/cursor-eraser.png" + visible: eraserHandler.hovered + x: eraserHandler.point.position.x + y: eraserHandler.point.position.y - 32 + } + } + } +} -- cgit v1.2.3