2 * Copyright (C) 2013, 2014 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
19 import Ubuntu.Gestures 0.1
22 import Unity.DashCommunicator 0.1
23 import "../Components"
35 dashContent.currentScope.performQuery(uris[0])
39 DashCommunicatorService {
40 objectName: "dashCommunicatorService"
41 onSetCurrentScopeRequested: {
42 if (!isSwipe || !window.active || bottomEdgeController.progress != 0 || scopeItem.scope || dashContent.subPageShown) {
43 if (bottomEdgeController.progress != 0 && window.active) animate = false;
44 dashContent.setCurrentScopeAtIndex(index, animate, true)
50 function backToDashContent()
52 // Close dash overview and nested temp scopes in it
53 if (bottomEdgeController.progress != 0) {
54 bottomEdgeController.enableAnimation = window.active;
55 bottomEdgeController.progress = 0;
57 // Close normal temp scopes (e.g. App Store)
58 if (scopeItem.scope) {
59 scopeItem.backClicked();
62 if (dashContent.subPageShown) {
63 dashContent.closePreview();
67 function setCurrentScope(scopeId, animate, reset) {
69 for (var i = 0; i < scopes.count; ++i) {
70 if (scopes.getScope(i).id == scopeId) {
76 if (scopeIndex == -1) {
77 console.warn("No match for scope with id: %1".arg(scopeId))
83 dashContent.closePreview();
85 if (scopeIndex == dashContent.currentIndex && !reset) {
86 // the scope is already the current one
90 dashContent.workaroundRestoreIndex = -1;
91 dashContent.setCurrentScopeAtIndex(scopeIndex, animate, reset)
94 function closeOverlayScope() {
95 if (dashContent.x != 0) {
105 id: bottomEdgeController
106 objectName: "bottomEdgeController"
108 property alias enableAnimation: progressAnimation.enabled
109 property real progress: 0
110 Behavior on progress {
111 id: progressAnimation
112 UbuntuNumberAnimation { }
116 // FIXME This is to workaround a Qt bug with the model moving the current item
117 // when the list is ListView.SnapOneItem and ListView.StrictlyEnforceRange
118 // together with the code in DashContent.qml
119 if (dashContent.workaroundRestoreIndex != -1) {
120 dashContent.currentIndex = dashContent.workaroundRestoreIndex;
121 dashContent.workaroundRestoreIndex = -1;
129 objectName: "dashContent"
135 dash.setCurrentScope(scopeId, true, false);
138 scopeItem.scope = scope;
142 UbuntuNumberAnimation {
144 if (!running && dashContent.x == 0) {
145 scopes.closeScope(scopeItem.scope);
146 scopeItem.scope = null;
152 // This is to avoid the situation where a bottom-edge swipe would bring up the dash overview
153 // (as expected) but would also cause the dash content flickable to move a bit, because
154 // that flickable was getting the touch events while overviewDragHandle was still undecided
155 // about whether that touch was indeed performing a directional drag gesture.
156 forceNonInteractive: overviewDragHandle.dragging
158 enabled: bottomEdgeController.progress == 0
163 opacity: bottomEdgeController.progress
164 anchors.fill: dashContent
169 objectName: "scopesList"
172 scope: scopes.overviewScope
173 y: dash.height * (1 - bottomEdgeController.progress)
174 visible: bottomEdgeController.progress != 0
176 bottomEdgeController.enableAnimation = true;
177 bottomEdgeController.progress = 0;
180 bottomEdgeController.enableAnimation = true;
181 bottomEdgeController.progress = 0;
182 scopesList.scope.performQuery("scope://com.canonical.scopes.clickstore");
185 scopes.setFavorite(scopeId, favorite);
187 onRequestFavoriteMoveTo: {
188 scopes.moveFavoriteTo(scopeId, index);
191 bottomEdgeController.enableAnimation = true;
192 bottomEdgeController.progress = 0;
193 dash.setCurrentScope(scopeId, false, false);
197 target: scopesList.scope
199 value: bottomEdgeController.progress === 1 && (Qt.application.state == Qt.ApplicationActive)
203 target: scopesList.scope
205 bottomEdgeController.enableAnimation = true;
206 bottomEdgeController.progress = 0;
207 scopeItem.scope = scope;
208 dashContent.x = -dashContent.width;
211 bottomEdgeController.enableAnimation = true;
212 bottomEdgeController.progress = 0;
213 dashContent.gotoScope(scopeId);
219 anchors.fill: scopeItem
220 visible: scopeItem.visible
225 objectName: "dashTempScopeItem"
227 x: dashContent.x + width
230 height: parent.height
231 visible: scope != null
240 target: scopeItem.scope
242 dashContent.gotoScope(scopeId);
245 scopeItem.closePreview();
246 var oldScope = scopeItem.scope;
247 scopeItem.scope = scope;
248 scopes.closeScope(oldScope);
255 objectName: "processingIndicator"
259 bottom: parent.bottom
260 bottomMargin: Qt.inputMethod.keyboardRectangle.height
263 color: scopeStyle.backgroundLuminance > 0.7 ? "#50000000" : "#50ffffff"
267 readonly property bool processing: dashContent.processing || scopeItem.processing || scopesList.processing
269 Behavior on opacity {
270 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
273 onProcessingChanged: {
274 if (processing) delay.start();
275 else if (!persist.running) indicator.opacity = 0;
281 onTriggered: if (indicator.processing) {
283 indicator.opacity = 1;
289 interval: 2 * UbuntuAnimation.SleepyDuration - UbuntuAnimation.FastDuration
290 onTriggered: if (!indicator.processing) indicator.opacity = 0
295 anchors { top: parent.top; bottom: parent.bottom }
296 width: parent.width / 4
297 color: UbuntuColors.orange
299 SequentialAnimation {
300 running: indicator.visible
301 loops: Animation.Infinite
303 from: -orange.width / 2
304 to: indicator.width - orange.width / 2
305 duration: UbuntuAnimation.SleepyDuration
306 easing.type: Easing.InOutSine
310 from: indicator.width - orange.width / 2
311 to: -orange.width / 2
312 duration: UbuntuAnimation.SleepyDuration
313 easing.type: Easing.InOutSine
321 objectName: "overviewHint"
322 source: "graphics/overview_hint.png"
323 anchors.horizontalCenter: parent.horizontalCenter
324 opacity: !scopeItem.scope && (scopes.count == 0 || dashContent.pageHeaderTotallyVisible) &&
325 (overviewDragHandle.enabled || bottomEdgeController.progress != 0) ? 1 : 0
326 Behavior on opacity {
327 enabled: bottomEdgeController.progress == 0
328 UbuntuNumberAnimation {}
330 y: parent.height - height * (1 - bottomEdgeController.progress * 4)
332 // Eat direct presses on the overview hint so that they do not end up in the card below
334 enabled: parent.opacity != 0
336 // TODO: This is a temporary workaround to allow people opening the
337 // dash overview when there's no touch input around. Will be replaced with
338 // a SDK component once that's available
339 onClicked: bottomEdgeController.progress = 1;
341 // We need to eat touch events here in order to not allow opening the bottom edge with a touch press
342 MultiPointTouchArea {
345 enabled: parent.enabled
350 DirectionalDragArea {
351 id: overviewDragHandle
352 objectName: "overviewDragHandle"
354 direction: Direction.Upwards
355 enabled: !dashContent.subPageShown &&
356 (scopes.count == 0 || (dashContent.currentScope && dashContent.currentScope.searchQuery == "")) &&
358 (bottomEdgeController.progress == 0 || dragging)
360 readonly property real fullMovement: dash.height
362 anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
365 onSceneDistanceChanged: {
367 bottomEdgeController.enableAnimation = false;
368 bottomEdgeController.progress = Math.max(0, Math.min(1, sceneDistance / fullMovement));
374 bottomEdgeController.enableAnimation = true;
375 bottomEdgeController.progress = (bottomEdgeController.progress > 0.2) ? 1 : 0;