~macslow/unity8/fix-1475678

« back to all changes in this revision

Viewing changes to Greeter/Infographics.qml

  • Committer: Michał Sawicz
  • Date: 2013-06-05 22:03:08 UTC
  • Revision ID: michal.sawicz@canonical.com-20130605220308-yny8fv3futtr04fg
Inital unity8 commit.

Previous history can be found at https://code.launchpad.net/~unity-team/unity/phablet

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2013 Canonical, Ltd.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; version 3.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 */
 
16
 
 
17
import "../Components"
 
18
import "Gradient.js" as Gradient
 
19
import QtQuick 2.0
 
20
import Ubuntu.Components 0.1
 
21
 
 
22
Item {
 
23
    id: infographic
 
24
 
 
25
    property var model
 
26
 
 
27
    property int animDuration: 10
 
28
 
 
29
    Connections {
 
30
        target: model
 
31
 
 
32
        onDataAppeared: startShowAnimation()
 
33
 
 
34
        onDataAboutToChange: startHideAnimation()
 
35
 
 
36
        onDataChanged: startShowAnimation()
 
37
 
 
38
        onDataAboutToDisappear: startHideAnimation()
 
39
    }
 
40
 
 
41
    function startShowAnimation() {
 
42
        dotShowAnimTimer.startFromBeginning()
 
43
        notification.showAnim.start()
 
44
    }
 
45
 
 
46
    function startHideAnimation() {
 
47
        dotHideAnimTimer.startFromBeginning()
 
48
        notification.hideAnim.start()
 
49
    }
 
50
 
 
51
    visible: model.label !== ""
 
52
 
 
53
    Component.onCompleted: startShowAnimation()
 
54
 
 
55
    Item {
 
56
        id: dataCircle
 
57
        objectName: "dataCircle"
 
58
 
 
59
        property real divisor: 1.5
 
60
 
 
61
        width: Math.min(parent.height, parent.width) / divisor
 
62
        height: width
 
63
 
 
64
        anchors.centerIn: parent
 
65
 
 
66
        Timer {
 
67
            id: circleGrowAnimTimer
 
68
 
 
69
            property int pastCircleCounter
 
70
            property int presentCircleCounter
 
71
 
 
72
            interval: animDuration
 
73
            running: false
 
74
            repeat: true
 
75
            onTriggered: {
 
76
                if (pastCircleCounter < pastCircles.count) {
 
77
                    var nextCircle = pastCircles.itemAt(pastCircleCounter++)
 
78
                    if (nextCircle !== null) nextCircle.pastCircleGrowAnim.start()
 
79
                }
 
80
                if (pastCircleCounter > pastCircles.count / 2) {
 
81
                    var nextCircle = presentCircles.itemAt(presentCircleCounter++)
 
82
                    if (nextCircle !== null) nextCircle.presentCircleGrowAnim.start()
 
83
                }
 
84
                if (presentCircleCounter > infographic.model.currentDay) {
 
85
                    stop()
 
86
                }
 
87
            }
 
88
 
 
89
            function startFromBeginning() {
 
90
                circleGrowAnimTimer.pastCircleCounter = 0
 
91
                circleGrowAnimTimer.presentCircleCounter = 0
 
92
                start()
 
93
            }
 
94
        }
 
95
 
 
96
        Timer {
 
97
            id: circleShrinkAnimTimer
 
98
 
 
99
            property int pastCircleCounter
 
100
            property int presentCircleCounter
 
101
 
 
102
            interval: animDuration
 
103
            running: false
 
104
            repeat: true
 
105
            onTriggered: {
 
106
                if (pastCircleCounter >= 0) {
 
107
                    var nextCircle = pastCircles.itemAt(pastCircleCounter--)
 
108
                    if (nextCircle !== null) nextCircle.pastCircleShrinkAnim.start()
 
109
                }
 
110
                if (pastCircleCounter < pastCircles.count / 2) {
 
111
                    var nextCircle = presentCircles.itemAt(presentCircleCounter--)
 
112
                    if (nextCircle !== null) nextCircle.presentCircleShrinkAnim.start()
 
113
                }
 
114
                if (presentCircleCounter < 0) {
 
115
                    stop()
 
116
                    infographic.model.readyForDataChange()
 
117
                }
 
118
            }
 
119
 
 
120
            function startFromBeginning() {
 
121
                pastCircleCounter = pastCircles.count - 1
 
122
                presentCircleCounter = model.currentDay
 
123
                start()
 
124
            }
 
125
        }
 
126
 
 
127
        Repeater {
 
128
            id: pastCircles
 
129
            objectName: "pastCircles"
 
130
            model: infographic.model.secondMonth
 
131
 
 
132
            delegate: ObjectPositioner {
 
133
                property alias pastCircleGrowAnim: pastCircleGrowAnim
 
134
                property alias pastCircleShrinkAnim: pastCircleShrinkAnim
 
135
 
 
136
                index: model.index
 
137
                count: pastCircles.count
 
138
                radius: parent.width / 2
 
139
                halfSize: pastCircle.width / 2
 
140
                posOffset: 0.0
 
141
 
 
142
                Circle {
 
143
                    id: pastCircle
 
144
                    objectName: "pastCircle" + index
 
145
 
 
146
                    property real divisor: 1.8
 
147
                    property real circleOpacity: 0.1
 
148
 
 
149
                    width: dataCircle.width / divisor
 
150
                    height: dataCircle.height / divisor
 
151
                    opacity: 0.0
 
152
                    scale: 0.0
 
153
                    visible: modelData !== undefined
 
154
                    color: Gradient.threeColorByIndex(index, count, infographic.model.secondColor)
 
155
 
 
156
                    SequentialAnimation {
 
157
                        id: pastCircleGrowAnim
 
158
 
 
159
                        loops: 1
 
160
                        ParallelAnimation {
 
161
                            PropertyAnimation {
 
162
                                target: pastCircle
 
163
                                property: "opacity"
 
164
                                from: 0.0
 
165
                                to: pastCircle.circleOpacity
 
166
                                easing.type: Easing.OutCurve
 
167
                                duration: circleGrowAnimTimer.interval * 4
 
168
                            }
 
169
                            PropertyAnimation {
 
170
                                target: pastCircle
 
171
                                property: "scale"
 
172
                                from: 0.0
 
173
                                to: modelData
 
174
                                easing.type: Easing.OutCurve
 
175
                                duration: circleGrowAnimTimer.interval * 4
 
176
                            }
 
177
                        }
 
178
                    }
 
179
 
 
180
                    SequentialAnimation {
 
181
                        id: pastCircleShrinkAnim
 
182
 
 
183
                        loops: 1
 
184
                        ParallelAnimation {
 
185
                            PropertyAnimation {
 
186
                                target: pastCircle
 
187
                                property: "opacity"
 
188
                                from: pastCircle.circleOpacity
 
189
                                to: 0.0
 
190
                                easing.type: Easing.OutCurve
 
191
                                duration: circleShrinkAnimTimer.interval * 4
 
192
                            }
 
193
                            PropertyAnimation {
 
194
                                target: pastCircle
 
195
                                property: "scale"
 
196
                                from: modelData
 
197
                                to: 0.0
 
198
                                easing.type: Easing.OutCurve
 
199
                                duration: circleShrinkAnimTimer.interval * 4
 
200
                            }
 
201
                        }
 
202
                    }
 
203
                }
 
204
            }
 
205
        }
 
206
 
 
207
        Repeater {
 
208
            id: presentCircles
 
209
            objectName: "presentCircles"
 
210
            model: infographic.model.firstMonth
 
211
 
 
212
            delegate: ObjectPositioner {
 
213
                property alias presentCircleGrowAnim: presentCircleGrowAnim
 
214
                property alias presentCircleShrinkAnim: presentCircleShrinkAnim
 
215
 
 
216
                index: model.index
 
217
                count: presentCircles.count
 
218
                radius: parent.width / 2
 
219
                halfSize: presentCircle.width / 2
 
220
                posOffset: 0.0
 
221
 
 
222
                Circle {
 
223
                    id: presentCircle
 
224
                    objectName: "presentCircle" + index
 
225
 
 
226
                    property real divisor: 1.8
 
227
                    property real circleOpacity: 0.3
 
228
 
 
229
                    width: dataCircle.width / divisor
 
230
                    height: dataCircle.height / divisor
 
231
                    opacity: 0.0
 
232
                    scale: 0.0
 
233
                    visible: modelData !== undefined
 
234
                    color: Gradient.threeColorByIndex(index, infographic.model.currentDay, infographic.model.firstColor)
 
235
 
 
236
                    SequentialAnimation {
 
237
                        id: presentCircleGrowAnim
 
238
 
 
239
                        loops: 1
 
240
 
 
241
                        ParallelAnimation {
 
242
                            PropertyAnimation {
 
243
                                target: presentCircle
 
244
                                property: "opacity"
 
245
                                to: presentCircle.circleOpacity
 
246
                                easing.type: Easing.OutCurve
 
247
                                duration: circleGrowAnimTimer.interval * 4
 
248
                            }
 
249
                            PropertyAnimation {
 
250
                                target: presentCircle
 
251
                                property: "scale"
 
252
                                to: modelData
 
253
                                easing.type: Easing.OutCurve
 
254
                                duration: circleGrowAnimTimer.interval * 4
 
255
                            }
 
256
                        }
 
257
                    }
 
258
 
 
259
                    SequentialAnimation {
 
260
                        id: presentCircleShrinkAnim
 
261
 
 
262
                        loops: 1
 
263
                        ParallelAnimation {
 
264
                            PropertyAnimation {
 
265
                                target: presentCircle
 
266
                                property: "opacity"
 
267
                                to: 0.0
 
268
                                easing.type: Easing.OutCurve
 
269
                                duration: circleShrinkAnimTimer.interval * 4
 
270
                            }
 
271
                            PropertyAnimation {
 
272
                                target: presentCircle
 
273
                                property: "scale"
 
274
                                to: 0.0
 
275
                                easing.type: Easing.OutCurve
 
276
                                duration: circleShrinkAnimTimer.interval * 4
 
277
                            }
 
278
                        }
 
279
                    }
 
280
                }
 
281
            }
 
282
        }
 
283
 
 
284
        Image {
 
285
            id: backgroundCircle
 
286
            objectName: "backgroundCircle"
 
287
 
 
288
            anchors.fill: parent
 
289
            opacity: 0.9
 
290
 
 
291
            source: "graphics/infographic_circle.png"
 
292
        }
 
293
 
 
294
        Timer {
 
295
            id: dotShowAnimTimer
 
296
 
 
297
            property int dotCounter: 0
 
298
 
 
299
            interval: animDuration * 0.5; running: false; repeat: true
 
300
            onTriggered: {
 
301
                if (dotCounter < dots.count) {
 
302
                    var nextDot = dots.itemAt(dotCounter++)
 
303
                    nextDot.unlockAnimation.start()
 
304
                } else {
 
305
                    stop()
 
306
                }
 
307
                if (dotCounter == Math.round(dots.count / 2)) {
 
308
                    circleGrowAnimTimer.startFromBeginning()
 
309
                }
 
310
            }
 
311
 
 
312
            function startFromBeginning() {
 
313
                if (!dotShowAnimTimer.running)
 
314
                    dotCounter = 0
 
315
 
 
316
                start()
 
317
            }
 
318
        }
 
319
 
 
320
        Timer {
 
321
            id: dotHideAnimTimer
 
322
 
 
323
            property int dotCounter
 
324
 
 
325
            interval: animDuration * 0.5
 
326
            running: false
 
327
            repeat: true
 
328
            onTriggered: {
 
329
                if (dotCounter >= 0) {
 
330
                    var nextDot = dots.itemAt(dotCounter--)
 
331
                    nextDot.changeAnimation.start()
 
332
                } else {
 
333
                    stop()
 
334
                }
 
335
                if (dotCounter == Math.round(dots.count / 2)) {
 
336
                    circleShrinkAnimTimer.startFromBeginning()
 
337
                }
 
338
            }
 
339
 
 
340
            function startFromBeginning() {
 
341
                if (!dotHideAnimTimer.running)
 
342
                    dotCounter = dots.count - 1
 
343
 
 
344
                start()
 
345
            }
 
346
        }
 
347
 
 
348
        Repeater {
 
349
            id: dots
 
350
            objectName: "dots"
 
351
 
 
352
            model: infographic.model.firstMonth
 
353
 
 
354
            delegate: ObjectPositioner {
 
355
                property alias unlockAnimation: dotUnlockAnim
 
356
                property alias changeAnimation: dotChangeAnim
 
357
 
 
358
                property int currentDay: infographic.model.currentDay
 
359
 
 
360
                index: model.index
 
361
                count: dots.count
 
362
                radius: backgroundCircle.width / 2
 
363
                halfSize: dot.width / 2
 
364
                posOffset: radius / dot.width / 3
 
365
                state: dot.state
 
366
 
 
367
                Dot {
 
368
                    id: dot
 
369
                    objectName: "dot" + index
 
370
 
 
371
                    property real baseOpacity: 0.4
 
372
 
 
373
                    width: units.dp(5) * parent.radius / 200
 
374
                    height: units.dp(5) * parent.radius / 200
 
375
                    opacity: 0.0
 
376
                    smooth: true
 
377
                    state: index < currentDay ? "filled" : index == currentDay ? "pointer" : "unfilled"
 
378
 
 
379
                    PropertyAnimation {
 
380
                        id: dotUnlockAnim
 
381
 
 
382
                        target: dot
 
383
                        property: "opacity"
 
384
                        to: dot.baseOpacity
 
385
                        duration: dotShowAnimTimer.interval
 
386
                    }
 
387
 
 
388
                    PropertyAnimation {
 
389
                        id: dotChangeAnim
 
390
 
 
391
                        target: dot
 
392
                        property: "opacity"
 
393
                        to: 0.0
 
394
                        duration: dotHideAnimTimer.interval
 
395
                    }
 
396
                }
 
397
            }
 
398
        }
 
399
 
 
400
        Text {
 
401
            id: notification
 
402
            objectName: "label"
 
403
 
 
404
            property alias hideAnim: decreaseOpacity
 
405
            property alias showAnim: increaseOpacity
 
406
 
 
407
            property real baseOpacity: 0.6
 
408
 
 
409
            height: 0.7 * backgroundCircle.width
 
410
            width: notification.height
 
411
            anchors.centerIn: parent
 
412
 
 
413
            text: infographic.model.label
 
414
            font.pixelSize: notification.height / 12
 
415
 
 
416
            wrapMode: Text.WordWrap
 
417
            horizontalAlignment: Text.AlignHCenter
 
418
            verticalAlignment: Text.AlignVCenter
 
419
            color: "white"
 
420
            font.weight: Font.Light
 
421
 
 
422
            PropertyAnimation {
 
423
                id: increaseOpacity
 
424
 
 
425
                target: notification
 
426
                property: "opacity"
 
427
                from: 0.0
 
428
                to: notification.baseOpacity
 
429
                duration: dotShowAnimTimer.interval * dots.count * 5
 
430
            }
 
431
 
 
432
            PropertyAnimation {
 
433
                id: decreaseOpacity
 
434
 
 
435
                target: notification
 
436
                property: "opacity"
 
437
                from: notification.baseOpacity
 
438
                to: 0.0
 
439
                duration: dotShowAnimTimer.interval * dots.count * 5
 
440
            }
 
441
        }
 
442
    }
 
443
 
 
444
    MouseArea {
 
445
        anchors.fill: dataCircle
 
446
 
 
447
        onDoubleClicked: {
 
448
            if (!dotHideAnimTimer.running &&
 
449
                    !dotShowAnimTimer.running &&
 
450
                    !circleShrinkAnimTimer.running &&
 
451
                    !circleGrowAnimTimer.running)
 
452
                infographic.model.nextDataSource()
 
453
        }
 
454
    }
 
455
}