1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Extras module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40import QtQuick 2.2
41import QtGraphicalEffects 1.0
42import QtQuick.Controls.Styles 1.4
43import QtQuick.Extras 1.4
44import QtQuick.Extras.Private.CppUtils 1.1
45
46/*!
47    \qmltype DelayButtonStyle
48    \inqmlmodule QtQuick.Controls.Styles
49    \since 5.5
50    \ingroup controlsstyling
51    \brief Provides custom styling for DelayButton.
52
53    You can create a custom DelayButton by replacing the following delegates:
54    \list
55        \li \l foreground
56        \li \l {ButtonStyle::}{label}
57    \endlist
58*/
59
60CircularButtonStyle {
61    id: delayButtonStyle
62
63    /*!
64        The \l DelayButton that this style is attached to.
65    */
66    readonly property DelayButton control: __control
67
68    /*!
69        The gradient of the progress bar around the button.
70    */
71    property Gradient progressBarGradient: Gradient {
72        GradientStop {
73            position: 0
74            color: "#ff6666"
75        }
76        GradientStop {
77            position: 1
78            color: "#ff0000"
79        }
80    }
81
82    /*!
83        The color of the drop shadow under the progress bar.
84    */
85    property color progressBarDropShadowColor: "#ff6666"
86
87    background: Item {
88        implicitWidth: __buttonHelper.implicitWidth
89        implicitHeight: __buttonHelper.implicitHeight
90
91        Canvas {
92            id: backgroundCanvas
93            anchors.fill: parent
94
95            Connections {
96                target: control
97                function onPressedChanged() { backgroundCanvas.requestPaint() }
98                function onCheckedChanged() { backgroundCanvas.requestPaint() }
99            }
100
101            onPaint: {
102                var ctx = getContext("2d");
103                __buttonHelper.paintBackground(ctx);
104            }
105        }
106    }
107
108    /*!
109        The foreground of the button.
110
111        The progress bar is drawn here.
112    */
113    property Component foreground: Item {
114        id: foregroundItem
115
116        state: "normal"
117        states: [
118            State {
119                name: "normal"
120
121                PropertyChanges {
122                    target: foregroundItem
123                    opacity: 1
124                }
125            },
126            State {
127                name: "activated"
128            }
129        ]
130
131        transitions: [
132            Transition {
133                from: "normal"
134                to: "activated"
135                SequentialAnimation {
136                    loops: Animation.Infinite
137
138                    NumberAnimation {
139                        target: foregroundItem
140                        property: "opacity"
141                        from: 0.8
142                        to: 0
143                        duration: 500
144                        easing.type: Easing.InOutSine
145                    }
146                    NumberAnimation {
147                        target: foregroundItem
148                        property: "opacity"
149                        from: 0
150                        to: 0.8
151                        duration: 500
152                        easing.type: Easing.InOutSine
153                    }
154                }
155            }
156        ]
157
158        Connections {
159            target: control
160            function onActivated() { state = "activated" }
161            function onCheckedChanged() { if (!control.checked) state = "normal" }
162        }
163
164        CircularProgressBar {
165            id: progressBar
166            visible: false
167            width: Math.min(parent.width, parent.height) + progressBarDropShadow.radius * 3 * 2
168            height: width
169            anchors.centerIn: parent
170            antialiasing: true
171            barWidth: __buttonHelper.outerArcLineWidth
172            inset: progressBarDropShadow.radius * 3
173            minimumValueAngle: -180
174            maximumValueAngle: 180
175
176            progress: control.progress
177
178            // TODO: Add gradient property if/when we drop support for building with 5.1.
179            function updateGradient() {
180                clearStops();
181                for (var i = 0; i < progressBarGradient.stops.length; ++i) {
182                    addStop(progressBarGradient.stops[i].position, progressBarGradient.stops[i].color);
183                }
184            }
185
186            Component.onCompleted: updateGradient()
187
188            Connections {
189                target: delayButtonStyle
190                function onProgressBarGradientChanged() { progressBar.updateGradient() }
191            }
192        }
193
194        DropShadow {
195            id: progressBarDropShadow
196            anchors.fill: progressBar
197            // QTBUG-33747
198//            cached: !control.pressed
199            color: progressBarDropShadowColor
200            source: progressBar
201        }
202    }
203
204    panel: Item {
205        implicitWidth: backgroundLoader.implicitWidth
206        implicitHeight: backgroundLoader.implicitHeight
207
208        Loader {
209            id: backgroundLoader
210            anchors.fill: parent
211            sourceComponent: background
212        }
213
214        Loader {
215            id: foregroundLoader
216            anchors.fill: parent
217            sourceComponent: foreground
218        }
219
220        Loader {
221            id: labelLoader
222            sourceComponent: label
223            anchors.fill: parent
224            anchors.leftMargin: padding.left
225            anchors.topMargin: padding.top
226            anchors.rightMargin: padding.right
227            anchors.bottomMargin: padding.bottom
228        }
229    }
230}
231