Files
komplex-hub/build/qml/QtQuickUltralite/Studio/Components/ArcItem.qml
T
2026-06-02 15:11:36 -04:00

245 lines
9.3 KiB
QML

/****************************************************************************
**
** Copyright (C) 2023 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Quick Ultralite compatibility.
**
** $QT_BEGIN_LICENSE:GPL$
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.9
import QtQuick.Shapes 1.12
//! [ArcItem compatibility]
Shape {
id: root
implicitWidth: 100
implicitHeight: 100
// These properties are not supported in Qt Quick Ultralite:
// strokeStyle, dashPattern, dashOffset
property alias gradient: path.fillGradient
property alias strokeWidth: path.strokeWidth
property alias strokeColor: path.strokeColor
property alias joinStyle: path.joinStyle
property alias fillColor: path.fillColor
property alias capStyle: path.capStyle
property real begin: 0
property real end: 90
property real arcWidth: 10
property real alpha: root.clamp(root.sortedEnd() - root.sortedBegin(), 0, 359.9)
// antialiasing is enabled to have the same shape as Qt Quick Ultralite runtime
antialiasing: true
layer.enabled: root.antialiasing
layer.smooth: root.antialiasing
layer.samples: root.antialiasing ? 4 : 0
property bool outlineArc: false
property bool round: false
property bool roundEnd: root.round
property bool roundBegin: root.round
function clamp(num, min, max) {
return Math.max(min, Math.min(num, max))
}
function toRadians(degrees) {
return degrees * (Math.PI / 180.0)
}
function myCos(angleInDegrees) {
return Math.cos(root.toRadians(angleInDegrees))
}
function mySin(angleInDegrees) {
return Math.sin(root.toRadians(angleInDegrees))
}
function polarToCartesianX(centerX, centerY, radius, angleInDegrees) {
return centerX + radius * Math.cos(root.toRadians(angleInDegrees))
}
function polarToCartesianY(centerX, centerY, radius, angleInDegrees) {
return centerY + radius * Math.sin(root.toRadians(angleInDegrees))
}
function sortedBegin() {
return Math.min(root.begin, root.end)
}
function sortedEnd() {
return Math.min(Math.max(root.begin, root.end), root.sortedBegin() + 359.9)
}
function isArcFull() {
return root.alpha > 359.5
}
onAlphaChanged: {
if (root.__wasFull !== root.isArcFull())
root.constructArcItem()
root.__wasFull = root.isArcFull()
}
onOutlineArcChanged: root.constructArcItem()
onRoundChanged: root.constructArcItem()
onRoundBeginChanged: root.constructArcItem()
onRoundEndChanged: root.constructArcItem()
property bool __wasFull: false
property real maxArcWidth: Math.min(path.__xRadius, path.__yRadius)
ShapePath {
id: path
property real __xRadius: root.width / 2 - root.strokeWidth / 2
property real __yRadius: root.height / 2 - root.strokeWidth / 2
property real __arcWidth: Math.min(Math.min(path.__xRadius, path.__yRadius), root.arcWidth)
property real __xCenter: root.width / 2
property real __yCenter: root.height / 2
strokeColor: "red"
strokeWidth: 4
capStyle: ShapePath.FlatCap
startX: root.polarToCartesianX(path.__xCenter, path.__yCenter, path.__xRadius, root.sortedBegin() - 90)
startY: root.polarToCartesianY(path.__xCenter, path.__yCenter, path.__yRadius, root.sortedBegin() - 90)
}
function constructArcItem() {
root.clearPathElements()
// Outer arc
let outerArc = Qt.createQmlObject('import QtQuick 2.15; PathArc {}', path)
outerArc.x = Qt.binding(function() {
return root.polarToCartesianX(path.__xCenter, path.__yCenter, path.__xRadius, root.sortedEnd() - 90)
})
outerArc.y = Qt.binding(function() {
return root.polarToCartesianY(path.__xCenter, path.__yCenter, path.__yRadius, root.sortedEnd() - 90)
})
outerArc.radiusX = Qt.binding(function() { return path.__xRadius })
outerArc.radiusY = Qt.binding(function() { return path.__yRadius })
outerArc.useLargeArc = Qt.binding(function() { return root.alpha > 180 })
path.pathElements.push(outerArc)
// Straight end
if (!root.roundEnd && root.outlineArc && !root.isArcFull()) {
let pathLine = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path)
pathLine.relativeX = Qt.binding(function() {
return -path.__arcWidth * root.myCos(root.sortedEnd() - 90)
})
pathLine.relativeY = Qt.binding(function() {
return -path.__arcWidth * root.mySin(root.sortedEnd() - 90)
})
path.pathElements.push(pathLine)
}
// Round end
if (root.roundEnd && root.outlineArc && !root.isArcFull()) {
let pathArc = Qt.createQmlObject('import QtQuick 2.15; PathArc {}', path)
pathArc.relativeX = Qt.binding(function() {
return -path.__arcWidth * root.myCos(root.sortedEnd() - 90)
})
pathArc.relativeY = Qt.binding(function() {
return -path.__arcWidth * root.mySin(root.sortedEnd() - 90)
})
pathArc.radiusX = Qt.binding(function() { return path.__arcWidth / 2 })
pathArc.radiusY = Qt.binding(function() { return path.__arcWidth / 2 })
path.pathElements.push(pathArc)
}
// Open end
if (root.outlineArc && root.isArcFull()) {
let pathMove = Qt.createQmlObject('import QtQuick 2.15; PathMove {}', path)
pathMove.relativeX = Qt.binding(function() {
return -path.__arcWidth * root.myCos(root.sortedEnd() - 90)
})
pathMove.relativeY = Qt.binding(function() {
return -path.__arcWidth * root.mySin(root.sortedEnd() - 90)
})
path.pathElements.push(pathMove)
}
// Inner arc
if (root.outlineArc) {
let innerArc = Qt.createQmlObject('import QtQuick 2.15; PathArc {}', path)
innerArc.x = Qt.binding(function() {
return path.startX - path.__arcWidth * root.myCos(root.sortedBegin() - 90)
})
innerArc.y = Qt.binding(function() {
return path.startY - path.__arcWidth * root.mySin(root.sortedBegin() - 90)
})
innerArc.radiusX = Qt.binding(function() { return path.__xRadius - path.__arcWidth })
innerArc.radiusY = Qt.binding(function() { return path.__yRadius - path.__arcWidth })
innerArc.useLargeArc = Qt.binding(function() { return root.alpha > 180 })
innerArc.direction = PathArc.Counterclockwise
path.pathElements.push(innerArc)
}
// Straight begin
if (!root.roundBegin && root.outlineArc && !root.isArcFull()) {
let pathLine = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path)
pathLine.x = Qt.binding(function() { return path.startX })
pathLine.y = Qt.binding(function() { return path.startY })
path.pathElements.push(pathLine)
}
// Round begin
if (root.roundBegin && root.outlineArc && !root.isArcFull()) {
let pathArc = Qt.createQmlObject('import QtQuick 2.15; PathArc {}', path)
pathArc.x = Qt.binding(function() { return path.startX })
pathArc.y = Qt.binding(function() { return path.startY })
pathArc.radiusX = Qt.binding(function() { return path.__arcWidth / 2 })
pathArc.radiusY = Qt.binding(function() { return path.__arcWidth / 2 })
path.pathElements.push(pathArc)
}
// Open begin
if (root.outlineArc && root.isArcFull()) {
let pathMove = Qt.createQmlObject('import QtQuick 2.15; PathMove {}', path)
pathMove.x = Qt.binding(function() { return path.startX })
pathMove.y = Qt.binding(function() { return path.startY })
path.pathElements.push(pathMove)
}
}
function clearPathElements() {
for (var i = 0; i !== path.pathElements.length; ++i)
path.pathElements[i].destroy()
path.pathElements = []
}
Component.onCompleted: {
root.__wasFull = root.isArcFull()
root.constructArcItem()
}
}
//! [ArcItem compatibility]