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/Private | |
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/Private')
-rw-r--r-- | src/extras/Private/CircularButton.qml | 49 | ||||
-rw-r--r-- | src/extras/Private/CircularButtonStyleHelper.qml | 133 | ||||
-rw-r--r-- | src/extras/Private/CircularTickmarkLabel.qml | 142 | ||||
-rw-r--r-- | src/extras/Private/Handle.qml | 120 | ||||
-rw-r--r-- | src/extras/Private/PieMenuIcon.qml | 99 | ||||
-rw-r--r-- | src/extras/Private/TextSingleton.qml | 41 | ||||
-rw-r--r-- | src/extras/Private/private.pri | 24 | ||||
-rw-r--r-- | src/extras/Private/qmldir | 1 | ||||
-rw-r--r-- | src/extras/Private/qquickcircularprogressbar.cpp | 209 | ||||
-rw-r--r-- | src/extras/Private/qquickcircularprogressbar_p.h | 99 | ||||
-rw-r--r-- | src/extras/Private/qquickflatprogressbar.cpp | 202 | ||||
-rw-r--r-- | src/extras/Private/qquickflatprogressbar_p.h | 88 | ||||
-rw-r--r-- | src/extras/Private/qquickmathutils.cpp | 111 | ||||
-rw-r--r-- | src/extras/Private/qquickmathutils_p.h | 61 | ||||
-rw-r--r-- | src/extras/Private/qquickmousethief.cpp | 208 | ||||
-rw-r--r-- | src/extras/Private/qquickmousethief_p.h | 86 | ||||
-rw-r--r-- | src/extras/Private/qquickstylesettings.cpp | 157 | ||||
-rw-r--r-- | src/extras/Private/qquickstylesettings_p.h | 79 |
18 files changed, 1909 insertions, 0 deletions
diff --git a/src/extras/Private/CircularButton.qml b/src/extras/Private/CircularButton.qml new file mode 100644 index 00000000..b2baf5a2 --- /dev/null +++ b/src/extras/Private/CircularButton.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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 QtQuick.Controls 1.1 +import QtQuick.Extras 1.3 +import QtQuick.Extras.Private 1.0 +import QtQuick.Extras.Styles 1.3 + +/*! + \internal +*/ +Button { + id: button + style: Qt.createComponent(StyleSettings.style + "/CircularButtonStyle.qml", button) +} diff --git a/src/extras/Private/CircularButtonStyleHelper.qml b/src/extras/Private/CircularButtonStyleHelper.qml new file mode 100644 index 00000000..fedd3a37 --- /dev/null +++ b/src/extras/Private/CircularButtonStyleHelper.qml @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** 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 QtQuick.Extras 1.3 +import QtQuick.Extras.Private 1.0 + +QtObject { + id: circularButtonStyleHelper + + property Item control + + property color buttonColorUpTop: "#e3e3e3" + property color buttonColorUpBottom: "#b3b3b3" + property color buttonColorDownTop: "#d3d3d3" + property color buttonColorDownBottom: "#939393" + property color outerArcColorTop: "#9c9c9c" + property color outerArcColorBottom: Qt.rgba(0.941, 0.941, 0.941, 0.29) + property color innerArcColorTop: "#e3e3e3" + property color innerArcColorBottom: "#acacac" + property real innerArcColorBottomStop: 0.4 + property color shineColor: Qt.rgba(1, 1, 1, 0.29) + property real smallestAxis: control ? Math.min(control.width, control.height) : 0 + property real outerArcLineWidth: smallestAxis * 0.04 + property real innerArcLineWidth: Math.max(1, outerArcLineWidth * 0.1) + property real shineArcLineWidth: Math.max(1, outerArcLineWidth * 0.1) + property real implicitWidth: Math.round(TextSingleton.implicitHeight * 8) + property real implicitHeight: Math.round(TextSingleton.implicitHeight * 8) + + property color textColorUp: "#4e4e4e" + property color textColorDown: "#303030" + property color textRaisedColorUp: "#ffffff" + property color textRaisedColorDown: "#e3e3e3" + + property real radius: (smallestAxis * 0.5) - outerArcLineWidth - innerArcLineWidth + property real halfRadius: radius / 2 + property real outerArcRadius: innerArcRadius + outerArcLineWidth / 2 + property real innerArcRadius: radius + innerArcLineWidth / 2 + property real shineArcRadius: outerArcRadius + outerArcLineWidth / 2 - shineArcLineWidth / 2 + property real zeroAngle: Math.PI * 0.5 + + property color buttonColorTop: control && control.pressed ? buttonColorDownTop : buttonColorUpTop + property color buttonColorBottom: control && control.pressed ? buttonColorDownBottom : buttonColorUpBottom + + function toPixels(percentageOfSmallestAxis) { + return percentageOfSmallestAxis * smallestAxis; + } + + function paintBackground(ctx) { + ctx.reset(); + + if (outerArcRadius < 0 || radius < 0) + return; + + var xCenter = ctx.canvas.width / 2; + var yCenter = ctx.canvas.height / 2; + + /* Draw outer arc */ + ctx.beginPath(); + ctx.lineWidth = outerArcLineWidth; + ctx.arc(xCenter, yCenter, outerArcRadius, 0, Math.PI * 2, false); + var gradient = ctx.createRadialGradient(xCenter, yCenter - halfRadius, + halfRadius, xCenter, yCenter - halfRadius, radius); + gradient.addColorStop(0, outerArcColorTop); + gradient.addColorStop(1, outerArcColorBottom); + ctx.strokeStyle = gradient; + ctx.stroke(); + + /* Draw the shine along the bottom */ + ctx.beginPath(); + ctx.lineWidth = shineArcLineWidth; + ctx.arc(xCenter, yCenter, shineArcRadius, 0, Math.PI, false); + gradient = ctx.createLinearGradient(xCenter, yCenter + radius, xCenter, yCenter); + gradient.addColorStop(0, shineColor); + gradient.addColorStop(0.5, "rgba(255, 255, 255, 0)"); + ctx.strokeStyle = gradient; + ctx.stroke(); + + /* Draw inner arc */ + ctx.beginPath(); + ctx.lineWidth = innerArcLineWidth + 1; + ctx.arc(xCenter, yCenter, innerArcRadius, 0, Math.PI * 2, false); + gradient = ctx.createLinearGradient(xCenter, yCenter - halfRadius, + xCenter, yCenter + halfRadius); + gradient.addColorStop(0, innerArcColorTop); + gradient.addColorStop(innerArcColorBottomStop, innerArcColorBottom); + ctx.strokeStyle = gradient; + ctx.stroke(); + + /* Draw the button's body */ + ctx.beginPath(); + ctx.ellipse(xCenter - radius, yCenter - radius, radius * 2, radius * 2); + gradient = ctx.createRadialGradient(xCenter, yCenter + radius * 0.85, radius, + xCenter, yCenter + radius * 0.85, radius * 0.85); + gradient.addColorStop(1, buttonColorTop); + gradient.addColorStop(0, buttonColorBottom); + ctx.fillStyle = gradient; + ctx.fill(); + } +} diff --git a/src/extras/Private/CircularTickmarkLabel.qml b/src/extras/Private/CircularTickmarkLabel.qml new file mode 100644 index 00000000..05554878 --- /dev/null +++ b/src/extras/Private/CircularTickmarkLabel.qml @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** 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 +// Workaround for QTBUG-37751; we need this import for RangeModel, although we shouldn't. +import QtQuick.Controls 1.1 +import QtQuick.Controls.Private 1.0 +import QtQuick.Extras 1.3 +import QtQuick.Extras.Private 1.0 + +Control { + id: label + style: Qt.createComponent(StyleSettings.style + "/CircularTickmarkLabelStyle.qml", label) + + property alias minimumValue: range.minimumValue + + property alias maximumValue: range.maximumValue + + property alias stepSize: range.stepSize + + RangeModel { + id: range + minimumValue: 0 + maximumValue: 100 + stepSize: 0 + // Not used. + value: minimumValue + } + + /*! + This property determines the angle at which the first tickmark is drawn. + */ + property real minimumValueAngle: -145 + + /*! + This property determines the angle at which the last tickmark is drawn. + */ + property real maximumValueAngle: 145 + + /*! + The range between \l minimumValueAngle and \l maximumValueAngle, in + degrees. + */ + readonly property real angleRange: maximumValueAngle - minimumValueAngle + + /*! + The interval at which tickmarks are displayed. + */ + property real tickmarkStepSize: 10 + + /*! + The distance in pixels from the outside of the control (outerRadius) at + which the outermost point of the tickmark line is drawn. + */ + property real tickmarkInset: 0.0 + + /*! + The amount of tickmarks displayed. + */ + readonly property int tickmarkCount: __tickmarkCount + + /*! + The amount of minor tickmarks between each tickmark. + */ + property int minorTickmarkCount: 4 + + /*! + The distance in pixels from the outside of the control (outerRadius) at + which the outermost point of the minor tickmark line is drawn. + */ + property real minorTickmarkInset: 0.0 + + /*! + The distance in pixels from the outside of the control (outerRadius) at + which the center of the value marker text is drawn. + */ + property real labelInset: __style.__protectedScope.toPixels(0.19) + + /*! + The interval at which tickmark labels are displayed. + */ + property real labelStepSize: tickmarkStepSize + + /*! + The amount of tickmark labels displayed. + */ + readonly property int labelCount: (maximumValue - minimumValue) / labelStepSize + 1 + + /*! \internal */ + readonly property real __tickmarkCount: tickmarkStepSize > 0 ? (maximumValue - minimumValue) / tickmarkStepSize + 1 : 0 + + /*! + This property determines whether or not the control displays tickmarks, + minor tickmarks, and labels. + */ + property bool tickmarksVisible: true + + /*! + Returns \a value as an angle in degrees. + + 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. + */ + function valueToAngle(value) { + var normalised = (value - minimumValue) / (maximumValue - minimumValue); + return (maximumValueAngle - minimumValueAngle) * normalised + minimumValueAngle; + } +} diff --git a/src/extras/Private/Handle.qml b/src/extras/Private/Handle.qml new file mode 100644 index 00000000..12e2804d --- /dev/null +++ b/src/extras/Private/Handle.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** 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.0 +import QtGraphicalEffects 1.0 +import QtQuick.Controls.Private 1.0 +import QtQuick.Extras.Styles 1.3 +import QtQuick.Extras.Private 1.1 +import QtQuick.Extras.Private.CppUtils 1.0 + +Control { + id: root + x: handleArea.centerOfHandle.x - width / 2 + y: handleArea.centerOfHandle.y - height / 2 + + style: Qt.createComponent(StyleSettings.style + "/HandleStyle.qml", root) + + /*! + The angle of the handle along the circumference of \l rotationRadius in + radians, scaled to be in the range of 0.0 to 1.0. + */ + property alias value: range.value + + RangeModel { + id: range + minimumValue: 0.0 + maximumValue: 1.0 + stepSize: 0 + value: minimumValue + } + + /*! + The angle in radians where the dial starts. + */ + property real zeroAngle: 0 + + /*! + The radius of the rotation of this handle. + */ + property real rotationRadius: 50 + + /*! + The center of the dial. This is the origin point for the handle's + rotation. + */ + property real dialXCenter: 0 + property real dialYCenter: 0 + + /*! + This property holds the amount of extra room added to each side of + the handle to make it easier to drag on touch devices. + */ + property real allowance: Math.max(width, height) * 1.5 + + /* + The function used to determine the handle's value from the position of + the mouse. + + Can be set to provide custom value calculation. It expects these + parameters: \c mouseX, \c mouseY, \c xCenter, \c yCenter, \c zeroAngle + */ + property var valueFromMouse: handleArea.valueFromMouse + + property alias handleArea: handleArea + + MouseArea { + id: handleArea + // Respond to value changes by calculating the new center of the handle. + property point centerOfHandle: MathUtils.centerAlongCircle(dialXCenter, dialYCenter, + 0, 0, MathUtils.valueToAngle(value, 1, zeroAngle), rotationRadius); + + anchors.fill: parent + anchors.margins: -allowance + + onPositionChanged: { + // Whenever the handle is moved with the mouse, update the value. + value = root.valueFromMouse(mouse.x + centerOfHandle.x - allowance, + mouse.y + centerOfHandle.y - allowance, dialXCenter, dialYCenter, zeroAngle); + } + + // A helper function for onPositionChanged. + function valueFromMouse(mouseX, mouseY, xCenter, yCenter, zeroAngle) { + return MathUtils.angleToValue( + MathUtils.halfPi - Math.atan2(mouseX - xCenter, mouseY - yCenter), 1, zeroAngle); + } + } +} diff --git a/src/extras/Private/PieMenuIcon.qml b/src/extras/Private/PieMenuIcon.qml new file mode 100644 index 00000000..f54e035f --- /dev/null +++ b/src/extras/Private/PieMenuIcon.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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.3 +import QtQuick.Extras 1.3 +import QtQuick.Extras.Private 1.0 +import QtQuick.Extras.Private.CppUtils 1.0 + +Loader { + id: iconLoader + active: iconSource != "" + + property PieMenu control: null + property QtObject styleData: null + + readonly property string iconSource: styleData && styleData.index < control.__protectedScope.visibleItems.length + ? control.__protectedScope.visibleItems[styleData.index].iconSource + : "" + + sourceComponent: Image { + id: iconImage + source: iconSource + x: pos.x + y: pos.y + scale: scaleFactor + + readonly property point pos: MathUtils.centerAlongCircle( + iconLoader.parent.width / 2, iconLoader.parent.height / 2, width, height, + MathUtils.degToRadOffset(sectionCenterAngle(styleData.index)), control.__style.__iconOffset) + + /* + The icons should scale with the menu at some point, so that they + stay within the bounds of each section. We down-scale the image by + whichever of the following amounts are larger: + + a) The amount by which the largest dimension's diagonal size exceeds + the "selectable" radius. The selectable radius is the distance in pixels + between lines A and B in the incredibly visually appealing image below: + + __________ + - B - + / \ + / ____ \ + | / A \ | + --------| |-------- + + b) The amount by which the diagonal exceeds the circumference of + one section. + */ + readonly property real scaleFactor: { + var largestDimension = Math.max(iconImage.sourceSize.width, iconImage.sourceSize.height) * Math.sqrt(2); + // TODO: add padding + var radiusDifference = largestDimension - control.__style.__selectableRadius; + var circumferenceDifference = largestDimension - Math.abs(control.__protectedScope.circumferenceOfSection); + if (circumferenceDifference > 0 || radiusDifference > 0) { + // We need to down-scale. + if (radiusDifference > circumferenceDifference) { + return control.__style.__selectableRadius / largestDimension; + } else { + return Math.abs(control.__protectedScope.circumferenceOfSection) / largestDimension; + } + } + return 1; + } + } +} diff --git a/src/extras/Private/TextSingleton.qml b/src/extras/Private/TextSingleton.qml new file mode 100644 index 00000000..6e51c66f --- /dev/null +++ b/src/extras/Private/TextSingleton.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +pragma Singleton +import QtQuick 2.1 + +Text { +} diff --git a/src/extras/Private/private.pri b/src/extras/Private/private.pri new file mode 100644 index 00000000..4f394412 --- /dev/null +++ b/src/extras/Private/private.pri @@ -0,0 +1,24 @@ +QT += gui quick + +HEADERS += \ + $$PWD/qquickcircularprogressbar_p.h \ + $$PWD/qquickflatprogressbar_p.h \ + $$PWD/qquickmousethief_p.h \ + $$PWD/qquickstylesettings_p.h \ + $$PWD/qquickmathutils_p.h + +SOURCES += \ + $$PWD/qquickcircularprogressbar.cpp \ + $$PWD/qquickflatprogressbar.cpp \ + $$PWD/qquickmousethief.cpp \ + $$PWD/qquickstylesettings.cpp \ + $$PWD/qquickmathutils.cpp + +OTHER_FILES += \ + $$PWD/qmldir \ + $$PWD/CircularButton.qml \ + $$PWD/CircularButtonStyleHelper.qml \ + $$PWD/CircularTickmarkLabel.qml \ + $$PWD/Handle.qml \ + $$PWD/PieMenuIcon.qml \ + $$PWD/TextSingleton.qml diff --git a/src/extras/Private/qmldir b/src/extras/Private/qmldir new file mode 100644 index 00000000..3b115bba --- /dev/null +++ b/src/extras/Private/qmldir @@ -0,0 +1 @@ +module QtQuick.Extras.Private diff --git a/src/extras/Private/qquickcircularprogressbar.cpp b/src/extras/Private/qquickcircularprogressbar.cpp new file mode 100644 index 00000000..5bdab7d3 --- /dev/null +++ b/src/extras/Private/qquickcircularprogressbar.cpp @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qquickcircularprogressbar_p.h" + +#include <QtGui/QPen> +#include <QtGui/QPainter> +#include <QtMath> + +QQuickCircularProgressBar::QQuickCircularProgressBar(QQuickItem *parent) : + QQuickPaintedItem(parent), + mProgress(0), + mBarWidth(1), + mInset(0), + mBackgroundColor(QColor(Qt::transparent)), + mMinimumValueAngle(-90 * 16), + mMaximumValueAngle(-450 * 16) +{ + setFlag(ItemHasContents, true); +} + +QQuickCircularProgressBar::~QQuickCircularProgressBar() +{ +} + +void QQuickCircularProgressBar::paint(QPainter *painter) +{ + QPen pen(Qt::red); + pen.setWidthF(mBarWidth); + + const QRectF bounds = boundingRect(); + const qreal smallest = qMin(bounds.width(), bounds.height()); + QRectF rect = QRectF(pen.widthF() / 2.0, pen.widthF() / 2.0, smallest - pen.widthF(), smallest - pen.widthF()); + rect.adjust(mInset, mInset, -mInset, -mInset); + + // Make sure the arc is aligned to whole pixels. + if (rect.x() - int(rect.x()) > 0) { + rect.setX(qCeil(rect.x())); + } + if (rect.y() - int(rect.y()) > 0) { + rect.setY(qCeil(rect.y())); + } + if (rect.width() - int(rect.width()) > 0) { + rect.setWidth(qFloor(rect.width())); + } + if (rect.height() - int(rect.height()) > 0) { + rect.setHeight(qFloor(rect.height())); + } + + painter->setRenderHint(QPainter::Antialiasing); + + // QPainter::drawArc uses positive values for counter clockwise - the opposite of our API - + // so we must reverse the angles with * -1. Also, our angle origin is at 12 o'clock, whereas + // QPainter's is 3 o'clock, hence - 90. + const qreal startAngle = ((mMinimumValueAngle - 90) * -1) * 16; + if (mBackgroundColor != Qt::transparent) { + QBrush bgBrush(mBackgroundColor); + QPen bgPen; + bgPen.setWidthF(mBarWidth); + bgPen.setBrush(bgBrush); + painter->setPen(bgPen); + painter->drawArc(rect, startAngle, (((mMaximumValueAngle - 90) * -1 * 16) - startAngle)); + } + + QLinearGradient gradient; + gradient.setStart(bounds.width() / 2, mInset); + gradient.setFinalStop(bounds.width() / 2, bounds.height() - mInset); + gradient.setStops(mGradientStops); + + QBrush brush(gradient); + pen.setBrush(brush); + + painter->setPen(pen); + + const qreal spanAngle = progress() * (((mMaximumValueAngle - 90) * -1 * 16) - startAngle); + painter->drawArc(rect, startAngle, spanAngle); +} + +qreal QQuickCircularProgressBar::progress() const +{ + return mProgress; +} + +void QQuickCircularProgressBar::setProgress(qreal progress) +{ + if (mProgress != progress) { + mProgress = progress; + emit progressChanged(mProgress); + update(); + } +} + +qreal QQuickCircularProgressBar::barWidth() const +{ + return mBarWidth; +} + +void QQuickCircularProgressBar::setBarWidth(qreal barWidth) +{ + if (mBarWidth != barWidth) { + mBarWidth = barWidth; + emit barWidthChanged(mBarWidth); + update(); + } +} + +qreal QQuickCircularProgressBar::inset() const +{ + return mInset; +} + +void QQuickCircularProgressBar::setInset(qreal inset) +{ + if (mInset != inset) { + mInset = inset; + emit insetChanged(mInset); + update(); + } +} + +qreal QQuickCircularProgressBar::minimumValueAngle() const +{ + return mMinimumValueAngle; +} + +void QQuickCircularProgressBar::setMinimumValueAngle(qreal minimumValueAngle) +{ + if (mMinimumValueAngle != minimumValueAngle) { + mMinimumValueAngle = minimumValueAngle; + emit minimumValueAngleChanged(mMinimumValueAngle); + update(); + } +} + +qreal QQuickCircularProgressBar::maximumValueAngle() const +{ + return mMinimumValueAngle; +} + +void QQuickCircularProgressBar::setMaximumValueAngle(qreal maximumValueAngle) +{ + if (mMaximumValueAngle != maximumValueAngle) { + mMaximumValueAngle = maximumValueAngle; + emit maximumValueAngleChanged(mMaximumValueAngle); + update(); + } +} + +void QQuickCircularProgressBar::clearStops() +{ + mGradientStops.clear(); +} + +void QQuickCircularProgressBar::addStop(qreal position, const QColor &color) +{ + mGradientStops.append(QGradientStop(position, color)); +} + +void QQuickCircularProgressBar::redraw() +{ + update(); +} + +QColor QQuickCircularProgressBar::backgroundColor() const +{ + return mBackgroundColor; +} + +void QQuickCircularProgressBar::setBackgroundColor(const QColor &backgroundColor) +{ + if (mBackgroundColor != backgroundColor) { + mBackgroundColor = backgroundColor; + emit backgroundColorChanged(backgroundColor); + update(); + } +} diff --git a/src/extras/Private/qquickcircularprogressbar_p.h b/src/extras/Private/qquickcircularprogressbar_p.h new file mode 100644 index 00000000..7e9be6ee --- /dev/null +++ b/src/extras/Private/qquickcircularprogressbar_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef CIRCULARPROGRESSBAR_P_H +#define CIRCULARPROGRESSBAR_P_H + +#include <QtGui/QColor> +#include <QtGui/QGradientStops> +#include <QtQuick/QQuickPaintedItem> + +class QQuickCircularProgressBar : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged) + Q_PROPERTY(qreal barWidth READ barWidth WRITE setBarWidth NOTIFY barWidthChanged) + Q_PROPERTY(qreal inset READ inset WRITE setInset NOTIFY insetChanged) + Q_PROPERTY(qreal minimumValueAngle READ minimumValueAngle WRITE setMinimumValueAngle NOTIFY minimumValueAngleChanged) + Q_PROPERTY(qreal maximumValueAngle READ maximumValueAngle WRITE setMaximumValueAngle NOTIFY maximumValueAngleChanged) + // For Flat DialStyle, so that we don't need to create two progress bars + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged) + +public: + QQuickCircularProgressBar(QQuickItem *parent = 0); + ~QQuickCircularProgressBar(); + + void paint(QPainter *painter); + + qreal progress() const; + void setProgress(qreal progress); + + qreal barWidth() const; + void setBarWidth(qreal barWidth); + + qreal inset() const; + void setInset(qreal inset); + + qreal minimumValueAngle() const; + void setMinimumValueAngle(qreal minimumValueAngle); + + qreal maximumValueAngle() const; + void setMaximumValueAngle(qreal maximumValueAngle); + + Q_INVOKABLE void clearStops(); + Q_INVOKABLE void addStop(qreal position, const QColor &color); + Q_INVOKABLE void redraw(); + + QColor backgroundColor() const; + void setBackgroundColor(const QColor &backgroundColor); +signals: + void progressChanged(qreal progress); + void barWidthChanged(qreal barWidth); + void insetChanged(qreal inset); + void minimumValueAngleChanged(qreal minimumValueAngle); + void maximumValueAngleChanged(qreal maximumValueAngle); + void backgroundColorChanged(const QColor &backgroundColor); +private: + qreal mProgress; + qreal mBarWidth; + qreal mInset; + QGradientStops mGradientStops; + QColor mBackgroundColor; + qreal mMinimumValueAngle; + qreal mMaximumValueAngle; +}; + +#endif // CIRCULARPROGRESSBAR_P_H diff --git a/src/extras/Private/qquickflatprogressbar.cpp b/src/extras/Private/qquickflatprogressbar.cpp new file mode 100644 index 00000000..f45a708a --- /dev/null +++ b/src/extras/Private/qquickflatprogressbar.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qquickflatprogressbar_p.h" + +#include <QtCore/QtMath> +#include <QtGui/QPainter> + +QQuickFlatProgressBar::QQuickFlatProgressBar(QQuickItem *parent) : + QQuickPaintedItem(parent), + mStripeOffset(0), + mRadius(0), + mIndeterminate(false) +{ + mAnimation.setTargetObject(this); + mAnimation.setPropertyName("stripeOffset"); + mAnimation.setEndValue(0); + mAnimation.setDuration(800); + mAnimation.setLoopCount(-1); + + connect(this, SIGNAL(stripeOffsetChanged(qreal)), this, SLOT(repaint())); + connect(this, SIGNAL(progressChanged(qreal)), this, SLOT(repaint())); + connect(this, SIGNAL(enabledChanged()), this, SLOT(repaint())); + connect(this, SIGNAL(indeterminateChanged(bool)), this, SLOT(repaint())); + connect(this, SIGNAL(widthChanged()), this, SLOT(onWidthChanged())); + connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged())); + connect(this, SIGNAL(visibleChanged()), this, SLOT(onVisibleChanged())); +} + +int QQuickFlatProgressBar::barWidth() +{ + // 14 is the design height of stripes on the bar, 10 is design width of stripe + return int(height() * 10 / 14); +} + +void QQuickFlatProgressBar::paint(QPainter *painter) +{ + // This item should always be rounded to an integer size, so it is safe to use int here. + const int w = width(); + const int h = height(); + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(Qt::transparent); + + // Draw the background. + painter->setBrush(isIndeterminate() && mProgress > 0 ? QColor(92, 170, 21) : QColor(0, 0, 0, 255 * 0.15)); + painter->drawRoundedRect(0, 0, w, h, mRadius, mRadius); + + // Draw progress, or indeterminate stripes. + painter->setClipPath(mClipPath); + + if (!mIndeterminate) { + painter->setBrush(isEnabled() ? QColor(92, 170, 21) : QColor(179, 179, 179)); + painter->drawRect(0, 0, int(w * mProgress), h); + } else { + QPainterPath innerClipPath; + // 1 is the design margin thickness. + const int margin = qMax(1, int(height() * (1.0 / 16.0))); + // We take the margin from the radius so that the inner and outer radii match each other visually. + innerClipPath.addRoundedRect(margin, margin, width() - margin * 2, height() - margin * 2, mRadius - margin, mRadius - margin); + painter->setClipPath(innerClipPath); + + painter->translate(mStripeOffset, 0); + + const qreal stripeWidth = barWidth(); + // The horizontal distance created by the slant of the stripe. + const qreal stripeSlantDistance = h; + + // One stripe width is equal to the height of the bar. + QPainterPath stripe; + stripe.moveTo(0, h); + stripe.lineTo(stripeSlantDistance, 0); + stripe.lineTo(stripeSlantDistance + stripeWidth, 0); + stripe.lineTo(stripeWidth, h); + stripe.closeSubpath(); + + painter->setBrush(QBrush(mProgress > 0 ? QColor(255, 255, 255, 77) : Qt::white)); + + for (int i = -stripeWidth * 2; i < w + stripeWidth * 2; i += stripeWidth * 2) { + painter->translate(i, 0); + painter->drawPath(stripe); + painter->translate(-i, 0); + } + + painter->translate(-mStripeOffset, 0); + } +} + +qreal QQuickFlatProgressBar::stripeOffset() const +{ + return mStripeOffset; +} + +void QQuickFlatProgressBar::setStripeOffset(qreal pos) +{ + if (pos != mStripeOffset) { + mStripeOffset = pos; + emit stripeOffsetChanged(pos); + } +} + +qreal QQuickFlatProgressBar::progress() const +{ + return mProgress; +} + +void QQuickFlatProgressBar::setProgress(qreal progress) +{ + if (progress != mProgress) { + mProgress = progress; + emit progressChanged(mProgress); + } +} + +bool QQuickFlatProgressBar::isIndeterminate() +{ + return mIndeterminate; +} + +void QQuickFlatProgressBar::setIndeterminate(bool indeterminate) +{ + if (indeterminate != mIndeterminate) { + mIndeterminate = indeterminate; + emit indeterminateChanged(mIndeterminate); + } +} + +void QQuickFlatProgressBar::repaint() +{ + QQuickPaintedItem::update(QRect(0, 0, width(), height())); +} + +void QQuickFlatProgressBar::restartAnimation() +{ + mAnimation.stop(); + mAnimation.setStartValue(-barWidth() * 2); + mAnimation.start(); +} + +void QQuickFlatProgressBar::onVisibleChanged() +{ + if (isVisible()) { + restartAnimation(); + } else { + mAnimation.stop(); + } +} + +void QQuickFlatProgressBar::onWidthChanged() +{ + restartAnimation(); + + mClipPath = QPainterPath(); + mClipPath.addRoundedRect(0, 0, width(), height(), mRadius, mRadius); +} + +void QQuickFlatProgressBar::onHeightChanged() +{ + restartAnimation(); + + // 3 is the design radius, 16 is the design height of the bar + const qreal radius = height() * 3 / 16; + if (radius != mRadius) { + mRadius = radius; + } + + mClipPath = QPainterPath(); + mClipPath.addRoundedRect(0, 0, width(), height(), mRadius, mRadius); +} diff --git a/src/extras/Private/qquickflatprogressbar_p.h b/src/extras/Private/qquickflatprogressbar_p.h new file mode 100644 index 00000000..1c3061e4 --- /dev/null +++ b/src/extras/Private/qquickflatprogressbar_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef FLATPROGRESSBAR_H +#define FLATPROGRESSBAR_H + +#include <QtCore/QPropertyAnimation> +#include <QtGui/QPainterPath> +#include <QtQuick/QQuickPaintedItem> + +class QQuickFlatProgressBar : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(qreal stripeOffset READ stripeOffset WRITE setStripeOffset NOTIFY stripeOffsetChanged) + Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged) + Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate NOTIFY indeterminateChanged) +public: + explicit QQuickFlatProgressBar(QQuickItem *parent = 0); + + void paint(QPainter *painter); + + qreal stripeOffset() const; + void setStripeOffset(qreal stripeOffset); + + qreal progress() const; + void setProgress(qreal progress); + + bool isIndeterminate(); + void setIndeterminate(bool indeterminate); + +public slots: + void repaint(); + void restartAnimation(); + void onVisibleChanged(); + void onWidthChanged(); + void onHeightChanged(); + +signals: + void stripeOffsetChanged(qreal stripeOffset); + void progressChanged(qreal progress); + void indeterminateChanged(bool indeterminate); + +private: + int barWidth(); + +private: + qreal mStripeOffset; + qreal mProgress; + qreal mRadius; + bool mIndeterminate; + QPainterPath mClipPath; + QPropertyAnimation mAnimation; +}; + +#endif // FLATPROGRESSBAR_H diff --git a/src/extras/Private/qquickmathutils.cpp b/src/extras/Private/qquickmathutils.cpp new file mode 100644 index 00000000..8f4b2a6b --- /dev/null +++ b/src/extras/Private/qquickmathutils.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qquickmathutils_p.h" + +#include <qmath.h> + +QQuickMathUtils::QQuickMathUtils(QObject *parent) : + QObject(parent) +{ +} + +qreal QQuickMathUtils::pi2() const +{ + return M_PI * 2; +} + +/*! + Converts the angle \a degrees to radians. +*/ +qreal QQuickMathUtils::degToRad(qreal degrees) const { + return degrees * (M_PI / 180); +} + +/*! + Converts the angle \a degrees to radians. + + This function assumes that the angle origin (0) is north, as this + is the origin used by all of the Extras. The angle + returned will have its angle origin (0) pointing east, in order to be + consistent with standard angles used by \l {QtQuick::Canvas}{Canvas}, + for example. +*/ +qreal QQuickMathUtils::degToRadOffset(qreal degrees) const { + return (degrees - 90) * (M_PI / 180); +} + +/*! + Converts the angle \a radians to degrees. +*/ +qreal QQuickMathUtils::radToDeg(qreal radians) const { + return radians * (180 / M_PI); +} + +/*! + Converts the angle \a radians to degrees. + + This function assumes that the angle origin (0) is east; as is standard for + mathematical operations using radians (this origin is used by + \l {QtQuick::Canvas}{Canvas}, for example). The angle returned in degrees + will have its angle origin (0) pointing north, which is what the extras + expect. +*/ +qreal QQuickMathUtils::radToDegOffset(qreal radians) const { + return radians * (180 / M_PI) + 90; +} + +/*! + Returns the top left position of the item if it were centered along + a circle according to \a angleOnCircle and \a distanceAlongRadius. + + \a angleOnCircle is from 0.0 - M_PI2. + \a distanceAlongRadius is the distance along the radius in M_PIxels. +*/ +QPointF QQuickMathUtils::centerAlongCircle(qreal xCenter, qreal yCenter, + qreal width, qreal height, qreal angleOnCircle, qreal distanceAlongRadius) const { + return QPointF( + (xCenter - width / 2) + (distanceAlongRadius * cos(angleOnCircle)), + (yCenter - height / 2) + (distanceAlongRadius * sin(angleOnCircle))); +} + +/*! + Returns \a number rounded to the nearest even integer. +*/ +qreal QQuickMathUtils::roundEven(qreal number) const { + int rounded = qRound(number); + return rounded % 2 == 0 ? rounded : rounded + 1; +} diff --git a/src/extras/Private/qquickmathutils_p.h b/src/extras/Private/qquickmathutils_p.h new file mode 100644 index 00000000..35e15a84 --- /dev/null +++ b/src/extras/Private/qquickmathutils_p.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QQUICKMATHUTILS_P +#define QQUICKMATHUTILS_P + +#include <QObject> +#include <QPointF> + +class QQuickMathUtils : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal pi2 READ pi2 CONSTANT) +public: + QQuickMathUtils(QObject *parent = 0); + + qreal pi2() const; + Q_INVOKABLE qreal degToRad(qreal degrees) const; + Q_INVOKABLE qreal degToRadOffset(qreal degrees) const; + Q_INVOKABLE qreal radToDeg(qreal radians) const; + Q_INVOKABLE qreal radToDegOffset(qreal radians) const; + Q_INVOKABLE QPointF centerAlongCircle(qreal xCenter, qreal yCenter, + qreal width, qreal height, qreal angleOnCircle, qreal distanceAlongRadius) const; + Q_INVOKABLE qreal roundEven(qreal number) const; +}; + +#endif // QQUICKMATHUTILS_P + diff --git a/src/extras/Private/qquickmousethief.cpp b/src/extras/Private/qquickmousethief.cpp new file mode 100644 index 00000000..5fe82672 --- /dev/null +++ b/src/extras/Private/qquickmousethief.cpp @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qquickmousethief_p.h" + +#include <QtCore/QMetaObject> +#include <QtQuick/QQuickWindow> + +QQuickMouseThief::QQuickMouseThief(QObject *parent) : + QObject(parent), + mItem(0), + mReceivedPressEvent(false), + mAcceptCurrentEvent(false) +{ +} + +bool QQuickMouseThief::receivedPressEvent() const +{ + return mReceivedPressEvent; +} + +void QQuickMouseThief::setReceivedPressEvent(bool receivedPressEvent) +{ + if (receivedPressEvent != mReceivedPressEvent) { + mReceivedPressEvent = receivedPressEvent; + emit receivedPressEventChanged(); + } +} + +void QQuickMouseThief::grabMouse(QQuickItem *item) +{ + if (item) { + mItem = item; + + // Handle the case where someone makes the PieMenu an orphan. E.g.: + // property PieMenu pieMenu: PieMenu {} + // They have to set the parent explicitly if they want that to work. + // This can also be null if the menu is visible when constructed. + if (mItem->window()) { + // We install an event filter so that we can track release events. + // This is because the MouseArea that we steal the mouse from stores the + // pressed flag (before item is visible) and we don't, so we don't know + // that it's a release. + mItem->grabMouse(); + mItem->window()->installEventFilter(this); + } else { + // The menu was visible when constructed (visible: true), so install the + // event filter later on. + connect(mItem, SIGNAL(windowChanged(QQuickWindow*)), + this, SLOT(itemWindowChanged(QQuickWindow*))); + } + } +} + +void QQuickMouseThief::ungrabMouse() +{ + if (mItem) { + // This can be null if someone does the following: + // PieMenu { Component.onCompleted: { visible = true; visible = false; } + if (mItem->window()) { + if (mItem->window()->mouseGrabberItem() == mItem) { + mItem->ungrabMouse(); + } + mItem->window()->removeEventFilter(this); + } + mItem = 0; + } +} + +void QQuickMouseThief::acceptCurrentEvent() +{ + mAcceptCurrentEvent = true; +} + +void QQuickMouseThief::itemWindowChanged(QQuickWindow *window) +{ + // The window will be null when the application is closing. + if (window) { + // This can be null if someone does the following: + // PieMenu { Component.onCompleted: { visible = true; visible = false; } + if (mItem) { + mItem->grabMouse(); + window->installEventFilter(this); + } + } +} + +bool QQuickMouseThief::eventFilter(QObject *, QEvent *event) +{ + if (!mItem) + return false; + + // The PieMenu QML code dictates which events are accepted by + // setting this property when it responds to our signals. + mAcceptCurrentEvent = false; + + if (event->type() == QEvent::MouseButtonRelease) { + const QPointF mouseWindowPos = static_cast<QMouseEvent *>(event)->windowPos(); + emitReleased(mouseWindowPos); + // Even if the release should close the menu, we should emit + // clicked to be consistent since we have to do it ourselves. + bool releaseAccepted = mAcceptCurrentEvent; + mAcceptCurrentEvent = false; + + emitClicked(mouseWindowPos); + if (!mAcceptCurrentEvent) { + // We might not have accepted click, but we may have accepted release. + mAcceptCurrentEvent = releaseAccepted; + } + } else if (event->type() == QEvent::MouseButtonPress) { + emitPressed(static_cast<QMouseEvent *>(event)->windowPos()); + } else if (event->type() == QEvent::TouchEnd) { + // The finger(s) were lifted off the screen. We don't get this as a release event since + // we're doing our own custom handling, so we handle it here. + QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event); + const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints(); + // We only care about one finger. If there's more than one, ignore them. + if (!points.isEmpty()) { + const QPointF pos = points.first().pos(); + emitReleased(pos); + // Even if the release should close the menu, we should emit + // clicked to be consistent since we have to do it ourselves. + bool releaseAccepted = mAcceptCurrentEvent; + mAcceptCurrentEvent = false; + + emitClicked(pos); + if (!mAcceptCurrentEvent) { + // We might not have accepted click, but we may have accepted release. + mAcceptCurrentEvent = releaseAccepted; + } + } + } else if (event->type() == QEvent::TouchBegin) { + QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event); + const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints(); + if (!points.isEmpty()) { + emitPressed(points.first().pos()); + } + } else if (event->type() == QEvent::TouchUpdate) { + QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event); + const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints(); + if (!points.isEmpty()) { + const QPointF mappedPos = mItem->mapFromScene(points.first().pos()); + emit touchUpdate(mappedPos.x(), mappedPos.y()); + } + } + return mAcceptCurrentEvent; +} + +void QQuickMouseThief::emitPressed(const QPointF &pos) +{ + setReceivedPressEvent(true); + + // PieMenu can't detect presses outside its own MouseArea, + // so we need to provide these as well. + QPointF mappedPos = mItem->mapFromScene(pos); + emit pressed(mappedPos.x(), mappedPos.y()); +} + +void QQuickMouseThief::emitReleased(const QPointF &pos) +{ + QPointF mappedPos = mItem->mapFromScene(pos); + emit released(mappedPos.x(), mappedPos.y()); +} + +void QQuickMouseThief::emitClicked(const QPointF &pos) +{ + // mItem can be destroyed if the slots connected to released() caused it to be hidden. + // That's fine for us, since PieMenu doesn't need to handle anything if released() + // is emitted when the triggerMode is PieMenu.TriggerOnRelease. + if (mItem) { + QPointF mappedPos = mItem->mapFromScene(pos); + // Since we are creating the release events, we must also handle clicks. + emit clicked(mappedPos.x(), mappedPos.y()); + } +} diff --git a/src/extras/Private/qquickmousethief_p.h b/src/extras/Private/qquickmousethief_p.h new file mode 100644 index 00000000..3b1a5a4d --- /dev/null +++ b/src/extras/Private/qquickmousethief_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef MOUSETHIEF_H +#define MOUSETHIEF_H + +#include <QObject> +#include <QtQuick/QQuickItem> + +class QQuickMouseThief : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool receivedPressEvent READ receivedPressEvent + WRITE setReceivedPressEvent NOTIFY receivedPressEventChanged) +public: + explicit QQuickMouseThief(QObject *parent = 0); + + bool receivedPressEvent() const; + void setReceivedPressEvent(bool receivedPressEvent); + + Q_INVOKABLE void grabMouse(QQuickItem *item); + Q_INVOKABLE void ungrabMouse(); + Q_INVOKABLE void acceptCurrentEvent(); +signals: + /*! + Coordinates are relative to the window of mItem. + */ + void pressed(int mouseX, int mouseY); + + void released(int mouseX, int mouseY); + + void clicked(int mouseX, int mouseY); + + void touchUpdate(int mouseX, int mouseY); + + void receivedPressEventChanged(); + + void handledEventChanged(); +protected: + bool eventFilter(QObject *obj, QEvent *event); +private slots: + void itemWindowChanged(QQuickWindow *window); +private: + void emitPressed(const QPointF &pos); + void emitReleased(const QPointF &pos); + void emitClicked(const QPointF &pos); + + QQuickItem *mItem; + bool mReceivedPressEvent; + bool mAcceptCurrentEvent; +}; + +#endif // MOUSETHIEF_H diff --git a/src/extras/Private/qquickstylesettings.cpp b/src/extras/Private/qquickstylesettings.cpp new file mode 100644 index 00000000..0936e55e --- /dev/null +++ b/src/extras/Private/qquickstylesettings.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qquickstylesettings_p.h" +#include <qqmlengine.h> +#include <qfileinfo.h> +#include <qdebug.h> +#include <qdir.h> + +QT_BEGIN_NAMESPACE + +static QString defaultStyleName() +{ + return QLatin1String("Base"); +} + +static QString styleImportName() +{ + QString name = qgetenv("QT_QUICK_CONTROLS_STYLE"); + if (name.isEmpty()) + name = defaultStyleName(); + return QFileInfo(name).fileName(); +} + +static bool isResource(const QString &path) +{ + return path.startsWith(":/"); +} + +static QString styleImportPath(QQmlEngine *engine, const QString &styleName) +{ + static const char * const stylePaths[] = { "/QtQuick/Extras/Styles", "/QtQuick/Controls/Styles" }; + QString path = qgetenv("QT_QUICK_CONTROLS_STYLE"); + QFileInfo info(path); + if (isResource(path)) { + path = info.path(); + } else if (info.isRelative()) { + bool found = false; + QStringList importPaths = engine->importPathList(); + importPaths.prepend(QStringLiteral(":/ExtrasImports/")); + + foreach (const QString &import, importPaths) { + for (unsigned i = 0; i < sizeof(stylePaths) / sizeof(stylePaths[0]); i++) { + QDir dir(import + QLatin1String(stylePaths[i])); + if (dir.exists(styleName)) { + found = true; + path = dir.absolutePath(); + break; + } + } + if (found) + break; + } + if (!found) + path = QLatin1String(":/ExtrasImports/QtQuick/Extras/Styles"); + } else { + path = info.absolutePath(); + } + return path; +} + +QQuickStyleSettings::QQuickStyleSettings(QQmlEngine *engine) +{ + m_name = styleImportName(); + m_path = styleImportPath(engine, m_name); + + QString path = styleFilePath(); + + if (!QDir(path).exists()) { + QString unknownStyle = m_name; + m_name = defaultStyleName(); + m_path = styleImportPath(engine, m_name); + qWarning() << "WARNING: Cannot find style" << unknownStyle << "- fallback:" << styleFilePath(); + } + + connect(this, SIGNAL(styleNameChanged()), SIGNAL(styleChanged())); + connect(this, SIGNAL(stylePathChanged()), SIGNAL(styleChanged())); +} + +QUrl QQuickStyleSettings::style() const +{ + QUrl result; + QString path = styleFilePath(); + if (isResource(path)) { + result.setScheme("qrc"); + path.remove(0, 1); // remove ':' prefix + result.setPath(path); + } else + result = QUrl::fromLocalFile(path); + return result; +} + +QString QQuickStyleSettings::styleName() const +{ + return m_name; +} + +void QQuickStyleSettings::setStyleName(const QString &name) +{ + if (m_name != name) { + m_name = name; + emit styleNameChanged(); + } +} + +QString QQuickStyleSettings::stylePath() const +{ + return m_path; +} + +void QQuickStyleSettings::setStylePath(const QString &path) +{ + if (m_path != path) { + m_path = path; + emit stylePathChanged(); + } +} + +QString QQuickStyleSettings::styleFilePath() const +{ + return m_path + QLatin1Char('/') + m_name; +} + +QT_END_NAMESPACE diff --git a/src/extras/Private/qquickstylesettings_p.h b/src/extras/Private/qquickstylesettings_p.h new file mode 100644 index 00000000..3cb157a8 --- /dev/null +++ b/src/extras/Private/qquickstylesettings_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef STYLESETTINGS_P_H +#define STYLESETTINGS_P_H + +#include <QtCore/qurl.h> +#include <QtCore/qobject.h> + +QT_BEGIN_NAMESPACE + +class QQmlEngine; + +class QQuickStyleSettings : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUrl style READ style NOTIFY styleChanged) + Q_PROPERTY(QString styleName READ styleName WRITE setStyleName NOTIFY styleNameChanged) + Q_PROPERTY(QString stylePath READ stylePath WRITE setStylePath NOTIFY stylePathChanged) + +public: + QQuickStyleSettings(QQmlEngine *engine); + + QUrl style() const; + + QString styleName() const; + void setStyleName(const QString &name); + + QString stylePath() const; + void setStylePath(const QString &path); + +signals: + void styleChanged(); + void styleNameChanged(); + void stylePathChanged(); + +private: + QString styleFilePath() const; + + QString m_name; + QString m_path; +}; + +QT_END_NAMESPACE + +#endif // STYLESETTINGS_P_H |