diff options
author | Mitch Curtis <mitch.curtis@theqtcompany.com> | 2015-02-12 13:55:22 +0100 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-02-13 12:01:33 +0000 |
commit | 6f15c206b069ed0fcf48a285bfcc4ad636927df0 (patch) | |
tree | 6150e262bc2d049219981a4cb1e1deeeeed5d636 /src/extras/Styles/Base/CircularGaugeStyle.qml | |
parent | d28a02aec9a1632f2263d9276099454b33fb6741 (diff) | |
download | qtquickcontrols-6f15c206b069ed0fcf48a285bfcc4ad636927df0.tar.gz |
Import Qt Quick Extras (the former Qt Quick Enterprise Controls)
Change-Id: I59c5c97c564f707da4ce617e25e13ff8124f7d4b
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'src/extras/Styles/Base/CircularGaugeStyle.qml')
-rw-r--r-- | src/extras/Styles/Base/CircularGaugeStyle.qml | 498 |
1 files changed, 498 insertions, 0 deletions
diff --git a/src/extras/Styles/Base/CircularGaugeStyle.qml b/src/extras/Styles/Base/CircularGaugeStyle.qml new file mode 100644 index 00000000..2030f775 --- /dev/null +++ b/src/extras/Styles/Base/CircularGaugeStyle.qml @@ -0,0 +1,498 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Extras module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtGraphicalEffects 1.0 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Private 1.0 +import QtQuick.Extras 1.3 +import QtQuick.Extras.Styles 1.3 +import QtQuick.Extras.Private 1.0 + +/*! + \qmltype CircularGaugeStyle + \inqmlmodule QtQuick.Extras.Styles + \since QtQuick.Extras.Styles 1.0 + \ingroup extrasstyles + \brief Provides custom styling for CircularGauge. + + You can create a custom circular gauge by replacing the following delegates: + \list + \li \l background + \li \l tickmark + \li \l minorTickmark + \li \l tickmarkLabel + \li \l needle + \li \l foreground + \endlist + + Below is an example that changes the needle to a basic orange \l Rectangle: + \code + CircularGauge { + style: CircularGaugeStyle { + needle: Rectangle { + y: outerRadius * 0.15 + implicitWidth: outerRadius * 0.03 + implicitHeight: outerRadius * 0.9 + antialiasing: true + color: Qt.rgba(0.66, 0.3, 0, 1) + } + } + } + \endcode + + The result: + \image circulargauge-needle-example-2.png CircularGaugeStyle example + + \section2 Direction + + \l minimumValueAngle and \l maximumValueAngle determine not only the + position of the tickmarks, labels and needle, but the direction in which + they are displayed around the gauge. For example, if \l minimumValueAngle + is greater than \l maximumValueAngle, the gauge will be anti-clockwise. + Below, there are two gauges: the top gauge has a \l minimumValueAngle of + \c -90 degrees and a \l maximumValueAngle of \c 90 degrees, and the bottom + gauge has the opposite. + + \image circulargauge-reversed.png Reversed CircularGauge + + \sa {Styling CircularGauge} +*/ + +Style { + id: circularGaugeStyle + + /*! + \since 1.3 + + The \l CircularGauge that this style is attached to. + */ + readonly property CircularGauge control: __control + + /*! + The distance from the center of the gauge to the outer edge of the + gauge. + + This property is useful for determining the size of the various + components of the style, in order to ensure that they are scaled + proportionately when the gauge is resized. + */ + readonly property real outerRadius: Math.min(control.width, control.height) * 0.5 + + /*! + This property determines the angle at which the minimum value is + displayed on the gauge. + + The angle set affects the following components of the gauge: + \list + \li The angle of the needle + \li The position of the tickmarks and labels + \endlist + + The angle origin points north: + + \image circulargauge-angles.png + + There is no minimum or maximum angle for this property, but the default + style only supports angles whose absolute range is less than or equal + to \c 360 degrees. This is because ranges higher than \c 360 degrees + will cause the tickmarks and labels to overlap each other. + + The default value is \c -145. + */ + property real minimumValueAngle: -145 + + /*! + This property determines the angle at which the maximum value is + displayed on the gauge. + + The angle set affects the following components of the gauge: + \list + \li The angle of the needle + \li The position of the tickmarks and labels + \endlist + + The angle origin points north: + + \image circulargauge-angles.png + + There is no minimum or maximum angle for this property, but the default + style only supports angles whose absolute range is less than or equal + to \c 360 degrees. This is because ranges higher than \c 360 degrees + will cause the tickmarks and labels to overlap each other. + + The default value is \c 145. + */ + property real maximumValueAngle: 145 + + /*! + The range between \l minimumValueAngle and \l maximumValueAngle, in + degrees. This value will always be positive. + */ + readonly property real angleRange: control.__panel.circularTickmarkLabel.angleRange + + /*! + This property holds the rotation of the needle in degrees. + */ + property real needleRotation: { + var percentage = (control.value - control.minimumValue) / (control.maximumValue - control.minimumValue); + minimumValueAngle + percentage * angleRange; + } + + /*! + The interval at which tickmarks are displayed. + + For example, if this property is set to \c 10 (the default), + control.minimumValue to \c 0, and control.maximumValue to \c 100, + the tickmarks displayed will be 0, 10, 20, etc., to 100, + around the gauge. + */ + property real tickmarkStepSize: 10 + + /*! + The distance in pixels from the outside of the gauge (outerRadius) at + which the outermost point of the tickmark line is drawn. + */ + property real tickmarkInset: 0 + + + /*! + The amount of tickmarks displayed by the gauge, calculated from + \l tickmarkStepSize and the control's + \l {CircularGauge::minimumValue}{minimumValue} and + \l {CircularGauge::maximumValue}{maximumValue}. + + \sa minorTickmarkCount + */ + readonly property int tickmarkCount: control.__panel.circularTickmarkLabel.tickmarkCount + + /*! + The amount of minor tickmarks between each tickmark. + + The default value is \c 4. + + \sa tickmarkCount + */ + property int minorTickmarkCount: 4 + + /*! + The distance in pixels from the outside of the gauge (outerRadius) at + which the outermost point of the minor tickmark line is drawn. + */ + property real minorTickmarkInset: 0 + + /*! + The distance in pixels from the outside of the gauge (outerRadius) at + which the center of the value marker text is drawn. + */ + property real labelInset: __protectedScope.toPixels(0.19) + + /*! + The interval at which tickmark labels are displayed. + + For example, if this property is set to \c 10 (the default), + control.minimumValue to \c 0, and control.maximumValue to \c 100, the + tickmark labels displayed will be 0, 10, 20, etc., to 100, + around the gauge. + */ + property real labelStepSize: tickmarkStepSize + + /*! + The amount of tickmark labels displayed by the gauge, calculated from + \l labelStepSize and the control's + \l {CircularGauge::minimumValue}{minimumValue} and + \l {CircularGauge::maximumValue}{maximumValue}. + + \sa tickmarkCount, minorTickmarkCount + */ + readonly property int labelCount: control.__panel.circularTickmarkLabel.labelCount + + /*! + \since QtQuick.Extras 1.2 + + Returns \a value as an angle in degrees. + + This function is useful for custom drawing or positioning of items in + the style's components. For example, it can be used to calculate the + angles at which to draw an arc around the gauge indicating the safe + area for the needle to be within. + + For example, if minimumValueAngle is set to \c 270 and + maximumValueAngle is set to \c 90, this function will return \c 270 + when passed minimumValue and \c 90 when passed maximumValue. + + \sa {Styling CircularGauge#styling-circulargauge-background}{ + Styling CircularGauge's background} + */ + function valueToAngle(value) { + return control.__panel.circularTickmarkLabel.valueToAngle(value); + } + + property QtObject __protectedScope: QtObject { + /*! + Converts a value expressed as a percentage of \l outerRadius to + a pixel value. + */ + function toPixels(percentageOfOuterRadius) { + return percentageOfOuterRadius * outerRadius; + } + } + + /*! + The background of the gauge. + + If set, the background determines the implicit size of the gauge. + + By default, there is no background defined. + + \sa {Styling CircularGauge#styling-circulargauge-background}{ + Styling CircularGauge's background} + */ + property Component background + + /*! + This component defines each individual tickmark. The position of each + tickmark is already set; only the + \l {Item::implicitWidth}{implicitWidth} and + \l {Item::implicitHeight}{implicitHeight} need to be specified. + + Each instance of this component has access to the following properties: + + \table + \row \li \c {readonly property int} \b styleData.index + \li The index of this tickmark. + \row \li \c {readonly property real} \b styleData.value + \li The value that this tickmark represents. + \endtable + + To illustrate what these properties refer to, we can use the following + example: + + \snippet circulargauge-tickmark-indices-values.qml tickmarks + + We've replaced the conventional \e line tickmarks with \l Text items + and have hidden the tickmarkLabel component in order to make the + association clearer: + + \image circulargauge-tickmark-indices-values.png Tickmarks + + The index property can be useful if you have another model that + contains images to display for each index, for example. + + The value property is useful for drawing lower and upper limits around + the gauge to indicate the recommended value ranges. For example, speeds + above 200 kilometers an hour in a car's speedometer could be indicated + as dangerous using this property. + + \sa {Styling CircularGauge#styling-circulargauge-tickmark}{ + Styling CircularGauge's tickmark} + */ + property Component tickmark: Rectangle { + implicitWidth: outerRadius * 0.02 + antialiasing: true + implicitHeight: outerRadius * 0.06 + color: "#c8c8c8" + } + + /*! + This component defines each individual minor tickmark. The position of + each minor tickmark is already set; only the + \l {Item::implicitWidth}{implicitWidth} and + \l {Item::implicitHeight}{implicitHeight} need to be specified. + + Each instance of this component has access to the following properties: + + \table + \row \li \c {readonly property int} \b styleData.index + \li The index of this tickmark. + \row \li \c {readonly property real} \b styleData.value + \li The value that this tickmark represents. + \endtable + + \sa {Styling CircularGauge#styling-circulargauge-minorTickmark}{ + Styling CircularGauge's minorTickmark} + */ + property Component minorTickmark: Rectangle { + implicitWidth: outerRadius * 0.01 + antialiasing: true + implicitHeight: outerRadius * 0.03 + color: "#c8c8c8" + } + + /*! + This defines the text of each tickmark label on the gauge. + + Each instance of this component has access to the following properties: + + \table + \row \li \c {readonly property int} \b styleData.index + \li The index of this label. + \row \li \c {readonly property real} \b styleData.value + \li The value that this label represents. + \endtable + + \sa {Styling CircularGauge#styling-circulargauge-tickmarkLabel}{ + Styling CircularGauge's tickmarkLabel} + */ + property Component tickmarkLabel: Text { + font.pixelSize: Math.max(6, __protectedScope.toPixels(0.12)) + text: styleData.value + color: "#c8c8c8" + antialiasing: true + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + /*! + The needle that points to the gauge's current value. + + This component is drawn below the \l foreground component. + + The style expects the needle to be pointing up at a rotation of \c 0, + in order for the rotation to be correct. For example: + + \image circulargauge-needle.png CircularGauge's needle + + When defining your own needle component, the only properties that the + style requires you to set are the + \l {Item::implicitWidth}{implicitWidth} and + \l {Item::implicitHeight}{implicitHeight}. + + Optionally, you can set \l {Item::x}{x} and \l {Item::y}{y} to change + the needle's transform origin. Setting the \c x position can be useful + for needle images where the needle is not centered exactly + horizontally. Setting the \c y position allows you to make the base of + the needle hang over the center of the gauge. + + \sa {Styling CircularGauge#styling-circulargauge-needle}{ + Styling CircularGauge's needle} + */ + property Component needle: Item { + implicitWidth: __protectedScope.toPixels(0.08) + implicitHeight: 0.9 * outerRadius + + Image { + anchors.fill: parent + source: "images/needle.png" + } + } + + /*! + The foreground of the gauge. This component is drawn above all others. + + Like \l background, the foreground component fills the entire gauge. + + By default, the knob of the gauge is defined here. + + \sa {Styling CircularGauge#styling-circulargauge-foreground}{ + Styling CircularGauge's foreground} + */ + property Component foreground: Item { + Image { + source: "images/knob.png" + anchors.centerIn: parent + scale: { + var idealHeight = __protectedScope.toPixels(0.2); + var originalImageHeight = sourceSize.height; + idealHeight / originalImageHeight; + } + } + } + + /*! \internal */ + property Component panel: Item { + id: panelItem + implicitWidth: backgroundLoader.item ? backgroundLoader.implicitWidth : TextSingleton.implicitHeight * 16 + implicitHeight: backgroundLoader.item ? backgroundLoader.implicitHeight : TextSingleton.implicitHeight * 16 + + property alias background: backgroundLoader.item + property alias circularTickmarkLabel: circularTickmarkLabel_ + + Loader { + id: backgroundLoader + sourceComponent: circularGaugeStyle.background + width: outerRadius * 2 + height: outerRadius * 2 + anchors.centerIn: parent + } + + CircularTickmarkLabel { + id: circularTickmarkLabel_ + anchors.fill: backgroundLoader + + minimumValue: control.minimumValue + maximumValue: control.maximumValue + stepSize: control.stepSize + tickmarksVisible: control.tickmarksVisible + minimumValueAngle: circularGaugeStyle.minimumValueAngle + maximumValueAngle: circularGaugeStyle.maximumValueAngle + tickmarkStepSize: circularGaugeStyle.tickmarkStepSize + tickmarkInset: circularGaugeStyle.tickmarkInset + minorTickmarkCount: circularGaugeStyle.minorTickmarkCount + minorTickmarkInset: circularGaugeStyle.minorTickmarkInset + labelInset: circularGaugeStyle.labelInset + labelStepSize: circularGaugeStyle.labelStepSize + + style: CircularTickmarkLabelStyle { + tickmark: circularGaugeStyle.tickmark + minorTickmark: circularGaugeStyle.minorTickmark + tickmarkLabel: circularGaugeStyle.tickmarkLabel + } + } + + Loader { + id: needleLoader + sourceComponent: circularGaugeStyle.needle + transform: [ + Rotation { + angle: needleRotation + origin.x: needleLoader.width / 2 + origin.y: needleLoader.height + }, + Translate { + x: panelItem.width / 2 - needleLoader.width / 2 + y: panelItem.height / 2 - needleLoader.height + } + ] + } + + Loader { + id: foreground + sourceComponent: circularGaugeStyle.foreground + anchors.fill: backgroundLoader + } + } +} |