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"
31 property string showScopeOnLoaded: "clickscope"
33 DashCommunicatorService {
34 objectName: "dashCommunicatorService"
35 onSetCurrentScopeRequested: {
36 if (!isSwipe || !window.active || overviewController.progress != 0) {
37 if (overviewController.progress != 0 && window.active) animate = false;
38 dash.setCurrentScope(scopeId, animate, isSwipe)
39 if (overviewController.progress != 0) {
41 dashContentCache.scheduleUpdate();
43 overviewController.enableAnimation = window.active && !scopesOverview.showingNonFavoriteScope;
44 overviewController.progress = 0;
45 scopesOverview.closeTempScope();
51 function setCurrentScope(scopeId, animate, reset) {
53 for (var i = 0; i < scopes.count; ++i) {
54 if (scopes.getScope(i).id == scopeId) {
60 if (scopeIndex == -1) {
61 console.warn("No match for scope with id: %1".arg(scopeId))
67 dashContent.closePreview();
69 if (scopeIndex == dashContent.currentIndex && !reset) {
70 // the scope is already the current one
74 dashContent.setCurrentScopeAtIndex(scopeIndex, animate, reset)
77 function closeOverlayScope() {
78 if (dashContent.x != 0) {
88 id: overviewController
89 objectName: "overviewController"
91 property alias enableAnimation: progressAnimation.enabled
92 property real progress: 0
93 Behavior on progress {
95 UbuntuNumberAnimation { }
101 objectName: "scopesOverview"
103 scope: scopes.overviewScope
104 progress: overviewController.progress
105 scopeScale: scopeItem.scope ? 0.4 : (1 - overviewController.progress * 0.6)
106 visible: scopeScale != 1
107 currentIndex: dashContent.currentIndex
109 if (currentTab == 1) {
110 animateDashFromAll(dashContent.currentScopeId);
114 onFavoriteSelected: {
115 setCurrentScope(scopeId, false, false);
116 dashContentCache.scheduleUpdate();
119 onAllFavoriteSelected: {
120 setCurrentScope(scopeId, false, false);
121 dashContentCache.scheduleUpdate();
122 animateDashFromAll(dashContent.currentScopeId);
127 for (var i = 0; i < scopes.count; ++i) {
128 if (scopes.getScope(i).id == scopeId) {
133 if (scopeIndex >= 0) {
135 setCurrentScope(scopeId, false, false);
136 dashContentCache.scheduleUpdate();
137 showDashFromPos(pos, size);
140 // Is not a favorite one, activate and get openScope
141 scope.activate(result);
145 overviewController.enableAnimation = true;
146 overviewController.progress = 0;
150 currentTab = scopeItem.scope ? 1 : 0;
157 parent: scopesOverview.dashItemEater
159 sourceItem: dashContent
160 height: sourceItem.height
161 width: sourceItem.width
162 opacity: 1 - overviewController.progress
163 visible: overviewController.progress != 0 && scopeItem.scope === null
170 property var scopeThatOpenedScope: null
172 objectName: "dashContent"
176 visible: !scopesOverview.showingNonFavoriteScope && x != -width
178 dash.setCurrentScope(scopeId, true, false);
181 scopeThatOpenedScope = currentScope;
182 scopeItem.scope = scope;
183 scopesOverview.currentTab = 1;
184 scopesOverview.ensureAllScopeVisible(scope.id);
188 if (scopeId == dash.showScopeOnLoaded) {
189 dash.setCurrentScope(scopeId, false, false)
190 dash.showScopeOnLoaded = ""
193 clip: scale != 1.0 || scopeItem.visible || overviewController.progress != 0
195 UbuntuNumberAnimation {
196 duration: overviewController.progress != 0 ? 0 : UbuntuAnimation.FastDuration
198 if (!running && dashContent.x == 0) {
199 dashContent.scopeThatOpenedScope.closeScope(scopeItem.scope);
200 scopeItem.scope = null;
201 if (overviewController.progress == 0) {
202 // Set tab to Favorites only if we are not showing the overview
203 scopesOverview.currentTab = 0;
210 // This is to avoid the situation where a bottom-edge swipe would bring up the dash overview
211 // (as expected) but would also cause the dash content flickable to move a bit, because
212 // that flickable was getting the touch events while overviewDragHandle was still undecided
213 // about whether that touch was indeed performing a directional drag gesture.
214 forceNonInteractive: overviewDragHandle.status != DirectionalDragArea.WaitingForTouch
216 enabled: overviewController.progress == 0
217 opacity: enabled ? 1 : 0
222 anchors.fill: scopeItem
223 visible: scopeItem.visible
224 parent: scopeItem.parent
225 scale: scopeItem.scale
226 opacity: scopeItem.opacity
231 objectName: "dashTempScopeItem"
233 readonly property real targetOverviewScale: {
234 if (scopesOverview.currentTab == 0) {
237 return scopesOverview.allCardSize.width / scopeItem.width;
240 readonly property real overviewProgressScale: (1 - overviewController.progress * (1 - targetOverviewScale))
241 readonly property var targetOverviewPosition: scope ? scopesOverview.allScopeCardPosition(scope.id) : null
242 readonly property real overviewProgressX: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ?
243 overviewController.progress * (targetOverviewPosition.x - (width - scopesOverview.allCardSize.width) / 2)
245 readonly property real overviewProgressY: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ?
246 overviewController.progress * (targetOverviewPosition.y - (height - scopesOverview.allCardSize.height) / 2)
249 x: overviewController.progress == 0 ? dashContent.x + width : overviewProgressX
250 y: overviewController.progress == 0 ? dashContent.y : overviewProgressY
252 height: parent.height
253 scale: overviewProgressScale
254 enabled: opacity == 1
255 opacity: 1 - overviewController.progress
257 visible: scope != null
266 target: scopeItem.scope
268 dashContent.gotoScope(scopeId);
271 dashContent.openScope(scope);
278 objectName: "processingIndicator"
282 bottom: parent.bottom
283 bottomMargin: Qt.inputMethod.keyboardRectangle.height
286 color: scopeStyle.backgroundLuminance > 0.7 ? "#50000000" : "#50ffffff"
290 readonly property bool processing: dashContent.processing || scopeItem.processing || scopesOverview.processing
292 Behavior on opacity {
293 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
296 onProcessingChanged: {
297 if (processing) delay.start();
298 else if (!persist.running) indicator.opacity = 0;
304 onTriggered: if (indicator.processing) {
306 indicator.opacity = 1;
312 interval: 2 * UbuntuAnimation.SleepyDuration - UbuntuAnimation.FastDuration
313 onTriggered: if (!indicator.processing) indicator.opacity = 0
318 anchors { top: parent.top; bottom: parent.bottom }
319 width: parent.width / 4
320 color: Theme.palette.selected.foreground
322 SequentialAnimation {
323 running: indicator.visible
324 loops: Animation.Infinite
326 from: -orange.width / 2
327 to: indicator.width - orange.width / 2
328 duration: UbuntuAnimation.SleepyDuration
329 easing.type: Easing.InOutSine
333 from: indicator.width - orange.width / 2
334 to: -orange.width / 2
335 duration: UbuntuAnimation.SleepyDuration
336 easing.type: Easing.InOutSine
344 source: "graphics/overview_hint.png"
345 anchors.horizontalCenter: parent.horizontalCenter
346 opacity: (scopeItem.scope ? scopeItem.pageHeaderTotallyVisible : dashContent.pageHeaderTotallyVisible) &&
347 (overviewDragHandle.enabled || overviewController.progress != 0) ? 1 : 0
348 Behavior on opacity {
349 enabled: overviewController.progress == 0
350 UbuntuNumberAnimation {}
352 y: parent.height - height * (1 - overviewController.progress * 4)
356 id: overviewDragHandle
357 objectName: "overviewDragHandle"
359 direction: Direction.Upwards
360 enabled: !dashContent.subPageShown &&
361 dashContent.currentScope &&
362 dashContent.currentScope.searchQuery == "" &&
363 !scopeItem.subPageShown &&
364 (overviewController.progress == 0 || dragging)
366 readonly property real fullMovement: units.gu(20)
368 anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
371 onSceneDistanceChanged: {
372 if (status == DirectionalDragArea.Recognized && initialSceneDistance != -1) {
373 if (overviewController.enableAnimation) {
374 dashContentCache.scheduleUpdate();
376 overviewController.enableAnimation = false;
377 var deltaDistance = sceneDistance - initialSceneDistance;
378 overviewController.progress = Math.max(0, Math.min(1, deltaDistance / fullMovement));
382 property int previousStatus: -1
383 property int currentStatus: DirectionalDragArea.WaitingForTouch
384 property real initialSceneDistance: -1
387 previousStatus = currentStatus;
388 currentStatus = status;
390 if (status == DirectionalDragArea.Recognized) {
391 initialSceneDistance = sceneDistance;
392 } else if (status == DirectionalDragArea.WaitingForTouch &&
393 previousStatus == DirectionalDragArea.Recognized) {
394 overviewController.enableAnimation = true;
395 overviewController.progress = (overviewController.progress > 0.7) ? 1 : 0;
396 initialSceneDistance = -1;