aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrols/macos/impl/SwitchIndicator.qml
blob: 33b6f5ca5fb4b78bce2202ef2f1429c74a09868e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

import QtQuick
import QtQuick.Templates as T

Rectangle {
    id: indicator
    implicitWidth: 38
    implicitHeight: 22
    radius: implicitHeight / 2

    required property T.AbstractButton control
    readonly property real downTintFactor: 1.05

    // For QQuickMacFocusFrame.
    readonly property real __focusFrameRadius: radius

    color: Qt.styleHints.colorScheme === Qt.Light
        ? Qt.darker(indicator.control.checked
            ? indicator.palette.accent : "#d9d6d2", indicator.control.down ? indicator.downTintFactor : 1)
        : Qt.lighter(indicator.control.checked
            ? indicator.palette.accent : "#454545", indicator.control.down ? indicator.downTintFactor : 1)

    states: [
        State {
            name: "checked"
            when: indicator.control.checked

            // Do a bit of duplication with the bindings here just so that
            // we can trigger the property change for the transition. We only
            // the ColorAnimation to happen when changing checked state.
            PropertyChanges {
                target: indicator
                color: Qt.styleHints.colorScheme === Qt.Light
                    ? indicator.control.checked ? indicator.palette.accent : "#d9d6d2"
                    : indicator.control.checked ? indicator.palette.accent : "#454545"
            }
        }
    ]

    transitions: Transition {
        ColorAnimation {
            targets: indicator
            property: "color"
            // We try to match the speed of x's SmoothedAnimation below,
            // and 17 pixels (handle travel distance) / 75 pixels a second = 0.226.
            duration: 226
            easing.type: Easing.InOutQuad
        }
    }

    // Since an equivalent to InnerShadow doesn't exist in Qt 6 (QTBUG-116161),
    // we approximate it using semi-transparent rectangle borders.
    Rectangle {
        width: parent.width
        height: parent.height
        radius: height / 2
        color: "transparent"
        border.color: Qt.styleHints.colorScheme === Qt.Light
            ? Qt.darker("#06000000", indicator.control.down ? indicator.downTintFactor : 1)
            : Qt.lighter("#1affffff", indicator.control.down ? indicator.downTintFactor : 1)

        Rectangle {
            x: 1
            y: 1
            implicitWidth: parent.width - 2
            implicitHeight: parent.height - 2
            radius: parent.radius
            color: "transparent"
            border.color: Qt.styleHints.colorScheme === Qt.Light
                ? Qt.darker("#02000000", indicator.control.down ? indicator.downTintFactor : 1)
                : Qt.lighter("#04ffffff", indicator.control.down ? indicator.downTintFactor : 1)
        }
    }

    SwitchHandle {
        id: handle
        x: Math.max(1, Math.min(parent.width - width - 1, indicator.control.visualPosition * parent.width - (width / 2)))
        y: (parent.height - height) / 2
        down: indicator.control.down

        // We have this here because we don't want this behavior for RangeSlider,
        // which also uses SwitchHandle.
        Behavior on x {
            enabled: !handle.down

            SmoothedAnimation {
                velocity: 200
            }
        }
    }
}