C
Qt Quick Ultralite Motorcycle Cluster Demo
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
import QtQuick 2.4
import QtQuickUltralite.Extras 2.0
Item {
id: root
property int rpm: 0
property int gear: 0
width: 152
height: 152
property bool active
property bool isDayMode
property color circlesColor: gear === 0 ? Style.neutralGreen : (root.rpm > 13000 ? Style.red : Style.neutralGreen)
property color ringsColor: Style.white
property color backgroundColor: gear === 0 ? backgroundColorForNeutral : (root.rpm > 13000 ? Style.red : Style.normalGreen)
property color fontColor: gear == 0 ? fontColorNeutral : Style.white
property string gearTextVal: gear == 0 ? "N" : gear
property color backgroundColorForNeutral: Style.neutralGreen
property color fontColorNeutral: Style.white
property image holeInBackgroundImg: "qrc:///images/fuelGauge/hole-in-bg-day.png"
property image gradientCircleImg: "qrc:///images/fuelGauge/fuel-colored-circle.png"
states: [
State {
name: "dayMode"
when: isDayMode === true
PropertyChanges {
target: root
holeInBackgroundImg: "qrc:///images/fuelGauge/hole-in-bg-day.png"
}
PropertyChanges {
target: root
backgroundColorForNeutral: Style.white
}
PropertyChanges {
target: root
ringsColor: Style.black
}
PropertyChanges {
target: root
fontColorNeutral: Style.black
}
PropertyChanges {
target: root
gradientCircleImg: "qrc:///images/fuelGauge/fuel-colored-circle-day.png"
}
PropertyChanges {
target: background
opacity: 1
}
PropertyChanges {
target: holeInBackground
opacity: 1
}
PropertyChanges {
target: gradientCircle
opacity: 1
}
},
State {
name: "nightMode"
when: isDayMode !== true
PropertyChanges {
target: root
holeInBackgroundImg: "qrc:///images/fuelGauge/hole-in-bg.png"
}
PropertyChanges {
target: root
backgroundColorForNeutral: Style.neutralGreen
}
PropertyChanges {
target: root
ringsColor: Style.white
}
PropertyChanges {
target: root
fontColorNeutral: Style.white
}
PropertyChanges {
target: root
gradientCircleImg: "qrc:///images/fuelGauge/fuel-colored-circle.png"
}
PropertyChanges {
target: background
opacity: 1
}
PropertyChanges {
target: holeInBackground
opacity: 1
}
PropertyChanges {
target: gradientCircle
opacity: 1
}
}
]
transitions: [
Transition {
SequentialAnimation {
id: dayModeAnimation
ParallelAnimation {
NumberAnimation {
target: background
duration: 300
property: "opacity"
to: 0
easing.type: Easing.OutCubic
}
NumberAnimation {
target: gradientCircle
duration: 300
property: "opacity"
to: 0
easing.type: Easing.OutCubic
}
}
NumberAnimation {
target: holeInBackground
property: "opacity"
to: 0
duration: 300
easing.type: Easing.OutCubic
}
ScriptAction {
script: {
holeInBackground.source = holeInBackgroundImg
}
}
ScriptAction {
script: {
gradientCircle.source = gradientCircleImg
}
}
PauseAnimation {
duration: 1000
}
NumberAnimation {
target: holeInBackground
property: "opacity"
to: 1
duration: 300
easing.type: Easing.OutCubic
}
ParallelAnimation {
NumberAnimation {
target: gradientCircle
property: "opacity"
to: 1
duration: 300
easing.type: Easing.OutCubic
}
NumberAnimation {
target: background
property: "opacity"
to: 1
duration: 300
easing.type: Easing.OutCubic
}
}
}
}
]
Behavior on circlesColor {
ColorAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
Behavior on backgroundColor {
ColorAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
Rectangle {
id: background
width: holeInBackground.width
height: holeInBackground.height
anchors.centerIn: root
color: backgroundColor
}
Image {
id: holeInBackground
anchors.centerIn: root
}
ColorizedImage {
id: gradientCircle
color: root.circlesColor
anchors.centerIn: root
}
Text {
id: textValue
font.family: "Barlow-mono"
font.pixelSize: 70
color: fontColor
anchors.centerIn: background
anchors.verticalCenterOffset: -14
text: gearTextVal
}
Text {
id: gearText
font.family: "Barlow-mono"
font.pixelSize: 20
color: fontColor
text: "Gear"
anchors.centerIn: background
anchors.verticalCenterOffset: 30
}
ColorizedImage {
id: ring1
source: "qrc:///images/fuelGauge/ring-2.png"
width: 130
height: 130
anchors.centerIn: root
color: root.ringsColor
}
ColorizedImage {
id: ring2
source: "qrc:///images/fuelGauge/ring-2.png"
anchors.centerIn: root
property int horizontalCenterOffsetValue
anchors.horizontalCenterOffset: horizontalCenterOffsetValue
color: root.ringsColor
}
function hideElements() {
ring1.opacity = 0
ring2.opacity = 0
holeInBackground.opacity = 0
background.opacity = 0
gradientCircle.opacity = 0
textValue.opacity = 0
gearText.opacity = 0
}
onActiveChanged: {
if (active) {
startAnimation()
} else {
hiddingAnimation()
}
}
function startAnimation() {
startUpAnimation.start()
}
function hiddingAnimation() {
hideAnimation.start()
}
SequentialAnimation {
id: hideAnimation
NumberAnimation {
target: background
property: "opacity"
to: 0
duration: 500
easing.type: Easing.OutCubic
}
NumberAnimation {
target: root
property: "opacity"
to: 0
duration: 500
easing.type: Easing.OutCubic
}
ScriptAction {
script: hideElements()
}
}
SequentialAnimation {
id: startUpAnimation
ScriptAction {
script: {
hideElements()
root.opacity = 1
}
}
ParallelAnimation {
NumberAnimation {
target: ring2
property: "horizontalCenterOffsetValue"
from: -StartupConfig.ring2TravelDistance
to: 0
duration: StartupConfig.ring2TravelDuration
easing.type: Easing.OutCubic
}
NumberAnimation {
target: ring2
property: "opacity"
from: 0
to: 1
duration: StartupConfig.ring2OpacityDuration
easing.type: Easing.OutCubic
}
}
ScriptAction {
script: {
holeInBackground.opacity = 1
}
}
SequentialAnimation {
NumberAnimation {
target: ring1
property: "opacity"
from: 0
to: 1
duration: StartupConfig.ring1OpacityDuration
easing.type: Easing.OutCubic
}
NumberAnimation {
target: gradientCircle
property: "opacity"
from: 0
to: 1
duration: StartupConfig.backgroundOpacityDuration
easing.type: Easing.OutCubic
}
ParallelAnimation {
NumberAnimation {
target: background
property: "opacity"
from: 0
to: 1
duration: StartupConfig.backgroundOpacityDuration
easing.type: Easing.OutCubic
}
NumberAnimation {
target: gearText
property: "opacity"
from: 0
to: 1
duration: StartupConfig.backgroundOpacityDuration
easing.type: Easing.OutCubic
}
}
NumberAnimation {
target: textValue
property: "opacity"
from: 0
to: 1
duration: 500
easing.type: Easing.OutCubic
}
}
}
Component.onCompleted: {
hideElements()
}
}