2
* Copyright (C) 2012, 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/>.
18
import Ubuntu.Components 0.1
21
import "../Components"
22
import "../Components/Flickables" as Flickables
27
readonly property real elementsPadding: units.gu(1)
28
readonly property real elementsYSliding: units.gu(2)
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
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
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
52
function resetToInitialState() {
56
parametrizedActionsPage.shown = false
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; }
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 }
75
name: "voice_input" //only inherited by other states.
77
PropertyChanges { target: soundAmplitudeVisualAnimator; visible: true }
78
PropertyChanges { target: resultsCardAnimator; visible: false }
79
PropertyChanges { target: soundAmplitudeVisualAnimator; progress: 1 }
80
PropertyChanges { target: searchBar; searchEnabled: false }
83
name: "voice_recognition_loading"
85
PropertyChanges { target: searchBar; placeholderText: i18n.tr("Loading. Please Wait...") }
88
name: "voice_recognition_listening"
90
PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speak Now...") }
93
name: "voice_recognition_processing"
95
PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speaking...") }
98
name: "showing_results"
100
PropertyChanges { target: searchBar; placeholderText: i18n.tr("Type or say a command") }
101
PropertyChanges { target: searchBar; searchEnabled: true }
108
to: "voice_recognition_loading"
109
SequentialAnimation {
110
NumberAnimation { // hide these components
111
targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
112
property: "progress"; duration: animationDuration; to: 0
115
PropertyAction { targets: [toolBarAnimator, resultsCardAnimator]; property: "visible"; value: false}
116
PropertyAction { target: soundAmplitudeVisualAnimator; property: "visible"; value: true}
118
AnchorAnimation { duration: 0 } // so anchor change happens at this point
120
NumberAnimation { // show these components
121
targets: [searchBarAnimator, soundAmplitudeVisualAnimator]
122
property: "progress"; duration: animationDuration; from: 0; to: 1
127
from: "showing_results"
128
to: "voice_recognition_loading"
129
SequentialAnimation {
130
PropertyAction { target: soundAmplitudeVisualAnimator; property: "progress"; value: 0}
132
PropertyAction { // hide these components
133
target: resultsCardAnimator; property: "progress"; value: 0
136
NumberAnimation { // show these components
137
target: soundAmplitudeVisualAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
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
148
PropertyAction { target: resultsCardAnimator; property: "visible"; value: true}
150
NumberAnimation { // show these components
151
target: resultsCardAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
157
to: "showing_results"
158
SequentialAnimation {
160
targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
161
property: "progress"; duration: animationDuration; to: 0
164
PropertyAction { target: toolBarAnimator; property: "visible"; value: false}
166
AnchorAnimation { duration: 0 } // so anchor change happens at this point
169
targets: [searchBarAnimator, resultsCardAnimator]
170
property: "progress"; duration: animationDuration; from: 0; to: 1
185
onShowParametrizedAction: {
186
parametrizedActionsPage.header = action
187
parametrizedActionsPage.setItems(items)
188
parametrizedActionsPage.shown = true
191
onVoiceQueryLoading: {
192
hud.state = "voice_recognition_loading"
193
searchBar.ignoreNextTextChange = true
196
soundAmplitudeVisual.startIdle()
198
onVoiceQueryListening: {
199
if (hud.state == "voice_recognition_loading" || hud.state == "showing_results") {
200
searchBar.ignoreNextTextChange = true
203
hud.state = "voice_recognition_listening"
206
onVoiceQueryHeardSomething: {
207
if (hud.state == "voice_recognition_listening") {
208
hud.state = "voice_recognition_processing"
209
soundAmplitudeVisual.setDetectorEnabled(true)
212
onVoiceQueryFinished: {
213
hud.state = "showing_results"
214
searchBar.text = query
215
soundAmplitudeVisual.setDetectorEnabled(false)
217
onVoiceQueryFailed: {
218
hud.state = "showing_results"
220
soundAmplitudeVisual.setDetectorEnabled(false)
226
objectName: "hudShowable"
227
height: parent.height
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
243
// Eat everything that doesn't go to other places
250
source: "graphics/hud_bg.png"
254
target: hideAnimation
256
if (!hideAnimation.running) {
257
showAnimation.duration = showableAnimationDuration
258
hud.resetToInitialState()
264
target: showAnimation
266
if (!showAnimation.running) {
267
hideAnimation.duration = showableAnimationDuration
282
height: handleImage.height
290
source: "graphics/hud_handlebar.png"
296
anchors.horizontalCenter: parent.horizontalCenter
297
source: "graphics/hud_handlearrow.png"
303
id: hudContentClipper
308
bottom: parent.bottom
311
clip: visible && hudContent.height !== height
312
visible: hudContent.height >= 0
319
bottom: parent.bottom
325
x: parametrizedActionsPage.x - width
331
objectName: "toolBarAnimator"
335
bottom: searchBarAnimator.top
336
margins: 2*elementsPadding //ensures positioning correct
338
progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
342
objectName: "toolBar"
343
model: hudClient.toolBarModel
344
anchors.horizontalCenter: parent.horizontalCenter
346
hudClient.executeToolBarAction(action)
352
id: searchBarAnimator
353
objectName: "searchBarAnimator"
357
bottom: parent.bottom
358
margins: elementsPadding
359
topMargin: handle.height + units.dp(1) + elementsPadding
361
progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
365
objectName: "searchBar"
367
property bool ignoreNextTextChange: false
369
anchors.left: parent.left
370
anchors.right: parent.right
373
placeholderText: i18n.tr("Type or say a command")
374
activityIndicatorVisible: hud.state == "voice_recognition_processing"
376
onMicrophoneClicked: hudClient.startVoiceQuery()
379
if (ignoreNextTextChange) {
380
ignoreNextTextChange = false
382
hudClient.setQuery(searchBar.text)
387
hud.state = "showing_results"
393
id: resultsCardAnimator
394
objectName: "resultsCardAnimator"
399
top: searchBarAnimator.bottom
400
margins: elementsPadding
402
progress: MathUtils.clamp((y - hudShowable.y + height - units.gu(8))/elementsYSliding, 0, 1)
404
Flickables.Flickable {
405
anchors.left: parent.left
406
anchors.right: parent.right
407
contentHeight: resultList.height
409
clip: height < contentHeight
410
interactive: height < contentHeight
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
424
anchors.left: parent.left
425
anchors.right: parent.right
426
height: childrenRect.height
429
hudClient.executeCommand(index)
432
model: hudClient.results
438
id: soundAmplitudeVisualAnimator
441
horizontalCenter: parent.horizontalCenter
442
verticalCenter: parent.verticalCenter
443
verticalCenterOffset: (searchBar.height + 2*elementsPadding)/2
447
progress: MathUtils.clamp((y - hudShowable.y - anchors.verticalCenterOffset)/elementsYSliding, 0, 1)
449
SoundAmplitudeVisual {
450
id: soundAmplitudeVisual
457
HudParametrizedActionsPage {
458
id: parametrizedActionsPage
459
objectName: "parametrizedActionsPage"
460
property bool shown: false
462
anchors.bottom: parent.bottom
463
height: hud.height - handle.height - units.dp(1)
467
hudClient.executeParametrizedAction(values())
470
hudClient.updateParametrizedAction(values())
477
hudClient.cancelParametrizedAction()
482
easing.type: outEasing
483
duration: animationDuration
491
anchors.left: hudContentClipper.right
492
anchors.top: hudContentClipper.top
493
anchors.bottom: hudContentClipper.bottom
495
source: "../graphics/dropshadow_right.png"