C

Qt Quick Ultralite perspective_transforms Example

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial

import QtQuick 2.12
import Constants 1.0
import PerspectiveTransformsConfiguration 1.0
import "controls"

Rectangle {
    id: root
    color: Constants.backgroundColor

    IdleTimer {
        id: idleTimer
        property int coverDir: 1
        onSwitchCover: {
            var idx = Math.round(currentState.selectedCover)
            idx = idx + coverDir
            if (idx >= (currentState.numberOfCovers-1) || idx <= 0) {
                coverDir = -coverDir
            }
            currentState.selectedCover = idx
            slider_cover.value = idx
        }
        onSwitchFlowType: {
            currentState.switchViewType((currentState.currentViewType + 1) % CoverFlowType.NumTypes)
        }
    }

    CoverFlowState {
        id: currentState
        screenWidth: root.width
        screenHeight: root.height
    }

    CoverFlow {
        anchors.fill: parent
        currentState: currentState
    }

    // Cover Flow Type switch controls
    Column {
        anchors{
            horizontalCenter: parent.horizontalCenter
            top: Configuration.enableCoverAndCameraControls ? parent.top : undefined
            bottom: Configuration.enableCoverAndCameraControls ? undefined : parent.bottom
            topMargin: Constants.controlsMarginS
        }
        width: parent.width * 0.9
        Row {
            spacing: Constants.controlsMarginM
            anchors.horizontalCenter: parent.horizontalCenter
            RadioButton {
                text: "Carousel"
                checked: currentState.currentViewType == CoverFlowType.Carousel
                onClicked: {
                    currentState.switchViewType(CoverFlowType.Carousel)
                }
                onPressedChanged: {
                    idleTimer.reset(pressed)
                }
            }

            RadioButton {
                text: "Circle"
                checked: currentState.currentViewType == CoverFlowType.Circle
                onClicked: {
                    currentState.switchViewType(CoverFlowType.Circle)
                }
                onPressedChanged: {
                    idleTimer.reset(pressed)
                }
            }

            RadioButton {
                text: "Circle 2D"
                checked: currentState.currentViewType == CoverFlowType.Circle2D
                onClicked: {
                    currentState.switchViewType(CoverFlowType.Circle2D)
                }
                onPressedChanged: {
                    idleTimer.reset(pressed)
                }
            }

            RadioButton {
                text: "Perspective"
                checked: currentState.currentViewType == CoverFlowType.Perspective
                onClicked: {
                    currentState.switchViewType(CoverFlowType.Perspective)
                }
                onPressedChanged: {
                    idleTimer.reset(pressed)
                }
            }
        }
    }

    // Cover + camera control slider
    Column {
        visible: Configuration.enableCoverAndCameraControls

        anchors{
            horizontalCenter: parent.horizontalCenter
            bottom: parent.bottom
            bottomMargin: Constants.controlsMarginM
        }
        width: parent.width - Constants.controlsMarginL * 2
        spacing: Constants.controlsMarginM

        Row {
            id: coverControls
            spacing: 80
            width: parent.width
            property int controlWidth: (coverControls.width - coverControls.spacing) / 2

            Slider {
                id: slider_cover
                width: coverControls.controlWidth
                value: 0
                stepSize: 1
                to: currentState.numberOfCovers-1
                text: "Current cover: " + (value+1)
                onValueChanged: {
                    currentState.selectedCover = slider_cover.value
                }
                onPressedChanged: {
                    idleTimer.reset(pressed)
                }
            }

            Slider {
                id: slider_modelSize
                width: coverControls.controlWidth
                value: 4
                stepSize: 1
                to: currentState.maximumNumberofCovers - 1
                text: "Number of covers: " + (value + 1)
                textHorizontalAlignment: Text.AlignRight
                onValueChanged: {
                    currentState.numberOfCovers = (slider_modelSize.value + 1)
                }
            }
        }

        Row {
            id: cameraControls
            spacing: 40
            width: parent.width
            property int controlWidth: (cameraControls.width - cameraControls.spacing * 2) / 3

            Slider {
                id: slider_height
                value: 0.5
                width: cameraControls.controlWidth
                text: "Camera Height"
                enabled: currentState.currentViewType != CoverFlowType.Perspective
                onValueChanged: {
                    currentState.cameraHeight = -1.2 + 2 * (slider_height.value - 0.5)
                }
                onPressedChanged: {
                    idleTimer.reset(pressed)
                }
            }

            Slider {
                id: slider_viewAngle
                value: 0.5
                text: "View Angle"
                textHorizontalAlignment: Text.AlignHCenter
                width: cameraControls.controlWidth
                enabled: currentState.currentViewType != CoverFlowType.Perspective
                onValueChanged: {
                    currentState.viewAngle = -21 + 30 * (slider_viewAngle.value - 0.5)
                }
                onPressedChanged: {
                    idleTimer.reset(pressed)
                }
            }

            Item {
                width: cameraControls.controlWidth
                CheckBox {
                    id: checkbox_reflection
                    text: "Show reflections"
                    anchors.right: parent.right
                    checked: true
                    onCheckedChanged: {
                        currentState.showReflection = checkbox_reflection.checked
                    }
                }
            }
        }
    }

    SequentialAnimation {
        running: Configuration.enableViewAngleIdleAnimation
        loops: Animation.Infinite

        NumberAnimation { target: currentState; property: "viewAngle"; to: -12.0; duration: 5000}
        NumberAnimation { target: currentState; property: "viewAngle"; to: -21.0; duration: 5000}
    }
}