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"
26 readonly property real elementsPadding: units.gu(1)
27 readonly property real elementsYSliding: units.gu(2)
29 property alias revealerTarget: hudShowable
30 property alias showAnimation: hudShowable.showAnimation
31 property alias hideAnimation: hudShowable.hideAnimation
32 property alias available: hudShowable.available
33 property alias shown: hudShowable.shown
34 property alias handleHeight: handle.height
36 readonly property variant outEasing: Easing.OutQuad
37 readonly property variant inEasing: Easing.InQuad
38 readonly property int animationDuration: 200
39 readonly property int showableAnimationDuration: 100
40 property bool showingOpenIndicator: false
42 // FIXME At the moment since we have no appstack
43 // it's not possible to get results of the sidestage app
44 // design has to come up with a solution
51 function resetToInitialState() {
55 parametrizedActionsPage.shown = false
61 PropertyChanges { target: searchBar; placeholderText: i18n.tr("Type or say a command") }
62 PropertyChanges { target: searchBar; searchEnabled: true }
63 PropertyChanges { target: toolBarAnimator; visible: true}
64 AnchorChanges { target: searchBarAnimator; anchors.top: undefined; anchors.bottom: parent.bottom; }
65 AnchorChanges { target: resultsCardAnimator; anchors.top: undefined; anchors.bottom: toolBarAnimator.top; }
68 name: "input" //only inherited by other states.
69 AnchorChanges { target: searchBarAnimator; anchors.top: parent.top; anchors.bottom: undefined; }
70 AnchorChanges { target: resultsCardAnimator; anchors.top: searchBarAnimator.bottom; anchors.bottom: undefined; }
71 PropertyChanges { target: toolBarAnimator; visible: false }
74 name: "voice_input" //only inherited by other states.
76 PropertyChanges { target: soundAmplitudeVisualAnimator; visible: true }
77 PropertyChanges { target: resultsCardAnimator; visible: false }
78 PropertyChanges { target: soundAmplitudeVisualAnimator; progress: 1 }
79 PropertyChanges { target: searchBar; searchEnabled: false }
82 name: "voice_recognition_loading"
84 PropertyChanges { target: searchBar; placeholderText: i18n.tr("Loading. Please Wait...") }
87 name: "voice_recognition_listening"
89 PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speak Now...") }
92 name: "voice_recognition_processing"
94 PropertyChanges { target: searchBar; placeholderText: i18n.tr("Speaking...") }
97 name: "showing_results"
99 PropertyChanges { target: searchBar; placeholderText: i18n.tr("Type or say a command") }
100 PropertyChanges { target: searchBar; searchEnabled: true }
107 to: "voice_recognition_loading"
108 SequentialAnimation {
109 NumberAnimation { // hide these components
110 targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
111 property: "progress"; duration: animationDuration; to: 0
114 PropertyAction { targets: [toolBarAnimator, resultsCardAnimator]; property: "visible"; value: false}
115 PropertyAction { target: soundAmplitudeVisualAnimator; property: "visible"; value: true}
117 AnchorAnimation { duration: 0 } // so anchor change happens at this point
119 NumberAnimation { // show these components
120 targets: [searchBarAnimator, soundAmplitudeVisualAnimator]
121 property: "progress"; duration: animationDuration; from: 0; to: 1
126 from: "showing_results"
127 to: "voice_recognition_loading"
128 SequentialAnimation {
129 PropertyAction { target: soundAmplitudeVisualAnimator; property: "progress"; value: 0}
131 PropertyAction { // hide these components
132 target: resultsCardAnimator; property: "progress"; value: 0
135 NumberAnimation { // show these components
136 target: soundAmplitudeVisualAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
141 from: "voice_recognition_processing"
142 to: "showing_results"
143 SequentialAnimation {
144 NumberAnimation { // hide these components
145 target: soundAmplitudeVisualAnimator; property: "progress"; duration: animationDuration; to: 0
147 PropertyAction { target: resultsCardAnimator; property: "visible"; value: true}
149 NumberAnimation { // show these components
150 target: resultsCardAnimator; property: "progress"; duration: animationDuration; from: 0; to: 1
156 to: "showing_results"
157 SequentialAnimation {
159 targets: [toolBarAnimator, searchBarAnimator, resultsCardAnimator]
160 property: "progress"; duration: animationDuration; to: 0
163 PropertyAction { target: toolBarAnimator; property: "visible"; value: false}
165 AnchorAnimation { duration: 0 } // so anchor change happens at this point
168 targets: [searchBarAnimator, resultsCardAnimator]
169 property: "progress"; duration: animationDuration; from: 0; to: 1
184 onShowParametrizedAction: {
185 parametrizedActionsPage.header = action
186 parametrizedActionsPage.setItems(items)
187 parametrizedActionsPage.shown = true
190 onVoiceQueryLoading: {
191 hud.state = "voice_recognition_loading"
192 searchBar.ignoreNextTextChange = true
195 soundAmplitudeVisual.startIdle()
197 onVoiceQueryListening: {
198 if (hud.state == "voice_recognition_loading" || hud.state == "showing_results") {
199 searchBar.ignoreNextTextChange = true
202 hud.state = "voice_recognition_listening"
205 onVoiceQueryHeardSomething: {
206 if (hud.state == "voice_recognition_listening") {
207 hud.state = "voice_recognition_processing"
208 soundAmplitudeVisual.setDetectorEnabled(true)
211 onVoiceQueryFinished: {
212 hud.state = "showing_results"
213 searchBar.text = query
214 soundAmplitudeVisual.setDetectorEnabled(false)
216 onVoiceQueryFailed: {
217 hud.state = "showing_results"
219 soundAmplitudeVisual.setDetectorEnabled(false)
225 objectName: "hudShowable"
226 height: parent.height
231 showAnimation.duration = 0
232 hideAnimation.duration = 0
233 } else if (!showAnimation.running && !hideAnimation.running) {
234 if (parent.height > 0) {
235 showAnimation.duration = Math.min(showableAnimationDuration * (1 - (parent.height - y) / parent.height), showableAnimationDuration)
236 hideAnimation.duration = showableAnimationDuration - showAnimation.duration
242 // Eat everything that doesn't go to other places
249 source: "graphics/hud_bg.png"
253 target: hideAnimation
255 if (!hideAnimation.running) {
256 showAnimation.duration = showableAnimationDuration
257 hud.resetToInitialState()
263 target: showAnimation
265 if (!showAnimation.running) {
266 hideAnimation.duration = showableAnimationDuration
281 height: handleImage.height
289 source: "graphics/hud_handlebar.png"
295 anchors.horizontalCenter: parent.horizontalCenter
296 source: "graphics/hud_handlearrow.png"
302 id: hudContentClipper
307 bottom: parent.bottom
310 clip: visible && hudContent.height !== height
311 visible: hudContent.height >= 0
318 bottom: parent.bottom
324 x: parametrizedActionsPage.x - width
330 objectName: "toolBarAnimator"
334 bottom: searchBarAnimator.top
335 margins: 2*elementsPadding //ensures positioning correct
337 progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
341 objectName: "toolBar"
342 model: hudClient.toolBarModel
343 anchors.horizontalCenter: parent.horizontalCenter
345 hudClient.executeToolBarAction(action)
351 id: searchBarAnimator
352 objectName: "searchBarAnimator"
356 bottom: parent.bottom
357 margins: elementsPadding
358 topMargin: handle.height + units.dp(1) + elementsPadding
360 progress: MathUtils.clamp((y - hudShowable.y - anchors.margins)/elementsYSliding, 0, 1)
364 objectName: "searchBar"
366 property bool ignoreNextTextChange: false
368 anchors.left: parent.left
369 anchors.right: parent.right
372 placeholderText: i18n.tr("Type or say a command")
373 activityIndicatorVisible: hud.state == "voice_recognition_processing"
375 onMicrophoneClicked: hudClient.startVoiceQuery()
378 if (ignoreNextTextChange) {
379 ignoreNextTextChange = false
381 hudClient.setQuery(searchBar.text)
386 hud.state = "showing_results"
392 id: resultsCardAnimator
393 objectName: "resultsCardAnimator"
398 top: searchBarAnimator.bottom
399 margins: elementsPadding
401 progress: MathUtils.clamp((y - hudShowable.y + height - units.gu(8))/elementsYSliding, 0, 1)
404 anchors.left: parent.left
405 anchors.right: parent.right
406 contentHeight: resultList.height
408 clip: height < contentHeight
409 interactive: height < contentHeight
412 if (hud.state == "showing_results") {
413 return shell.applicationManager.keyboardVisible ? Math.min(hud.height - searchBarAnimator.y - searchBarAnimator.height - units.gu(2) - shell.applicationManager.keyboardHeight, contentHeight) : contentHeight
423 anchors.left: parent.left
424 anchors.right: parent.right
425 height: childrenRect.height
428 hudClient.executeCommand(index)
431 model: hudClient.results
437 id: soundAmplitudeVisualAnimator
440 horizontalCenter: parent.horizontalCenter
441 verticalCenter: parent.verticalCenter
442 verticalCenterOffset: (searchBar.height + 2*elementsPadding)/2
446 progress: MathUtils.clamp((y - hudShowable.y - anchors.verticalCenterOffset)/elementsYSliding, 0, 1)
448 SoundAmplitudeVisual {
449 id: soundAmplitudeVisual
456 HudParametrizedActionsPage {
457 id: parametrizedActionsPage
458 objectName: "parametrizedActionsPage"
459 property bool shown: false
461 anchors.bottom: parent.bottom
462 height: hud.height - handle.height - units.dp(1)
466 hudClient.executeParametrizedAction(values())
469 hudClient.updateParametrizedAction(values())
476 hudClient.cancelParametrizedAction()
481 easing.type: outEasing
482 duration: animationDuration
490 anchors.left: hudContentClipper.right
491 anchors.top: hudContentClipper.top
492 anchors.bottom: hudContentClipper.bottom
494 source: "../graphics/dropshadow_right.png"