aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Gruendl <henning.gruendl@qt.io>2021-09-25 13:05:32 +0200
committerHenning Gruendl <henning.gruendl@qt.io>2021-11-24 12:40:42 +0200
commit3546c4e90b931b3add0b670f753b3c8c9b32b9e2 (patch)
treefc0635ff66754deea93245ac1455f00eebc882f1
parent7769943788ba38cb729a25cff24d503c70acefe3 (diff)
Components: Add RegularPolygonItem
* Add item library images * Add new RegularPolygonItem Task-number: QDS-5143 Change-Id: I34e8a6359cde2b1fc76557521df41ddb2700146c Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--src/imports/components/RegularPolygonItem.qml318
-rw-r--r--src/imports/components/components.pri1
-rw-r--r--src/imports/components/designer/RegularPolygonItemSpecifics.qml151
-rw-r--r--src/imports/components/designer/components.metainfo32
-rw-r--r--src/imports/components/designer/designer.pri4
-rw-r--r--src/imports/components/designer/images/polygon-16px.pngbin0 -> 320 bytes
-rw-r--r--src/imports/components/designer/images/polygon-24px.pngbin0 -> 460 bytes
-rw-r--r--src/imports/components/designer/images/polygon-24px@2x.pngbin0 -> 848 bytes
-rw-r--r--src/imports/components/qmldir1
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
new file mode 100644
index 0000000..b56c7bb
--- /dev/null
+++ b/src/imports/components/designer/images/polygon-16px.png
Binary files differ
diff --git a/src/imports/components/designer/images/polygon-24px.png b/src/imports/components/designer/images/polygon-24px.png
new file mode 100644
index 0000000..51209ec
--- /dev/null
+++ b/src/imports/components/designer/images/polygon-24px.png
Binary files differ
diff --git a/src/imports/components/designer/images/polygon-24px@2x.png b/src/imports/components/designer/images/polygon-24px@2x.png
new file mode 100644
index 0000000..a400ec6
--- /dev/null
+++ b/src/imports/components/designer/images/polygon-24px@2x.png
Binary files differ
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