diff options
Diffstat (limited to 'basicsuite/ebike-ui/SpeedView.qml')
-rw-r--r-- | basicsuite/ebike-ui/SpeedView.qml | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/basicsuite/ebike-ui/SpeedView.qml b/basicsuite/ebike-ui/SpeedView.qml new file mode 100644 index 0000000..d62e710 --- /dev/null +++ b/basicsuite/ebike-ui/SpeedView.qml @@ -0,0 +1,526 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $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.9 +import DataStore 1.0 +import "./BikeStyle" + +Rectangle { + width: UILayout.speedViewRadius * 2 + 2 + height: UILayout.speedViewRadius * 2 + 2 + color: "transparent" + radius: width * 0.5 + z: 1 + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: UILayout.speedViewTop + } + property int dotcount: UILayout.speedViewDots + property int curvewidth: UILayout.speedViewInnerWidth + property int speedTextSize: UILayout.speedTextSize + property int speedBaselineOffset: UILayout.speedBaselineOffset + 1 + property int innerRadius: UILayout.speedViewInnerRadius + property int speedUnitsSize: UILayout.speedUnitsSize + property int speedUnitBaselineOffset: UILayout.speedTextUnitMargin + property int speedIconsOffset: UILayout.speedIconsCenterOffset + property int speedInfoTextsOffset: 0 + property int speedInfoTextsSize: UILayout.speedInfoTextsSize + property int speedInfoUnitsOffset: UILayout.speedInfoUnitsOffset + property int assistPowerIconOffset: UILayout.assistPowerIconOffset + property bool enlarged: false + property alias cornerRectangle: cornerRectangle + property bool showZero: false + + signal showMain() + + // Speed info + Text { + id: speedText + anchors { + horizontalCenter: speedView.horizontalCenter + baseline: speedView.bottom + baselineOffset: -speedBaselineOffset + } + + color: Colors.speedText + font { + family: "Teko, Light" + weight: Font.Light + pixelSize: speedTextSize + } + text: showZero ? "0" : datastore.speed.toFixed(0) + } + + Text { + id: speedUnit + anchors { + horizontalCenter: speedText.horizontalCenter + baseline: speedText.baseline + baselineOffset: speedUnitBaselineOffset + } + + color: Colors.speedUnit + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: speedUnitsSize + } + text: datastore.unit === DataStore.Kmh ? qsTr("km/h") : qsTr("mph") + } + + // Average speed info + Text { + id: averageSpeedText + anchors { + baseline: speedText.baseline + baselineOffset: speedInfoTextsOffset + horizontalCenter: speedText.horizontalCenter + horizontalCenterOffset: -speedIconsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.averageSpeedText + font { + family: "Teko, Light" + weight: Font.Light + pixelSize: speedInfoTextsSize + } + text: datastore.averagespeed.toFixed(0) + } + + Text { + id: averageSpeedUnit + anchors { + horizontalCenter: averageSpeedText.horizontalCenter + baseline: averageSpeedText.baseline + baselineOffset: speedInfoUnitsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.averageSpeedUnit + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: speedUnitsSize + } + horizontalAlignment: Text.AlignHCenter + text: datastore.unit === DataStore.Kmh ? qsTr("AVG\nkm/h") : qsTr("AVG\nmph") + } + + Image { + id: averageSpeedIcon + width: UILayout.averageSpeedIconWidth + height: UILayout.averageSpeedIconHeight + source: "images/speed.png" + anchors { + horizontalCenter: averageSpeedText.horizontalCenter + bottom: averageSpeedText.top + bottomMargin: UILayout.averageSpeedIconMargin + } + visible: speedView.state !== "CORNERED" + } + + // Assist info + Text { + id: assistDistanceText + anchors { + baseline: speedText.baseline + baselineOffset: speedInfoTextsOffset + horizontalCenter: speedText.horizontalCenter + horizontalCenterOffset: speedIconsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.assistDistanceText + font { + family: "Teko, Light" + weight: Font.Light + pixelSize: speedInfoTextsSize + } + text: datastore.assistdistance.toFixed(0) + } + + Text { + id: assistDistanceUnit + anchors { + horizontalCenter: assistDistanceText.horizontalCenter + baseline: assistDistanceText.baseline + baselineOffset: speedInfoUnitsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.assistDistanceUnit + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: speedUnitsSize + } + horizontalAlignment: Text.AlignHCenter + text: datastore.unit === DataStore.Kmh ? qsTr("km\nassist\nleft") : qsTr("mi.\nassist\nleft") + } + + Image { + id: assistDistanceIcon + width: UILayout.assistDistanceIconWidth + height: UILayout.assistDistanceIconHeight + source: "images/battery.png" + anchors { + horizontalCenter: assistDistanceText.horizontalCenter + bottom: assistDistanceText.top + bottomMargin: UILayout.assistDistanceIconMargin + } + visible: speedView.state !== "CORNERED" + } + + // Assist power icon + Image { + id: assistPowerIcon + width: UILayout.assistPowerTconWidth + height: UILayout.assistPowerTconHeight + source: "images/assist.png" + anchors { + horizontalCenter: speedView.horizontalCenter + top: parent.verticalCenter + topMargin: assistPowerIconOffset + } + visible: speedView.state !== "CORNERED" + } + + Gradient { + id: assistPowerGradient + GradientStop { position: 0.0; color: Colors.assistPowerGradientStart } + GradientStop { position: 1.0; color: Colors.assistPowerGradientEnd } + } + + // Assist power circles + Rectangle { + id: assistPowerIcon1 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + right: assistPowerIcon2.left + rightMargin: UILayout.assistPowerCircleOffset + bottom: assistPowerIcon2.bottom + bottomMargin: UILayout.assistPowerCircleVerticalOffset + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 2.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + Rectangle { + id: assistPowerIcon2 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + right: parent.horizontalCenter + rightMargin: UILayout.assistPowerCircleOffset / 2 + top: assistPowerIcon.bottom + topMargin: UILayout.assistPowerCircleTopMargin + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 25.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + Rectangle { + id: assistPowerIcon3 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + left: parent.horizontalCenter + leftMargin: UILayout.assistPowerCircleOffset / 2 + top: assistPowerIcon.bottom + topMargin: UILayout.assistPowerCircleTopMargin + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 50.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + Rectangle { + id: assistPowerIcon4 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + left: assistPowerIcon3.right + leftMargin: UILayout.assistPowerCircleOffset + bottom: assistPowerIcon3.bottom + bottomMargin: UILayout.assistPowerCircleVerticalOffset + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 75.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + // Numbers for speed and battery level + Text { + anchors { + baseline: parent.bottom + baselineOffset: 20 + right: parent.horizontalCenter + rightMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "0" + } + + Text { + anchors { + baseline: parent.bottom + baselineOffset: 20 + left: parent.horizontalCenter + leftMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "0 %" + } + + Text { + anchors { + baseline: parent.verticalCenter + baselineOffset: -10 + right: parent.left + rightMargin: 9 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "30" + } + + Text { + anchors { + baseline: parent.verticalCenter + baselineOffset: -10 + left: parent.right + leftMargin: 9 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "50 %" + } + + Text { + anchors { + baseline: parent.top + baselineOffset: -10 + right: parent.horizontalCenter + rightMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "60" + } + + Text { + anchors { + baseline: parent.top + baselineOffset: -10 + left: parent.horizontalCenter + leftMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "100 %" + } + + Rectangle { + id: cornerRectangle + width: UILayout.speedViewRadiusMinified + height: width + // By default this is centered, and invisible + anchors.horizontalCenter: speedView.horizontalCenter + anchors.verticalCenter: speedView.verticalCenter + color: "transparent" + radius: 10 + z: -1 + + Image { + source: "images/small_speedometer_arrow.png" + width: UILayout.speedometerCornerArrowWidth + height: UILayout.speedometerCornerArrowHeight + anchors.left: parent.left + anchors.bottom: parent.bottom + visible: swipeView.currentIndex != 1 + } + } + + Image { + source: "images/small_speedometer_shadow.png" + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + horizontalCenterOffset: 1 + verticalCenterOffset: 1 + } + z: -1 + + visible: speedView.state == "CORNERED" + } + + Canvas { + id: speedArc + anchors.fill: parent + + Component.onCompleted: { + datastore.onSpeedChanged.connect(speedArc.requestPaint) + datastore.onBatterylevelChanged.connect(speedArc.requestPaint) + } + + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + + var currentRadius = (speedView.width - 2) / 2; + var centerX = speedView.width / 2; + var centerY = speedView.height / 2; + + // Draw the dotted circle (if not in corner mode) + if (speedView.state !== "CORNERED") { + ctx.fillStyle = Colors.dottedRing; + var angleStep = Math.PI * 2.0 / dotcount; + for (var angle = 0; angle <= Math.PI * 2; angle += angleStep) { + var x = currentRadius * Math.cos(angle); + var y = currentRadius * Math.sin(angle); + ctx.fillRect(centerX + x, centerY + y, 2, 2); + } + } + + // Draw speed and battery view bases + ctx.lineCap = "round"; + ctx.strokeStyle = Colors.dottedRing; + ctx.lineWidth = curvewidth; + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewSpeedStart, UILayout.speedViewSpeedEnd); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewBatteryStart, UILayout.speedViewBatteryEnd, true); + ctx.stroke(); + + // Draw speed gradient + if (!showZero) { + var speedArcLength = UILayout.speedViewSpeedEnd - UILayout.speedViewSpeedStart; + var speedAngle = Math.min(UILayout.speedViewSpeedEnd, + UILayout.speedViewSpeedStart + speedArcLength * (datastore.speed / 60)); + var speedAngleX = Math.cos(speedAngle) * innerRadius; + var speedAngleY = Math.sin(speedAngle) * innerRadius; + var speedGradient = ctx.createLinearGradient(centerX, centerY + innerRadius, + centerX + speedAngleX, centerY + speedAngleY); + speedGradient.addColorStop(0.0, Colors.speedGradientStart); + speedGradient.addColorStop(1.0, Colors.speedGradientEnd); + ctx.strokeStyle = speedGradient; + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewSpeedStart, speedAngle); + ctx.stroke(); + } + + // Draw battery gradient + var batteryArcLength = UILayout.speedViewBatteryEnd - UILayout.speedViewBatteryStart; + var batteryAngle = Math.max(UILayout.speedViewBatteryEnd, + UILayout.speedViewBatteryStart + batteryArcLength * (datastore.batterylevel / 100)); + var batteryAngleX = Math.cos(batteryAngle) * innerRadius; + var batteryAngleY = Math.sin(batteryAngle) * innerRadius; + var batteryGradient = ctx.createLinearGradient(centerX, centerY + innerRadius, + centerX + batteryAngleX, centerY + batteryAngleY); + //centerX, centerY - innerRadius); + batteryGradient.addColorStop(0.0, Colors.batteryGradientStart); + batteryGradient.addColorStop(1.0, Colors.batteryGradientEnd); + ctx.strokeStyle = batteryGradient; + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewBatteryStart, batteryAngle, true); + ctx.stroke(); + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (enlarged) + enlarged = false + else if (swipeView.currentIndex === 1) + enlarged = true + else + speedView.showMain() + } + } +} |