~mterry/+junk/u8.2

« back to all changes in this revision

Viewing changes to qml/Hud/Hud.qml

  • Committer: Michael Terry
  • Date: 2014-11-17 14:56:04 UTC
  • mfrom: (1317.1.118 unity8)
  • Revision ID: michael.terry@canonical.com-20141117145604-96dn9p5nwkifq2f4
MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2012, 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 QtQuick 2.0
18
 
import Ubuntu.Components 0.1
19
 
import HudClient 0.1
20
 
 
21
 
import "../Components"
22
 
import "../Components/Flickables" as Flickables
23
 
 
24
 
Item {
25
 
    id: hud
26
 
 
27
 
    readonly property real elementsPadding: units.gu(1)
28
 
    readonly property real elementsYSliding: units.gu(2)
29
 
 
30
 
    property alias revealerTarget: hudShowable
31
 
    property alias showAnimation: hudShowable.showAnimation
32
 
    property alias hideAnimation: hudShowable.hideAnimation
33
 
    property alias available: hudShowable.available
34
 
    property alias shown: hudShowable.shown
35
 
    property alias handleHeight: handle.height
36
 
 
37
 
    readonly property variant outEasing: Easing.OutQuad
38
 
    readonly property variant inEasing: Easing.InQuad
39
 
    readonly property int animationDuration: 200
40
 
    readonly property int showableAnimationDuration: 100
41
 
    property bool showingOpenIndicator: false
42
 
 
43
 
    // FIXME At the moment since we have no appstack
44
 
    // it's not possible to get results of the sidestage app
45
 
    // design has to come up with a solution
46
 
    function show() {
47
 
        hudShowable.show()
48
 
    }
49
 
    function hide() {
50
 
        hudShowable.hide()
51
 
    }
52
 
    function resetToInitialState() {
53
 
        hud.state = "initial"
54
 
        searchBar.unfocus()
55
 
        searchBar.text = ""
56
 
        parametrizedActionsPage.shown = false
57
 
    }
58
 
 
59
 
    states: [
60
 
        State {
61
 
            name: "initial"
62
 
            PropertyChanges { target: searchBar; placeholderText: i18n.tr("Type or say a command") }
63
 
            PropertyChanges { target: searchBar; searchEnabled: true }
64
 
            PropertyChanges { target: toolBarAnimator; visible: true}
65
 
            AnchorChanges { target: searchBarAnimator; anchors.top: undefined; anchors.bottom: parent.bottom; }
66
 
            AnchorChanges { target: resultsCardAnimator; anchors.top: undefined; anchors.bottom: toolBarAnimator.top; }
67
 
        },
68
 
        State {
69
 
            name: "input" //only inherited by other states.
70
 
            AnchorChanges { target: searchBarAnimator; anchors.top: parent.top; anchors.bottom: undefined; }
71
 
            AnchorChanges { target: resultsCardAnimator; anchors.top: searchBarAnimator.bottom; anchors.bottom: undefined; }
72
 
            PropertyChanges { target: toolBarAnimator; visible: false }
73
 
        },
74
 
        State {
75
 
            name: "voice_input" //only inherited by other states.
76
 
            extend: "input"
77
 
            PropertyChanges { target: soundAmplitudeVisualAnimator; visible: true }
78
 
            PropertyChanges { target: resultsCardAnimator; visible: false }
79
 
            PropertyChanges { target: soundAmplitudeVisualAnimator; progress: 1 }
80
 
            PropertyChanges { target: searchBar; searchEnabled: false }
81
 
        },
82
 
        State {
83
 
            name: "voice_recognition_loading"
84
 
            extend: "voice_input"
85
 
            PropertyChanges { target: searchBar; placeholderText: i18n.tr("Loading. Please Wait...") }
86
 
        },
87
 
        State {
88
 
            name: "voice_recognition_listening"
89
 
            extend: "voice_input"
90
 
            PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speak Now...") }
91
 
        },
92
 
        State {
93
 
            name: "voice_recognition_processing"
94
 
            extend: "voice_input"
95
 
            PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speaking...") }
96
 
        },
97
 
        State {
98
 
            name: "showing_results"
99
 
            extend: "input"
100
 
            PropertyChanges { target: searchBar; placeholderText: i18n.tr("Type or say a command") }
101
 
            PropertyChanges { target: searchBar; searchEnabled: true }
102
 
        }
103
 
    ]
104
 
 
105
 
    transitions: [
106
 
        Transition {
107
 
            from: "initial"
108
 
            to: "voice_recognition_loading"
109
 
            SequentialAnimation {
110
 
                NumberAnimation { // hide these components
111
 
                    targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
112
 
                    property: "progress"; duration: animationDuration; to: 0
113
 
                }
114
 
 
115
 
                PropertyAction { targets: [toolBarAnimator, resultsCardAnimator]; property: "visible"; value: false}
116
 
                PropertyAction { target: soundAmplitudeVisualAnimator; property: "visible"; value: true}
117
 
 
118
 
                AnchorAnimation { duration: 0 } // so anchor change happens at this point
119
 
 
120
 
                NumberAnimation { // show these components
121
 
                    targets: [searchBarAnimator, soundAmplitudeVisualAnimator]
122
 
                    property: "progress"; duration: animationDuration; from: 0; to: 1
123
 
                }
124
 
            }
125
 
        },
126
 
        Transition {
127
 
            from: "showing_results"
128
 
            to: "voice_recognition_loading"
129
 
            SequentialAnimation {
130
 
                PropertyAction { target: soundAmplitudeVisualAnimator; property: "progress"; value: 0}
131
 
 
132
 
                PropertyAction { // hide these components
133
 
                    target: resultsCardAnimator; property: "progress"; value: 0
134
 
                }
135
 
 
136
 
                NumberAnimation { // show these components
137
 
                    target: soundAmplitudeVisualAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
138
 
                }
139
 
            }
140
 
        },
141
 
        Transition {
142
 
            from: "voice_recognition_processing"
143
 
            to: "showing_results"
144
 
            SequentialAnimation {
145
 
                NumberAnimation { // hide these components
146
 
                    target: soundAmplitudeVisualAnimator; property: "progress"; duration: animationDuration; to: 0
147
 
                }
148
 
                PropertyAction { target: resultsCardAnimator; property: "visible"; value: true}
149
 
 
150
 
                NumberAnimation { // show these components
151
 
                    target: resultsCardAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
152
 
                }
153
 
            }
154
 
        },
155
 
        Transition {
156
 
            from: "initial"
157
 
            to: "showing_results"
158
 
            SequentialAnimation {
159
 
                NumberAnimation {
160
 
                    targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
161
 
                    property: "progress"; duration: animationDuration; to: 0
162
 
                }
163
 
 
164
 
                PropertyAction { target: toolBarAnimator; property: "visible"; value: false}
165
 
 
166
 
                AnchorAnimation { duration: 0 } // so anchor change happens at this point
167
 
 
168
 
                NumberAnimation {
169
 
                    targets: [searchBarAnimator, resultsCardAnimator]
170
 
                    property: "progress"; duration: animationDuration; from: 0; to: 1
171
 
                }
172
 
            }
173
 
        }
174
 
    ]
175
 
 
176
 
    state: "initial"
177
 
 
178
 
    HudClient {
179
 
        id: hudClient
180
 
 
181
 
        onCommandExecuted: {
182
 
            hudShowable.hide()
183
 
        }
184
 
 
185
 
        onShowParametrizedAction: {
186
 
            parametrizedActionsPage.header = action
187
 
            parametrizedActionsPage.setItems(items)
188
 
            parametrizedActionsPage.shown = true
189
 
        }
190
 
 
191
 
        onVoiceQueryLoading: {
192
 
            hud.state = "voice_recognition_loading"
193
 
            searchBar.ignoreNextTextChange = true
194
 
            searchBar.text = ""
195
 
            searchBar.unfocus()
196
 
            soundAmplitudeVisual.startIdle()
197
 
        }
198
 
        onVoiceQueryListening: {
199
 
            if (hud.state == "voice_recognition_loading" || hud.state == "showing_results") {
200
 
                searchBar.ignoreNextTextChange = true
201
 
                searchBar.text = ""
202
 
                searchBar.unfocus()
203
 
                hud.state = "voice_recognition_listening"
204
 
            }
205
 
        }
206
 
        onVoiceQueryHeardSomething: {
207
 
            if (hud.state == "voice_recognition_listening") {
208
 
                hud.state = "voice_recognition_processing"
209
 
                soundAmplitudeVisual.setDetectorEnabled(true)
210
 
            }
211
 
        }
212
 
        onVoiceQueryFinished: {
213
 
            hud.state = "showing_results"
214
 
            searchBar.text = query
215
 
            soundAmplitudeVisual.setDetectorEnabled(false)
216
 
        }
217
 
        onVoiceQueryFailed: {
218
 
            hud.state = "showing_results"
219
 
            searchBar.text = ""
220
 
            soundAmplitudeVisual.setDetectorEnabled(false)
221
 
        }
222
 
    }
223
 
 
224
 
    Showable {
225
 
        id: hudShowable
226
 
        objectName: "hudShowable"
227
 
        height: parent.height
228
 
        width: parent.width
229
 
 
230
 
        onYChanged: {
231
 
            if (greeter.shown) {
232
 
                showAnimation.duration = 0
233
 
                hideAnimation.duration = 0
234
 
            } else if (!showAnimation.running && !hideAnimation.running) {
235
 
                if (parent.height > 0) {
236
 
                    showAnimation.duration = Math.min(showableAnimationDuration * (1 - (parent.height - y) / parent.height), showableAnimationDuration)
237
 
                    hideAnimation.duration = showableAnimationDuration - showAnimation.duration
238
 
                }
239
 
            }
240
 
        }
241
 
 
242
 
        MouseArea {
243
 
            // Eat everything that doesn't go to other places
244
 
            anchors.fill: parent
245
 
        }
246
 
 
247
 
        Image {
248
 
            anchors.fill: parent
249
 
            fillMode: Image.Tile
250
 
            source: "graphics/hud_bg.png"
251
 
        }
252
 
 
253
 
        Connections {
254
 
            target: hideAnimation
255
 
            onRunningChanged: {
256
 
                if (!hideAnimation.running) {
257
 
                    showAnimation.duration = showableAnimationDuration
258
 
                    hud.resetToInitialState()
259
 
                }
260
 
            }
261
 
        }
262
 
 
263
 
        Connections {
264
 
            target: showAnimation
265
 
            onRunningChanged: {
266
 
                if (!showAnimation.running) {
267
 
                    hideAnimation.duration = showableAnimationDuration
268
 
                }
269
 
            }
270
 
        }
271
 
    }
272
 
 
273
 
    Item {
274
 
        id: handle
275
 
        objectName: "handle"
276
 
 
277
 
        y: hudShowable.y
278
 
        anchors {
279
 
            left: parent.left
280
 
            right: parent.right
281
 
        }
282
 
        height: handleImage.height
283
 
 
284
 
        Image {
285
 
            id: handleImage
286
 
            anchors {
287
 
                left: parent.left
288
 
                right: parent.right
289
 
            }
290
 
            source: "graphics/hud_handlebar.png"
291
 
        }
292
 
 
293
 
        Image {
294
 
            id: handleArrow
295
 
            y: units.gu(1)
296
 
            anchors.horizontalCenter: parent.horizontalCenter
297
 
            source: "graphics/hud_handlearrow.png"
298
 
            cache: false
299
 
        }
300
 
    }
301
 
 
302
 
    Item {
303
 
        id: hudContentClipper
304
 
 
305
 
        anchors {
306
 
            left: parent.left
307
 
            right: parent.right
308
 
            bottom: parent.bottom
309
 
            top: handle.bottom
310
 
        }
311
 
        clip: visible && hudContent.height !== height
312
 
        visible: hudContent.height >= 0
313
 
 
314
 
        Item {
315
 
            id: hudContent
316
 
            anchors {
317
 
                left: parent.left
318
 
                right: parent.right
319
 
                bottom: parent.bottom
320
 
            }
321
 
            height: hud.height
322
 
 
323
 
            Item {
324
 
                id: mainPage
325
 
                x: parametrizedActionsPage.x - width
326
 
                height: hud.height
327
 
                width: hud.width
328
 
 
329
 
                ShowingAnimation {
330
 
                    id: toolBarAnimator
331
 
                    objectName: "toolBarAnimator"
332
 
                    anchors {
333
 
                        left: parent.left
334
 
                        right: parent.right
335
 
                        bottom: searchBarAnimator.top
336
 
                        margins: 2*elementsPadding //ensures positioning correct
337
 
                    }
338
 
                    progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
339
 
 
340
 
                    ToolBar {
341
 
                        id: toolBar
342
 
                        objectName: "toolBar"
343
 
                        model: hudClient.toolBarModel
344
 
                        anchors.horizontalCenter: parent.horizontalCenter
345
 
                        onActionTriggered: {
346
 
                            hudClient.executeToolBarAction(action)
347
 
                        }
348
 
                    }
349
 
                }
350
 
 
351
 
                ShowingAnimation {
352
 
                    id: searchBarAnimator
353
 
                    objectName: "searchBarAnimator"
354
 
                    anchors {
355
 
                        left: parent.left
356
 
                        right: parent.right
357
 
                        bottom: parent.bottom
358
 
                        margins: elementsPadding
359
 
                        topMargin: handle.height + units.dp(1) + elementsPadding
360
 
                    }
361
 
                    progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
362
 
 
363
 
                    SearchBar {
364
 
                        id: searchBar
365
 
                        objectName: "searchBar"
366
 
 
367
 
                        property bool ignoreNextTextChange: false
368
 
 
369
 
                        anchors.left: parent.left
370
 
                        anchors.right: parent.right
371
 
                        height: units.gu(5)
372
 
 
373
 
                        placeholderText: i18n.tr("Type or say a command")
374
 
                        activityIndicatorVisible: hud.state == "voice_recognition_processing"
375
 
 
376
 
                        onMicrophoneClicked: hudClient.startVoiceQuery()
377
 
 
378
 
                        onTextChanged: {
379
 
                            if (ignoreNextTextChange) {
380
 
                                ignoreNextTextChange = false
381
 
                            } else {
382
 
                                hudClient.setQuery(searchBar.text)
383
 
                            }
384
 
                        }
385
 
 
386
 
                        onTextFocused: {
387
 
                            hud.state = "showing_results"
388
 
                        }
389
 
                    }
390
 
                }
391
 
 
392
 
                ShowingAnimation {
393
 
                    id: resultsCardAnimator
394
 
                    objectName: "resultsCardAnimator"
395
 
 
396
 
                    anchors {
397
 
                        left: parent.left
398
 
                        right: parent.right
399
 
                        top: searchBarAnimator.bottom
400
 
                        margins: elementsPadding
401
 
                    }
402
 
                    progress: MathUtils.clamp((y - hudShowable.y + height - units.gu(8))/elementsYSliding, 0, 1)
403
 
 
404
 
                    Flickables.Flickable {
405
 
                        anchors.left: parent.left
406
 
                        anchors.right: parent.right
407
 
                        contentHeight: resultList.height
408
 
                        contentWidth: width
409
 
                        clip: height < contentHeight
410
 
                        interactive: height < contentHeight
411
 
 
412
 
                        height: {
413
 
                            if (hud.state == "showing_results") {
414
 
                                return shell.applicationManager.keyboardVisible ? Math.min(hud.height - searchBarAnimator.y - searchBarAnimator.height - units.gu(2) - shell.applicationManager.keyboardHeight, contentHeight) : contentHeight
415
 
                            } else {
416
 
                                return contentHeight
417
 
                            }
418
 
                        }
419
 
 
420
 
 
421
 
                        ResultList {
422
 
                            id: resultList
423
 
 
424
 
                            anchors.left: parent.left
425
 
                            anchors.right: parent.right
426
 
                            height: childrenRect.height
427
 
 
428
 
                            onActivated: {
429
 
                                hudClient.executeCommand(index)
430
 
                            }
431
 
 
432
 
                            model: hudClient.results
433
 
                        }
434
 
                    }
435
 
                }
436
 
 
437
 
                ShowingAnimation {
438
 
                    id: soundAmplitudeVisualAnimator
439
 
 
440
 
                    anchors {
441
 
                        horizontalCenter: parent.horizontalCenter
442
 
                        verticalCenter: parent.verticalCenter
443
 
                        verticalCenterOffset: (searchBar.height + 2*elementsPadding)/2
444
 
                    }
445
 
                    visible: false
446
 
                    width: units.gu(33)
447
 
                    progress: MathUtils.clamp((y - hudShowable.y - anchors.verticalCenterOffset)/elementsYSliding, 0, 1)
448
 
 
449
 
                    SoundAmplitudeVisual {
450
 
                        id: soundAmplitudeVisual
451
 
                        width: units.gu(33)
452
 
                        height: width
453
 
                    }
454
 
                }
455
 
            }
456
 
 
457
 
            HudParametrizedActionsPage {
458
 
                id: parametrizedActionsPage
459
 
                objectName: "parametrizedActionsPage"
460
 
                property bool shown: false
461
 
 
462
 
                anchors.bottom: parent.bottom
463
 
                height: hud.height - handle.height - units.dp(1)
464
 
                width: parent.width
465
 
                x: shown ? 0 : width
466
 
                onConfirmPressed: {
467
 
                    hudClient.executeParametrizedAction(values())
468
 
                }
469
 
                onValuesUpdated: {
470
 
                    hudClient.updateParametrizedAction(values())
471
 
                }
472
 
                onBackPressed: {
473
 
                    shown = false
474
 
                }
475
 
                onShownChanged: {
476
 
                    if (!shown) {
477
 
                        hudClient.cancelParametrizedAction()
478
 
                    }
479
 
                }
480
 
                Behavior on x {
481
 
                    NumberAnimation {
482
 
                        easing.type: outEasing
483
 
                        duration: animationDuration
484
 
                    }
485
 
                }
486
 
            }
487
 
        }
488
 
    }
489
 
 
490
 
    Image {
491
 
        anchors.left: hudContentClipper.right
492
 
        anchors.top: hudContentClipper.top
493
 
        anchors.bottom: hudContentClipper.bottom
494
 
        fillMode: Image.Tile
495
 
        source: "../graphics/dropshadow_right.png"
496
 
    }
497
 
}