2
* Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
17
import "../Components"
18
import "Gradient.js" as Gradient
20
import Ubuntu.Components 0.1
27
property int animDuration: 10
32
onDataAppeared: startShowAnimation()
34
onDataAboutToChange: startHideAnimation()
36
onDataChanged: startShowAnimation()
38
onDataAboutToDisappear: startHideAnimation()
41
function startShowAnimation() {
42
dotShowAnimTimer.startFromBeginning()
43
notification.showAnim.start()
46
function startHideAnimation() {
47
dotHideAnimTimer.startFromBeginning()
48
notification.hideAnim.start()
51
visible: model.label !== ""
53
Component.onCompleted: startShowAnimation()
57
objectName: "dataCircle"
59
property real divisor: 1.5
61
width: Math.min(parent.height, parent.width) / divisor
64
anchors.centerIn: parent
67
id: circleGrowAnimTimer
69
property int pastCircleCounter
70
property int presentCircleCounter
72
interval: animDuration
76
if (pastCircleCounter < pastCircles.count) {
77
var nextCircle = pastCircles.itemAt(pastCircleCounter++)
78
if (nextCircle !== null) nextCircle.pastCircleGrowAnim.start()
80
if (pastCircleCounter > pastCircles.count / 2) {
81
var nextCircle = presentCircles.itemAt(presentCircleCounter++)
82
if (nextCircle !== null) nextCircle.presentCircleGrowAnim.start()
84
if (presentCircleCounter > infographic.model.currentDay) {
89
function startFromBeginning() {
90
circleGrowAnimTimer.pastCircleCounter = 0
91
circleGrowAnimTimer.presentCircleCounter = 0
97
id: circleShrinkAnimTimer
99
property int pastCircleCounter
100
property int presentCircleCounter
102
interval: animDuration
106
if (pastCircleCounter >= 0) {
107
var nextCircle = pastCircles.itemAt(pastCircleCounter--)
108
if (nextCircle !== null) nextCircle.pastCircleShrinkAnim.start()
110
if (pastCircleCounter < pastCircles.count / 2) {
111
var nextCircle = presentCircles.itemAt(presentCircleCounter--)
112
if (nextCircle !== null) nextCircle.presentCircleShrinkAnim.start()
114
if (presentCircleCounter < 0) {
116
infographic.model.readyForDataChange()
120
function startFromBeginning() {
121
pastCircleCounter = pastCircles.count - 1
122
presentCircleCounter = model.currentDay
129
objectName: "pastCircles"
130
model: infographic.model.secondMonth
132
delegate: ObjectPositioner {
133
property alias pastCircleGrowAnim: pastCircleGrowAnim
134
property alias pastCircleShrinkAnim: pastCircleShrinkAnim
137
count: pastCircles.count
138
radius: parent.width / 2
139
halfSize: pastCircle.width / 2
144
objectName: "pastCircle" + index
146
property real divisor: 1.8
147
property real circleOpacity: 0.1
149
width: dataCircle.width / divisor
150
height: dataCircle.height / divisor
153
visible: modelData !== undefined
154
color: Gradient.threeColorByIndex(index, count, infographic.model.secondColor)
156
SequentialAnimation {
157
id: pastCircleGrowAnim
165
to: pastCircle.circleOpacity
166
easing.type: Easing.OutCurve
167
duration: circleGrowAnimTimer.interval * 4
174
easing.type: Easing.OutCurve
175
duration: circleGrowAnimTimer.interval * 4
180
SequentialAnimation {
181
id: pastCircleShrinkAnim
188
from: pastCircle.circleOpacity
190
easing.type: Easing.OutCurve
191
duration: circleShrinkAnimTimer.interval * 4
198
easing.type: Easing.OutCurve
199
duration: circleShrinkAnimTimer.interval * 4
209
objectName: "presentCircles"
210
model: infographic.model.firstMonth
212
delegate: ObjectPositioner {
213
property alias presentCircleGrowAnim: presentCircleGrowAnim
214
property alias presentCircleShrinkAnim: presentCircleShrinkAnim
217
count: presentCircles.count
218
radius: parent.width / 2
219
halfSize: presentCircle.width / 2
224
objectName: "presentCircle" + index
226
property real divisor: 1.8
227
property real circleOpacity: 0.3
229
width: dataCircle.width / divisor
230
height: dataCircle.height / divisor
233
visible: modelData !== undefined
234
color: Gradient.threeColorByIndex(index, infographic.model.currentDay, infographic.model.firstColor)
236
SequentialAnimation {
237
id: presentCircleGrowAnim
243
target: presentCircle
245
to: presentCircle.circleOpacity
246
easing.type: Easing.OutCurve
247
duration: circleGrowAnimTimer.interval * 4
250
target: presentCircle
253
easing.type: Easing.OutCurve
254
duration: circleGrowAnimTimer.interval * 4
259
SequentialAnimation {
260
id: presentCircleShrinkAnim
265
target: presentCircle
268
easing.type: Easing.OutCurve
269
duration: circleShrinkAnimTimer.interval * 4
272
target: presentCircle
275
easing.type: Easing.OutCurve
276
duration: circleShrinkAnimTimer.interval * 4
286
objectName: "backgroundCircle"
291
source: "graphics/infographic_circle.png"
297
property int dotCounter: 0
299
interval: animDuration * 0.5; running: false; repeat: true
301
if (dotCounter < dots.count) {
302
var nextDot = dots.itemAt(dotCounter++)
303
nextDot.unlockAnimation.start()
307
if (dotCounter == Math.round(dots.count / 2)) {
308
circleGrowAnimTimer.startFromBeginning()
312
function startFromBeginning() {
313
if (!dotShowAnimTimer.running)
323
property int dotCounter
325
interval: animDuration * 0.5
329
if (dotCounter >= 0) {
330
var nextDot = dots.itemAt(dotCounter--)
331
nextDot.changeAnimation.start()
335
if (dotCounter == Math.round(dots.count / 2)) {
336
circleShrinkAnimTimer.startFromBeginning()
340
function startFromBeginning() {
341
if (!dotHideAnimTimer.running)
342
dotCounter = dots.count - 1
352
model: infographic.model.firstMonth
354
delegate: ObjectPositioner {
355
property alias unlockAnimation: dotUnlockAnim
356
property alias changeAnimation: dotChangeAnim
358
property int currentDay: infographic.model.currentDay
362
radius: backgroundCircle.width / 2
363
halfSize: dot.width / 2
364
posOffset: radius / dot.width / 3
369
objectName: "dot" + index
371
property real baseOpacity: 0.4
373
width: units.dp(5) * parent.radius / 200
374
height: units.dp(5) * parent.radius / 200
377
state: index < currentDay ? "filled" : index == currentDay ? "pointer" : "unfilled"
385
duration: dotShowAnimTimer.interval
394
duration: dotHideAnimTimer.interval
404
property alias hideAnim: decreaseOpacity
405
property alias showAnim: increaseOpacity
407
property real baseOpacity: 0.6
409
height: 0.7 * backgroundCircle.width
410
width: notification.height
411
anchors.centerIn: parent
413
text: infographic.model.label
414
font.pixelSize: notification.height / 12
416
wrapMode: Text.WordWrap
417
horizontalAlignment: Text.AlignHCenter
418
verticalAlignment: Text.AlignVCenter
420
font.weight: Font.Light
428
to: notification.baseOpacity
429
duration: dotShowAnimTimer.interval * dots.count * 5
437
from: notification.baseOpacity
439
duration: dotShowAnimTimer.interval * dots.count * 5
445
anchors.fill: dataCircle
448
if (!dotHideAnimTimer.running &&
449
!dotShowAnimTimer.running &&
450
!circleShrinkAnimTimer.running &&
451
!circleGrowAnimTimer.running)
452
infographic.model.nextDataSource()