diff options
-rw-r--r-- | src/imports/components/RegularPolygonItem.qml | 318 | ||||
-rw-r--r-- | src/imports/components/components.pri | 1 | ||||
-rw-r--r-- | src/imports/components/designer/RegularPolygonItemSpecifics.qml | 151 | ||||
-rw-r--r-- | src/imports/components/designer/components.metainfo | 32 | ||||
-rw-r--r-- | src/imports/components/designer/designer.pri | 4 | ||||
-rw-r--r-- | src/imports/components/designer/images/polygon-16px.png | bin | 0 -> 320 bytes | |||
-rw-r--r-- | src/imports/components/designer/images/polygon-24px.png | bin | 0 -> 460 bytes | |||
-rw-r--r-- | src/imports/components/designer/images/polygon-24px@2x.png | bin | 0 -> 848 bytes | |||
-rw-r--r-- | src/imports/components/qmldir | 1 |
9 files changed, 497 insertions, 10 deletions
diff --git a/src/imports/components/RegularPolygonItem.qml b/src/imports/components/RegularPolygonItem.qml new file mode 100644 index 0000000..0d51760 --- /dev/null +++ b/src/imports/components/RegularPolygonItem.qml @@ -0,0 +1,318 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Studio Components. +** +** $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.10 +import QtQuick.Shapes 1.0 + +/*! + \qmltype RegularPolygon + \inqmlmodule QtQuick.Studio.Components + \since QtQuick.Studio.Components 1.0 + \inherits Shape + + \brief A filled regular polygon with an optional border. +*/ + +Shape { + id: root + width: 200 + height: 200 + +/*! + The radius used to draw rounded corners. + + The default value is 10. + + If radius is non-zero, the corners will be rounded, otherwise they will + be sharp. The radius can also be specified separately for each corner by + using the \l bottomLeftRadius, \l bottomRightRadius, \l topLeftRadius, and + \l topRightRadius properties. +*/ + property int radius: 10 + +/*! + The gradient of the regular polygon fill color. + + By default, no gradient is enabled and the value is null. In this case, the + fill uses a solid color based on the value of \l fillColor. + + When set, \l fillColor is ignored and filling is done using one of the + \l ShapeGradient subtypes. + + \note The \l Gradient type cannot be used here. Rather, prefer using one of + the advanced subtypes, like \l LinearGradient. +*/ + property alias gradient: path.fillGradient + +/*! + The style of the regular polygon border. + + \value ShapePath.SolidLine + A solid line. This is the default value. + \value ShapePath.DashLine + Dashes separated by a few pixels. + The \l dashPattern property specifies the dash pattern. + + \sa Qt::PenStyle +*/ + property alias strokeStyle: path.strokeStyle + +/*! + The width of the border of the regular polygon. + + The default value is 4. + + A width of 1 creates a thin line. For no line, use a negative value or a + transparent color. + + \note The width of the regular polygon's border does not affect the geometry of + the regular polygon itself or its position relative to other items if anchors are + used. + + The border is rendered within the regular polygon's boundaries. +*/ + property alias strokeWidth: path.strokeWidth + +/*! + The color used to draw the border of the regular polygon. + + When set to \c transparent, no line is drawn. + + The default value is \c red. + + \sa QColor +*/ + property alias strokeColor: path.strokeColor + +/*! + The dash pattern of the regular polygon border specified as the dashes and the + gaps between them. + + The dash pattern is specified in units of the pen's width. That is, a dash + with the length 5 and width 10 is 50 pixels long. + + The default value is (4, 2), meaning a dash of 4 * \l strokeWidth pixels + followed by a space of 2 * \l strokeWidth pixels. + + \sa QPen::setDashPattern() +*/ + property alias dashPattern: path.dashPattern + + + property alias joinStyle: path.joinStyle + +/*! + The regular polygon fill color. + + A gradient for the fill can be specified by using \l gradient. If both a + color and a gradient are specified, the gradient is used. + + When set to \c transparent, no filling occurs. + + The default value is \c white. +*/ + property alias fillColor: path.fillColor + +/*! + The starting point of the dash pattern for the regular polygon border. + + The offset is measured in terms of the units used to specify the dash + pattern. For example, a pattern where each stroke is four units long, + followed by a gap of two units, will begin with the stroke when drawn + as a line. However, if the dash offset is set to 4.0, any line drawn + will begin with the gap. Values of the offset up to 4.0 will cause part + of the stroke to be drawn first, and values of the offset between 4.0 and + 6.0 will cause the line to begin with part of the gap. + + The default value is 0. + + \sa QPen::setDashOffset() +*/ + property alias dashOffset: path.dashOffset + +/*! + Number of sides on the polygon. +*/ + property int sideCount: 6 + + layer.enabled: root.antialiasing + layer.smooth: root.antialiasing + layer.textureSize: Qt.size(root.width * 2, root.height * 2) + + // This is used to make the bounding box of the item a bit bigger so it will draw sharp edges + // in case of large stroke width instead of cutting it off. + Item { + anchors.fill: parent + anchors.margins: -root.strokeWidth + } + + ShapePath { + id: path + + joinStyle: ShapePath.MiterJoin + strokeWidth: 4 + strokeColor: "red" + startX: 0 + startY: 0 + } + + onSideCountChanged: root.constructPolygon() + onRadiusChanged: { + // Only construct polygon if radius changed from 0 to 1 or vice versa. + if ((root.radius + root.__previousRadius) === 1) + root.constructPolygon() + + root.__previousRadius = root.radius + } + Component.onCompleted: root.constructPolygon() + + property real __centerX: root.width / 2 + property real __centerY: root.height / 2 + property real __radius: Math.min(root.width, root.height) / 2 + + property int __previousRadius: root.radius + + property int minRadius: 0 + property int maxRadius: root.__radius * Math.cos(root.toRadians(180.0 / root.sideCount)) + + property int __actualRadius: Math.max(root.minRadius, Math.min(root.maxRadius, root.radius)) + + function constructPolygon() { + root.clearPathElements() + + if (root.radius === 0) + root.constructNonRoundedPolygonPath() + else + root.constructRoundedPolygonPath() + } + + function toRadians(degrees) { + return degrees * (Math.PI / 180.0) + } + + function constructNonRoundedPolygonPath() { + for (var cornerNumber = 0; cornerNumber < root.sideCount; cornerNumber++) { + let angleToCorner = root.toRadians(cornerNumber * (360.0 / root.sideCount)) + + if (cornerNumber === 0) { + path.startX = Qt.binding(function() { + return root.__centerX + root.__radius * Math.cos(0) + }) + path.startY = Qt.binding(function() { + return root.__centerY + root.__radius * Math.sin(0) + }) + } else { + let pathLine = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path) + pathLine.x = Qt.binding(function() { + return root.__centerX + root.__radius * Math.cos(angleToCorner) + }) + pathLine.y = Qt.binding(function() { + return root.__centerY + root.__radius * Math.sin(angleToCorner) + }) + path.pathElements.push(pathLine) + } + } + + // Close the polygon + var pathLineClose = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path) + pathLineClose.x = Qt.binding(function() { return path.startX } ) + pathLineClose.y = Qt.binding(function() { return path.startY } ) + path.pathElements.push(pathLineClose) + } + + property real __halfInteriorCornerAngle: 90 - (180.0 / root.sideCount) + property real __halfCornerArcSweepAngle: 90 - root.__halfInteriorCornerAngle + property real __distanceToCornerArcCenter: root.__radius - root.__actualRadius / + Math.sin(root.toRadians(root.__halfInteriorCornerAngle)) + + function constructRoundedPolygonPath() { + for (var cornerNumber = 0; cornerNumber < root.sideCount; cornerNumber++) { + let angleToCorner = cornerNumber * (360.0 / root.sideCount) + + let pathArc = Qt.createQmlObject('import QtQuick 2.15; PathArc { + property real centerX; + property real centerY }', path) + pathArc.centerX = Qt.binding(function() { + return root.__centerX + root.__distanceToCornerArcCenter + * Math.cos(root.toRadians(angleToCorner)) + }) + pathArc.centerY = Qt.binding(function() { + return root.__centerY + root.__distanceToCornerArcCenter + * Math.sin(root.toRadians(angleToCorner)) + }) + pathArc.x = Qt.binding(function() { + return pathArc.centerX + root.__actualRadius + * (Math.cos(root.toRadians(angleToCorner + root.__halfCornerArcSweepAngle))) + }) + pathArc.y = Qt.binding(function() { + return pathArc.centerY + root.__actualRadius + * (Math.sin(root.toRadians(angleToCorner + root.__halfCornerArcSweepAngle))) + }) + pathArc.radiusX = Qt.binding(function() { return root.__actualRadius }) + pathArc.radiusY = Qt.binding(function() { return root.__actualRadius }) + + if (cornerNumber === 0) { + path.startX = Qt.binding(function() { + return pathArc.centerX + root.__actualRadius + * (Math.cos(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle))) + }) + path.startY = Qt.binding(function() { + return pathArc.centerY + root.__actualRadius + * (Math.sin(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle))) + }) + } else { + let pathLine = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path) + pathLine.x = Qt.binding(function() { + return pathArc.centerX + root.__actualRadius + * (Math.cos(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle))) + }) + pathLine.y = Qt.binding(function() { + return pathArc.centerY + root.__actualRadius + * (Math.sin(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle))) + }) + path.pathElements.push(pathLine) + } + + path.pathElements.push(pathArc) + } + + // Close the polygon + var pathLineClose = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path) + pathLineClose.x = Qt.binding(function() { return path.startX} ) + pathLineClose.y = Qt.binding(function() { return path.startY} ) + path.pathElements.push(pathLineClose) + } + + function clearPathElements() { + for (var i = 0; i !== path.pathElements.length; ++i) + path.pathElements[i].destroy() + + path.pathElements = [] + } +} diff --git a/src/imports/components/components.pri b/src/imports/components/components.pri index 7d5a306..2406587 100644 --- a/src/imports/components/components.pri +++ b/src/imports/components/components.pri @@ -7,6 +7,7 @@ QML_FILES += \ $$PWD/SvgPathItem.qml \ $$PWD/TriangleItem.qml \ $$PWD/RectangleItem.qml \ + $$PWD/RegularPolygonItem.qml \ $$PWD/GroupItem.qml \ $$PWD/ArcArrow.qml \ $$PWD/StraightArrow.qml diff --git a/src/imports/components/designer/RegularPolygonItemSpecifics.qml b/src/imports/components/designer/RegularPolygonItemSpecifics.qml new file mode 100644 index 0000000..33cc02e --- /dev/null +++ b/src/imports/components/designer/RegularPolygonItemSpecifics.qml @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Designer Components. +** +** $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.15 +import QtQuick.Layouts 1.15 +import HelperWidgets 2.0 +import StudioTheme 1.0 as StudioTheme + +Column { + anchors.left: parent.left + anchors.right: parent.right + + Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Regular Polygon Item") + + SectionLayout { + PropertyLabel { text: qsTr("Fill color") } + + ColorEditor { + backendValue: backendValues.fillColor + supportGradient: true + shapeGradients: true + } + + PropertyLabel { text: qsTr("Stroke color") } + + ColorEditor { + backendValue: backendValues.strokeColor + supportGradient: false + } + + PropertyLabel { text: qsTr("Stroke width") } + + SecondColumnLayout { + SpinBox { + id: strokeWidthSpin + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.strokeWidth + decimals: 1 + minimumValue: -1 + maximumValue: 200 + stepSize: 1 + } + + Spacer { + implicitWidth: StudioTheme.Values.twoControlColumnGap + + StudioTheme.Values.actionIndicatorWidth + } + + CheckBox { + id: strokeWidthCheck + text: qsTr("Hide") + checked: (backendValues.strokeWidth.value >= 0 ? false : true) + actionIndicator.visible: false + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + onCheckedChanged: { + if (strokeWidthCheck.checked === true) + backendValues.strokeWidth.value = -1 + else + backendValues.strokeWidth.value = ((backendValues.strokeWidth.value < 0) ? 4 : backendValues.strokeWidth.value) + } + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Side count") } + + SecondColumnLayout { + SpinBox { + backendValue: backendValues.sideCount + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + decimals: 0 + minimumValue: 3 + maximumValue: 100 + stepSize: 1 + } + + ExpandingSpacer {} + } + } + } + + StrokeDetailsSection { + showBorderMode: false + showJoinStyle: true + showCapStyle: false + } + + Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Radiuses") + + SectionLayout { + PropertyLabel { text: qsTr("Radius") } + + SecondColumnLayout { + SpinBox { + backendValue: backendValues.radius + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + decimals: 0 + minimumValue: backendValues.minRadius.value + maximumValue: backendValues.maxRadius.value + stepSize: 1 + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + MultiIconLabel { + icon0: StudioTheme.Constants.triangleCornerB + icon1: StudioTheme.Constants.triangleCornerA + } + + ExpandingSpacer {} + } + } + } +} diff --git a/src/imports/components/designer/components.metainfo b/src/imports/components/designer/components.metainfo index ebf488f..a7dbcb9 100644 --- a/src/imports/components/designer/components.metainfo +++ b/src/imports/components/designer/components.metainfo @@ -77,20 +77,32 @@ MetaInfo { } } - Type { - name: "QtQuick.Studio.Components.RectangleItem" - icon: "images/custom-rectangle-16px.png" +Type { + name: "QtQuick.Studio.Components.RectangleItem" + icon: "images/custom-rectangle-16px.png" - ItemLibraryEntry { - name: "Rectangle" - category: "Studio Components" - libraryIcon: "images/custom-rectangle-24px.png" - version: "1.0" - requiredImport: "QtQuick.Studio.Components" + ItemLibraryEntry { + name: "Rectangle" + category: "Studio Components" + libraryIcon: "images/custom-rectangle-24px.png" + version: "1.0" + requiredImport: "QtQuick.Studio.Components" - } } +} + +Type { + name: "QtQuick.Studio.Components.RegularPolygonItem" + icon: "images/polygon-16px.png" + ItemLibraryEntry { + name: "Regular Polygon" + category: "Studio Components" + libraryIcon: "images/polygon-24px.png" + version: "1.0" + requiredImport: "QtQuick.Studio.Components" + } +} Type { name: "QtQuick.Studio.Components.BorderItem" diff --git a/src/imports/components/designer/designer.pri b/src/imports/components/designer/designer.pri index 9ec2959..13db20e 100644 --- a/src/imports/components/designer/designer.pri +++ b/src/imports/components/designer/designer.pri @@ -14,6 +14,7 @@ AUX_QML_FILES += \ $$PWD/IsoItemSpecifics.qml \ $$PWD/PieItemSpecifics.qml \ $$PWD/RectangleItemSpecifics.qml \ + $$PWD/RegularPolygonItemSpecifics.qml \ $$PWD/StrokeDetailsSection.qml \ $$PWD/SvgPathItemSpecifics.qml \ $$PWD/TriangleItemSpecifics.qml @@ -46,6 +47,9 @@ AUX_QML_FILES += \ $$PWD/images/group-16px.png \ $$PWD/images/group-24px.png \ $$PWD/images/group-24px@2.png \ + $$PWD/images/polygon-16px.png \ + $$PWD/images/polygon-24px.png \ + $$PWD/images/polygon-24px@2x.png \ $$PWD/images/item-arrow-16px.png \ $$PWD/images/item-arrow-arc-16px.png \ $$PWD/images/item-arrow-arc-24px.png \ diff --git a/src/imports/components/designer/images/polygon-16px.png b/src/imports/components/designer/images/polygon-16px.png Binary files differnew file mode 100644 index 0000000..b56c7bb --- /dev/null +++ b/src/imports/components/designer/images/polygon-16px.png diff --git a/src/imports/components/designer/images/polygon-24px.png b/src/imports/components/designer/images/polygon-24px.png Binary files differnew file mode 100644 index 0000000..51209ec --- /dev/null +++ b/src/imports/components/designer/images/polygon-24px.png diff --git a/src/imports/components/designer/images/polygon-24px@2x.png b/src/imports/components/designer/images/polygon-24px@2x.png Binary files differnew file mode 100644 index 0000000..a400ec6 --- /dev/null +++ b/src/imports/components/designer/images/polygon-24px@2x.png diff --git a/src/imports/components/qmldir b/src/imports/components/qmldir index 6893f0d..38c358b 100644 --- a/src/imports/components/qmldir +++ b/src/imports/components/qmldir @@ -4,6 +4,7 @@ TriangleItem 1.0 TriangleItem.qml SvgPathItem 1.0 SvgPathItem.qml FlipableItem 1.0 FlipableItem.qml RectangleItem 1.0 RectangleItem.qml +RegularPolygonItem 1.0 RegularPolygonItem.qml BorderItem 1.0 BorderItem.qml IsoItem 1.0 IsoItem.qml GroupItem 1.0 GroupItem.qml |