C

Qt Quick Ultralite Motorcycle Cluster Demo

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
import QtQuick 2.0
import QtQuickUltralite.Extras 2.0

ItemWithAcivationAnimations {
    id: root
    width: 450
    height: 180

    property int distance: 1000
    property int naviState: NavigationModel.Off
    property int naviStatePrivate: NavigationModel.Off

    property bool isDayMode: false

    property int arrowsState: NavigationModel.TwoStright

    property color backgroundColor: getBackgroundColor(isDayMode)
    Behavior on backgroundColor {
        NumberAnimation {
            duration: welcomeAnimationDuration
        }
    }
    property color forgroundColor: getForgroundColor(isDayMode)
    Behavior on forgroundColor {
        NumberAnimation {
            duration: welcomeAnimationDuration
        }
    }
    property color forgroundColorPrime: getForgroundColor(!isDayMode)
    Behavior on forgroundColorPrime {
        NumberAnimation {
            duration: welcomeAnimationDuration
        }
    }
    property color activeArrowColor: getActiveArrowColor(isDayMode)
    Behavior on activeArrowColor {
        NumberAnimation {
            duration: welcomeAnimationDuration
        }
    }

    Row {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top
        opacity: naviStatePrivate !== NavigationModel.Off ? 1 : 0
        Behavior on opacity {
            NumberAnimation {
                duration: 500
            }
        }

        Arrow {
            id: leftArrow
            source: arrowsState === NavigationModel.LeftTurn ? "qrc:///images/navigation/tbt-1-arrow-left.png" :
                                                              "qrc:///images/navigation/tbt-1-arrow-stright.png"
            color: arrowsState === NavigationModel.LeftTurn ? activeArrowColor : backgroundColor
            targetOpacity: arrowsState === NavigationModel.LeftTurn ? 1 : 0.3
            runAnimation: arrowsState === NavigationModel.LeftTurn && distance < 150 && naviState === NavigationModel.Navigating
        }

        ColorizedImage {
            id: separator
            source: "qrc:///images/navigation/tbt-center-separator.png"
            color: backgroundColor
            opacity: 0.3
        }

        Arrow {
            id: rightArrow
            source: arrowsState === NavigationModel.RightTurn ? "qrc:///images/navigation/tbt-1-arrow-left.png" :
                                                               "qrc:///images/navigation/tbt-1-arrow-stright.png"
            color: arrowsState === NavigationModel.RightTurn ? activeArrowColor : backgroundColor
            targetOpacity: arrowsState === NavigationModel.RightTurn ? 1 : 0.3
            runAnimation: arrowsState === NavigationModel.RightTurn && distance < 150 && naviState === NavigationModel.Navigating

            transform: Scale {
                xScale: -1
                origin.x: rightArrow.implicitWidth / 2
            }
        }
    }

    ColorizedImage {
        id: destinationPin
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: distanceRec.top
        anchors.bottomMargin: 26
        source: "qrc:///images/navigation/destination-pin.png"
        color: backgroundColor
        opacity: naviStatePrivate === NavigationModel.Off ? 1 : 0
        Behavior on opacity {
            NumberAnimation {
                duration: 500
            }
        }
    }

    TextInRoundedBox {
        id: distanceRec

        anchors.horizontalCenter: root.horizontalCenter
        anchors.bottom: root.bottom

        color: backgroundColor
        text:  getButtonText()
        textColor: naviStatePrivate === NavigationModel.Navigating ? forgroundColor : forgroundColorPrime
        textColorPrime: naviStatePrivate !== NavigationModel.Navigating ? forgroundColor : forgroundColorPrime
        insideColor: isDayMode ? Style.white : Style.roadGreen
        insideOpacity: naviStatePrivate === NavigationModel.Navigating ? 0 : 1
    }

    onNaviStateChanged: {
        if(naviState === NavigationModel.Hidden || naviState === NavigationModel.Off) {
            activateButtonAnimation.start()
        } else {
           naviStatePrivate = naviState
        }
    }

    SequentialAnimation {
        id: activateButtonAnimation
        ScriptAction { script: { distanceRec.setActive() } }
        PauseAnimation { duration: 800 }
        ScriptAction { script: { naviStatePrivate = naviState } }
        PauseAnimation { duration: 1400 }
        ScriptAction { script: { distanceRec.setActive() } }
    }

    function getDistanceToTargetText() : string {
        if(distance < 40) {
            return "Turn now"
        }
        if(distance > 4500) {
            return (distance/1000).toFixed(0) + " km"
        }
        if(distance > 1500) {
            return ((distance - distance % 200)/1000).toFixed(1) + " km"
        }
        if(distance > 300) {
            return (distance - distance % 100).toString() + " m"
        }
        if(distance > 100) {
            return (distance - distance % 50).toString() + " m"
        }
        return (distance - distance % 20).toString() + " m"
    }

    function getButtonText() : string {
        if(naviStatePrivate === NavigationModel.Navigating) {
            return getDistanceToTargetText()
        }
        else if(naviStatePrivate === NavigationModel.Off) {
            return "Set Destination"
        }
        else if(naviStatePrivate === NavigationModel.Paused) {
            return "Stop Navigation"
        }
    }

    onIsDayModeChanged: {
        if (active) {
            changeDayModeAnimation.start()
        }
    }

    SequentialAnimation {
        id: changeDayModeAnimation
        PauseAnimation {
            duration: 900
        }
        ScriptAction {
            script: {
                root.backgroundColor = getBackgroundColor(isDayMode)
                root.forgroundColor = getForgroundColor(isDayMode)
                root.forgroundColorPrime = getForgroundColor(!isDayMode)
                root.activeArrowColor = getActiveArrowColor(isDayMode)
            }
        }
    }

    function getBackgroundColor(dayModeActive: bool) : color {
        return dayModeActive ? Style.black : Style.white
    }

    function getForgroundColor(dayModeActive: bool) : color {
        return !dayModeActive ? Style.black : Style.white
    }

    function getActiveArrowColor(dayModeActive: bool) : color {
        return dayModeActive ? Style.black : Style.white
    }
}