Unity 8
 All Classes Functions
Dash.qml
1 /*
2  * Copyright (C) 2013, 2014 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.2
18 import Ubuntu.Components 0.1
19 import Ubuntu.Gestures 0.1
20 import Unity 0.2
21 import Utils 0.1
22 import Unity.DashCommunicator 0.1
23 import "../Components"
24 
25 Showable {
26  id: dash
27  objectName: "dash"
28 
29  visible: shown
30 
31  property string showScopeOnLoaded: "clickscope"
32  property real contentScale: 1.0
33 
34  DashCommunicatorService {
35  objectName: "dashCommunicatorService"
36  onSetCurrentScopeRequested: {
37  if (!isSwipe || !window.active || overviewController.progress != 0) {
38  if (overviewController.progress != 0 && window.active) animate = false;
39  dash.setCurrentScope(scopeId, animate, isSwipe)
40  if (overviewController.progress != 0) {
41  if (window.active) {
42  dashContentCache.scheduleUpdate();
43  }
44  overviewController.enableAnimation = window.active;
45  overviewController.progress = 0;
46  }
47  }
48  }
49  }
50 
51  function setCurrentScope(scopeId, animate, reset) {
52  var scopeIndex = -1;
53  for (var i = 0; i < scopes.count; ++i) {
54  if (scopes.getScope(i).id == scopeId) {
55  scopeIndex = i;
56  break;
57  }
58  }
59 
60  if (scopeIndex == -1) {
61  console.warn("No match for scope with id: %1".arg(scopeId))
62  return
63  }
64 
65  closeOverlayScope();
66 
67  dashContent.closePreview();
68 
69  if (scopeIndex == dashContent.currentIndex && !reset) {
70  // the scope is already the current one
71  return
72  }
73 
74  dashContent.setCurrentScopeAtIndex(scopeIndex, animate, reset)
75  }
76 
77  function closeOverlayScope() {
78  if (dashContent.x != 0) {
79  dashContent.x = 0;
80  }
81  }
82 
83  Scopes {
84  id: scopes
85  }
86 
87  QtObject {
88  id: overviewController
89  objectName: "overviewController"
90 
91  property alias enableAnimation: progressAnimation.enabled
92  property real progress: 0
93  Behavior on progress {
94  id: progressAnimation
95  UbuntuNumberAnimation { }
96  }
97  }
98 
99  ScopesOverview {
100  id: scopesOverview
101  objectName: "scopesOverview"
102  anchors.fill: parent
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
108  onDone: {
109  if (currentTab == 1) {
110  animateDashFromAll(dashContent.currentScopeId);
111  }
112  hide();
113  }
114  onFavoriteSelected: {
115  setCurrentScope(scopeId, false, false);
116  dashContentCache.scheduleUpdate();
117  hide();
118  }
119  onAllFavoriteSelected: {
120  setCurrentScope(scopeId, false, false);
121  dashContentCache.scheduleUpdate();
122  animateDashFromAll(dashContent.currentScopeId);
123  hide();
124  }
125  onSearchSelected: {
126  var scopeIndex = -1;
127  for (var i = 0; i < scopes.count; ++i) {
128  if (scopes.getScope(i).id == scopeId) {
129  scopeIndex = i;
130  break;
131  }
132  }
133  if (scopeIndex >= 0) {
134  // Is a favorite one
135  setCurrentScope(scopeId, false, false);
136  dashContentCache.scheduleUpdate();
137  showDashFromPos(pos, size);
138  hide();
139  } else {
140  // Is not a favorite one, activate and get openScope
141  scope.activate(result);
142  }
143  }
144  function hide() {
145  overviewController.enableAnimation = true;
146  overviewController.progress = 0;
147  }
148  onProgressChanged: {
149  if (progress == 0) {
150  currentTab = scopeItem.scope ? 1 : 0;
151  }
152  }
153  }
154 
155  ShaderEffectSource {
156  id: dashContentCache
157  parent: scopesOverview.dashItemEater
158  z: 1
159  sourceItem: dashContent
160  height: sourceItem.height
161  width: sourceItem.width
162  opacity: 1 - overviewController.progress
163  visible: overviewController.progress != 0 && scopeItem.scope === null
164  live: false
165  }
166 
167  DashContent {
168  id: dashContent
169 
170  property var scopeThatOpenedScope: null
171 
172  objectName: "dashContent"
173  width: dash.width
174  height: dash.height
175  scopes: scopes
176  visible: !scopesOverview.showingNonFavoriteScope && x != -width
177  onGotoScope: {
178  dash.setCurrentScope(scopeId, true, false);
179  }
180  onOpenScope: {
181  scopeThatOpenedScope = currentScope;
182  scopeItem.scope = scope;
183  scopesOverview.currentTab = 1;
184  scopesOverview.ensureAllScopeVisible(scope.id);
185  x = -width;
186  }
187  onScopeLoaded: {
188  if (scopeId == dash.showScopeOnLoaded) {
189  dash.setCurrentScope(scopeId, false, false)
190  dash.showScopeOnLoaded = ""
191  }
192  }
193  scale: dash.contentScale
194  clip: scale != 1.0 || scopeItem.visible || overviewController.progress != 0
195  Behavior on x {
196  UbuntuNumberAnimation {
197  duration: overviewController.progress != 0 ? 0 : UbuntuAnimation.FastDuration
198  onRunningChanged: {
199  if (!running && dashContent.x == 0) {
200  dashContent.scopeThatOpenedScope.closeScope(scopeItem.scope);
201  scopeItem.scope = null;
202  if (overviewController.progress == 0) {
203  // Set tab to Favorites only if we are not showing the overview
204  scopesOverview.currentTab = 0;
205  }
206  }
207  }
208  }
209  }
210 
211  enabled: overviewController.progress == 0
212  opacity: enabled ? 1 : 0
213  }
214 
215  DashBackground
216  {
217  anchors.fill: scopeItem
218  visible: scopeItem.visible
219  parent: scopeItem.parent
220  scale: scopeItem.scale
221  opacity: scopeItem.opacity
222  }
223 
224  GenericScopeView {
225  id: scopeItem
226  objectName: "dashTempScopeItem"
227 
228  readonly property real targetOverviewScale: {
229  if (scopesOverview.currentTab == 0) {
230  return 0.4;
231  } else {
232  return scopesOverview.allCardSize.width / scopeItem.width;
233  }
234  }
235  readonly property real overviewProgressScale: (1 - overviewController.progress * (1 - targetOverviewScale))
236  readonly property var targetOverviewPosition: scope ? scopesOverview.allScopeCardPosition(scope.id) : null
237  readonly property real overviewProgressX: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ?
238  overviewController.progress * (targetOverviewPosition.x - (width - scopesOverview.allCardSize.width) / 2)
239  : 0
240  readonly property real overviewProgressY: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ?
241  overviewController.progress * (targetOverviewPosition.y - (height - scopesOverview.allCardSize.height) / 2)
242  : 0
243 
244  x: overviewController.progress == 0 ? dashContent.x + width : overviewProgressX
245  y: overviewController.progress == 0 ? dashContent.y : overviewProgressY
246  width: parent.width
247  height: parent.height
248  scale: dash.contentScale * overviewProgressScale
249  enabled: opacity == 1
250  opacity: 1 - overviewController.progress
251  clip: scale != 1.0
252  visible: scope != null
253  hasBackAction: true
254  isCurrent: visible
255  onBackClicked: {
256  closeOverlayScope();
257  closePreview();
258  }
259 
260  Connections {
261  target: scopeItem.scope
262  onGotoScope: {
263  dashContent.gotoScope(scopeId);
264  }
265  onOpenScope: {
266  dashContent.openScope(scope);
267  }
268  }
269  }
270 
271  Rectangle {
272  id: indicator
273  objectName: "processingIndicator"
274  anchors {
275  left: parent.left
276  right: parent.right
277  bottom: parent.bottom
278  bottomMargin: Qt.inputMethod.keyboardRectangle.height
279  }
280  height: units.dp(3)
281  color: scopeStyle.backgroundLuminance > 0.7 ? "#50000000" : "#50ffffff"
282  opacity: 0
283  visible: opacity > 0
284 
285  readonly property bool processing: dashContent.processing || scopeItem.processing || scopesOverview.processing
286 
287  Behavior on opacity {
288  UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
289  }
290 
291  onProcessingChanged: {
292  if (processing) delay.start();
293  else if (!persist.running) indicator.opacity = 0;
294  }
295 
296  Timer {
297  id: delay
298  interval: 200
299  onTriggered: if (indicator.processing) {
300  persist.restart();
301  indicator.opacity = 1;
302  }
303  }
304 
305  Timer {
306  id: persist
307  interval: 2 * UbuntuAnimation.SleepyDuration - UbuntuAnimation.FastDuration
308  onTriggered: if (!indicator.processing) indicator.opacity = 0
309  }
310 
311  Rectangle {
312  id: orange
313  anchors { top: parent.top; bottom: parent.bottom }
314  width: parent.width / 4
315  color: Theme.palette.selected.foreground
316 
317  SequentialAnimation {
318  running: indicator.visible
319  loops: Animation.Infinite
320  XAnimator {
321  from: -orange.width / 2
322  to: indicator.width - orange.width / 2
323  duration: UbuntuAnimation.SleepyDuration
324  easing.type: Easing.InOutSine
325  target: orange
326  }
327  XAnimator {
328  from: indicator.width - orange.width / 2
329  to: -orange.width / 2
330  duration: UbuntuAnimation.SleepyDuration
331  easing.type: Easing.InOutSine
332  target: orange
333  }
334  }
335  }
336  }
337 
338  Image {
339  source: "graphics/overview_hint.png"
340  anchors.horizontalCenter: parent.horizontalCenter
341  opacity: (scopeItem.scope ? scopeItem.pageHeaderTotallyVisible : dashContent.pageHeaderTotallyVisible) &&
342  (overviewDragHandle.enabled || overviewController.progress != 0) ? 1 : 0
343  Behavior on opacity {
344  enabled: overviewController.progress == 0
345  UbuntuNumberAnimation {}
346  }
347  y: parent.height - height * (1 - overviewController.progress * 4)
348  }
349 
350  EdgeDragArea {
351  id: overviewDragHandle
352  objectName: "overviewDragHandle"
353  z: 1
354  direction: Direction.Upwards
355  enabled: !dashContent.subPageShown &&
356  dashContent.currentScope &&
357  dashContent.currentScope.searchQuery == "" &&
358  !scopeItem.subPageShown &&
359  (overviewController.progress == 0 || dragging)
360 
361  readonly property real fullMovement: units.gu(20)
362 
363  anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
364  height: units.gu(2)
365 
366  onSceneDistanceChanged: {
367  if (overviewController.enableAnimation) {
368  dashContentCache.scheduleUpdate();
369  }
370  overviewController.enableAnimation = false;
371  overviewController.progress = Math.max(0, Math.min(1, sceneDistance / fullMovement));
372  }
373 
374  onDraggingChanged: {
375  overviewController.enableAnimation = true;
376  overviewController.progress = (overviewController.progress > 0.7) ? 1 : 0;
377  }
378  }
379 
380 }