Warning, /graphics/spectacle/src/Gui/Handle.qml is written in an unsupported language. File is not indexed.

0001 /* SPDX-FileCopyrightText: 2024 Noah Davis <noahadvs@gmail.com>
0002  * SPDX-License-Identifier: LGPL-2.0-or-later
0003  */
0004 
0005 import QtQuick
0006 import QtQuick.Shapes
0007 
0008 Shape {
0009     id: root
0010 
0011     property alias shapePath: shapePath
0012     property real startAngle: 0 // Zero and 360 are 3 o'clock, positive goes clockwise
0013     property real sweepAngle: 360 // positive goes clockwise
0014     property real xOffset: 0
0015     property real yOffset: 0
0016 
0017     containsMode: Shape.FillContains
0018     preferredRendererType: Shape.CurveRenderer
0019 
0020     function pointAtAngle(degrees) {
0021         const radians = degrees * (Math.PI / 180)
0022         return Qt.point(pathAngleArc.radiusX * Math.cos(radians) + pathAngleArc.centerX,
0023                         pathAngleArc.radiusY * Math.sin(radians) + pathAngleArc.centerY)
0024     }
0025 
0026     function xAtAngle(degrees) {
0027         return pathAngleArc.radiusX * Math.cos(degrees * (Math.PI / 180)) + pathAngleArc.centerX
0028     }
0029 
0030     function yAtAngle(degrees) {
0031         return pathAngleArc.radiusY * Math.sin(degrees * (Math.PI / 180)) + pathAngleArc.centerY
0032     }
0033 
0034     ShapePath {
0035         id: shapePath
0036         fillColor: root.enabled ? palette.active.highlight : palette.disabled.highlight
0037         strokeWidth: 0
0038         strokeColor: root.enabled ? palette.active.highlightedText : palette.disabled.highlightedText
0039         strokeStyle: ShapePath.SolidLine
0040         joinStyle: ShapePath.MiterJoin
0041         capStyle: ShapePath.FlatCap
0042         // Keep stroke in bounds
0043         scale: Qt.size((root.width - strokeWidth) / root.width,
0044                        (root.height - strokeWidth) / root.height)
0045         PathAngleArc {
0046             id: pathAngleArc
0047             moveToStart: true // this path should not be affected by startX/startY
0048             radiusX: root.width / 2
0049             radiusY: root.height / 2
0050             // offset with stroke and prevent scale from being applied to the offset
0051             centerX: (shapePath.strokeWidth / 2 + root.xOffset) / shapePath.scale.width + radiusX
0052             centerY: (shapePath.strokeWidth / 2 + root.yOffset) / shapePath.scale.height + radiusY
0053             startAngle: root.startAngle // Zero is 3 o'clock, positive goes clockwise
0054             sweepAngle: root.sweepAngle // positive goes clockwise
0055         }
0056         PathLine {
0057             id: lineFromArcEnd
0058             x: if (pathAngleArc.sweepAngle % 360 === 0) {
0059                 return root.xAtAngle(pathAngleArc.startAngle + pathAngleArc.sweepAngle)
0060             } else if (pathAngleArc.sweepAngle % 180 === 0) {
0061                 return root.xAtAngle(pathAngleArc.startAngle)
0062             } else {
0063                 return pathAngleArc.centerX
0064             }
0065             y: if (pathAngleArc.sweepAngle % 360 === 0) {
0066                 return root.yAtAngle(pathAngleArc.startAngle + pathAngleArc.sweepAngle)
0067             } else if (pathAngleArc.sweepAngle % 180 === 0) {
0068                 return root.yAtAngle(pathAngleArc.startAngle)
0069             } else {
0070                 return pathAngleArc.centerY
0071             }
0072         }
0073         PathLine {
0074             id: lineFromCenter
0075             x: pathAngleArc.sweepAngle % 180 === 0 ?
0076                 lineFromArcEnd.x : root.xAtAngle(pathAngleArc.startAngle)
0077             y: pathAngleArc.sweepAngle % 180 === 0 ?
0078                 lineFromArcEnd.y : root.yAtAngle(pathAngleArc.startAngle)
0079         }
0080     }
0081 }