summaryrefslogtreecommitdiff
path: root/controls/SmoothFadeLoader.qml
blob: 0c76a6711af9ae9251661cfd24785976e35f890f (plain) (blame)
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * This file is part of Fluid.
 *
 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
 *
 * $BEGIN_LICENSE:MPL2$
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * $END_LICENSE$
 */

import QtQuick 2.0

/*!
    \qmltype SmoothFadeLoader
    \inqmlmodule Fluid.Controls
    \ingroup fluidcontrols

    \brief Displays an item and smoothly fade when the source is changed.

    This component loads an item with a Loader and smoothly fade to another item when
    the source URL is changed.

    Items are loaded synchronously, also the item being hidden is not unloaded to
    avoid an unpleasant "flash" after the transition.

    Example of usage:
    \code
    import QtQuick 2.0
    import Fluid.Controls 1.0

    Item {
        width: 640
        height: 480

        SmoothFadeLoader {
            anchors.fill: parent
            source: "MyComponent.qml"
            fadeDuration: 400

            MouseArea {
                anchors.fill: parent
                onClicked: parent.source = "AnotherComponent.qml"
            }
        }
    }
    \endcode
*/
Item {
    /*!
        The item being displayed.

        \sa Loader::source
    */
    property url source

    /*!
        Set this to change the fade animation time (in milliseconds).
        Default value is 250 ms.
    */
    property int fadeDuration: 250

    /*!
        This property holds whether the fade animation is running or not.
    */
    readonly property bool running: animation.running

    id: root
    onSourceChanged: {
        animation.running = false;

        if (__priv.currentLoader == loader1) {
            __priv.currentLoader = loader2;
            __priv.nextLoader = loader1;
        } else {
            __priv.currentLoader = loader1;
            __priv.nextLoader = loader2;
        }

        __priv.currentLoader.source = sourceUrl;
        __priv.currentLoader.opacity = 0;
        __priv.currentLoader.z = 1;
        __priv.nextLoader.z = 0;

        if (__priv.firstTime) {
            __priv.currentLoader.opacity = 1.0;
            __priv.nextLoader.opacity = 0.0;
            __priv.firstTime = false;
        } else {
            animation.running = true;
        }
    }

    QtObject {
        id: __priv

        property bool firstTime: true
        property Loader currentLoader: loader1
        property Loader nextLoader: loader2
    }

    SequentialAnimation {
        id: animation
        running: false

        NumberAnimation {
            target: __priv.currentLoader
            properties: "opacity"
            from: 0.0
            to: 1.0
            duration: root.fadeDuration
            easing.type: Easing.OutQuad
        }

        ScriptAction {
            script: {
                __priv.nextLoader.opacity = 0;
                //__priv.nextLoader.source = "";
            }
        }
    }

    Loader {
        id: loader1
        anchors.fill: parent
        z: 1
    }

    Loader {
        id: loader2
        anchors.fill: parent
        z: 0
    }
}