~ubuntu-clock-dev/ubuntu-clock-app/reboot-packaging

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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
 * Copyright (C) 2014 Canonical Ltd
 *
 * This file is part of Ubuntu Clock App
 *
 * Ubuntu Clock App is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * Ubuntu Clock App is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import QtQuick 2.0
import Ubuntu.Components 1.1
import "Utils.js" as Utils

/*
 Generic clock component which has a digital and analog mode. A flip animation
 is shown when switching clock modes. This components is used by the main
 clock and the world clock list items.

 The component follows a parent-child model where certain functions are
 available only if used by a parent. You can set parent using the isMainClock
 variable. Some functions which are provided only to the parent are listed
 below,

 - Ability to switch clock modes by tapping on the center. As per design, only
   main clock app should allow switching mode by tapping at the center

 - Modify the user preference settings document to reflect the currently chosen
   clock mode. We don't want every child element modifying the file unnecessarily

 - Disable the clock hand in the child elements (world clock) as per the design
   spec.
*/
ClockCircle {
    id: _outerCircle

    // Property to set the analog time
    property var analogTime: new Date()

    // Property to set the digital time label
    property string time: Qt.formatTime(analogTime)

    // Property to keep track of the clock mode
    property alias isDigital: clockModeFlipable.isDigital

    // Properties to set the dimension of the clock like the font size, width etc
    property int fontSize
    property int periodFontSize
    property int innerCircleWidth

    // Property to set if the component is the parent or the child
    property bool isMainClock: false

    // Properties to expose the analog and digital modes
    property alias digitalModeLoader: _digitalModeLoader
    property alias analogModeLoader: _analogModeLoader

    // Signal which is triggered whenever the flip animation is started
    signal triggerFlip();

    function flipClock() {
        clockFlipAnimation.start()
    }

    // Sets the style to outer circle
    isOuter: true

    Shadow {
        id: upperShadow
        rotation: 0
        width: innerCircleWidth - units.gu(0.5)
        z: clockModeFlipable.z + 2
        anchors.centerIn: clockModeFlipable
        anchors.verticalCenterOffset: -width/4
    }

    Shadow {
        id: bottomShadow
        rotation: 180
        width: upperShadow.width
        z: clockModeFlipable.z + 2
        anchors.centerIn: clockModeFlipable
        anchors.verticalCenterOffset: width/4
    }

    Loader {
        id: analogShadow
        z: clockModeFlipable.isDigital ? clockModeFlipable.z + 1
                                       : clockModeFlipable.z + 3
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: clockModeFlipable.bottom
    }

    Loader {
        id: digitalShadow
        z: clockModeFlipable.isDigital ? clockModeFlipable.z + 3
                                       : clockModeFlipable.z + 1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: clockModeFlipable.bottom
    }

    Flipable {
        id: clockModeFlipable

        // Property to switch between digital and analog mode
        property bool isDigital: false

        width: innerCircleWidth
        height: width
        anchors.centerIn: parent

        front: Loader {
            id: _analogModeLoader
            anchors.centerIn: parent
        }

        back: Loader {
            id: _digitalModeLoader
            anchors.centerIn: parent
        }

        transform: Rotation {
            id: rotation
            origin.x: clockModeFlipable.width/2
            origin.y: clockModeFlipable.height/2
            axis.x: 1; axis.y: 0; axis.z: 0
            angle: 0
        }

        states: State {
            name: "Digital"
            when: clockModeFlipable.isDigital
            PropertyChanges {
                target: rotation
                angle: 180
            }
        }

        MouseArea {
            enabled: isMainClock
            anchors.fill: parent
            onClicked: {
                clockFlipAnimation.start()
            }
        }
    }

    /*
      The clockFlipAnimation is executed during every switch between
      analog and digital modes.
    */
    SequentialAnimation {
        id: clockFlipAnimation

        ScriptAction {
            script: {
                triggerFlip()
                analogShadow.setSource
                        ("AnalogShadow.qml",
                         {
                             "shadowWidth": innerCircleWidth,
                             "shadowTimeFontSize": fontSize,
                             "shadowPeriodFontSize": periodFontSize,
                             "showSeconds": isMainClock
                         })

                digitalShadow.setSource
                        ("DigitalShadow.qml",
                         {
                             "shadowWidth": innerCircleWidth,
                             "shadowTimeFontSize": fontSize,
                             "shadowPeriodFontSize": periodFontSize,
                             "showSeconds": isMainClock
                         })

                if (clockModeFlipable.isDigital) {
                    digitalShadow.item.isAnalog = true
                }
                else {
                    analogShadow.item.isDigital = true
                }
            }
        }

        PropertyAnimation {
            target: bottomShadow
            property: "opacity"
            duration: 333
            from: 1
            to: 0
        }

        PropertyAnimation {
            target: upperShadow
            property: "opacity"
            duration: 333
            from: 0
            to: 1
        }

        /*
          Script to clean up after the flip animation is complete which
          involves (in the order listed below)
            - Hiding the shadows
            - Toggling clock mode and unloading the hidden mode
            - Unloading the analog and digital shadow required to show the
              paper effect
        */

        ScriptAction {
            script: {
                upperShadow.opacity = bottomShadow.opacity = 0
                isDigital = !isDigital

                if (isDigital) {
                    _digitalModeLoader.setSource
                            ("DigitalMode.qml",
                             {
                                 "width": innerCircleWidth,
                                 "timeFontSize": fontSize,
                                 "timePeriodFontSize": periodFontSize
                             })
                    _analogModeLoader.source = ""
                }
                else {
                    _analogModeLoader.setSource
                            ("AnalogMode.qml",
                             {
                                 "width": innerCircleWidth,
                                 "showSeconds": isMainClock
                             })
                    _digitalModeLoader.source = ""
                }

                analogShadow.source = digitalShadow.source = ""

                if(isMainClock) {
                    var isDigitalSetting = JSON.parse
                            (JSON.stringify(clockModeDocument.contents))
                    isDigitalSetting.digitalMode = isDigital
                    clockModeDocument.contents = isDigitalSetting
                }
            }
        }
    }
}