Unity 8
FoldingLauncherDelegate.qml
1 /*
2  * Copyright (C) 2013 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.4
18 import Ubuntu.Components 1.3
19 
20 LauncherDelegate {
21  id: root
22 
23  // The angle used for rotating
24  angle: {
25  // First/last items are special
26  if (index == 0 || index == priv.listView.count-1) {
27  if (priv.distanceFromEdge < 0) {
28  // proportion equation: distanceFromTopEdge : angle = totalUnfoldedHeight/2 : maxAngle
29  return Math.max(-maxAngle, priv.distanceFromEdge * maxAngle / (priv.foldingAreaHeight)) * priv.orientationFlag
30  }
31  return 0; // Don't fold first/last item as long as inside the view
32  }
33 
34  // We reached the folded area... fold the last 5 degrees
35  if (priv.overlapWithFoldedArea > 0) {
36  // proportion equation: overlap : x = height : 5
37  return ((maxAngle - 5) + (priv.overlapWithFoldedArea * 5 / priv.foldingAreaHeight)) * -priv.orientationFlag
38  }
39 
40  // We are overlapping with the folding area, fold the icon to maxAngle - 5 degrees
41  if (priv.overlapWithFoldingArea > 0) {
42  // proportion equation: overlap: totalHeight = angle : (maxAngle - 5)
43  return -priv.overlapWithFoldingArea * (maxAngle -5) / priv.foldingAreaHeight * priv.orientationFlag;
44  }
45  return 0;
46  }
47 
48  // This is the offset that keeps the items inside the panel
49  offset: {
50  // First/last items are special
51  if (index == 0 || index == priv.listView.count-1) {
52  // Just keep them bound to the edges in case they're outside of the visible area
53  if (priv.distanceFromEdge < 0) {
54  return (-priv.distanceFromEdge - (height - effectiveHeight)) * priv.orientationFlag;
55  }
56  return 0;
57  }
58 
59  // Are we already completely outside the flickable? Stop the icon here.
60  if (priv.distanceFromEdge < -priv.totalUnfoldedHeight) {
61  return (-priv.distanceFromEdge - (root.height - effectiveHeight)) * priv.orientationFlag;
62  }
63 
64  // We stopped folding, move slower than the actual flicking speed.
65  if (priv.overlapWithFoldedArea > 0) {
66  return (priv.overlapWithFoldedArea * priv.totalEffectiveHeight / (priv.totalUnfoldedHeight + priv.listView.foldingStopHeight)) * priv.orientationFlag;
67  }
68  return 0;
69  }
70 
71  itemOpacity: {
72  // First/last items are special
73  if (index == 0 || index == priv.listView.count-1) {
74  if (priv.distanceFromEdge < 0) {
75  // Fade from 1 to 0 while traversing a distance of 2*foldingAreaHeight
76  // proportion equation: 0.5 : x = -2*foldingAreaHeight : distance
77  return 1 + (priv.distanceFromEdge / (priv.foldingAreaHeight * 2))
78  }
79  return 1; // Don't make first/last item transparent as long as inside the view
80  }
81 
82  // Did we stop folding? Fade out to 0 in 2*foldingAreaHeight
83  if (priv.overlapWithFoldedArea > 0) {
84  // overlap : foldingAreaHeight = opacity : 0.75
85  return 0.75 - (priv.overlapWithFoldedArea * 0.75 / (priv.foldingAreaHeight * 2));
86  }
87 
88  // We are overlapping with the folding area, fade out to 0.75 transparency
89  if (priv.overlapWithFoldingArea > 0) {
90  // proportion equation: overlap : totalHeight = 1-opacity : 0.25
91  return 1 - (priv.overlapWithFoldingArea * 0.25 / priv.foldingAreaHeight)
92  }
93  return 1;
94  }
95 
96  brightness: {
97  // First/last items are special
98  if (index == 0 || index == priv.listView.count-1) {
99 
100  // Traversed one foldingAreaHeight. Stop at 0.3
101  if (priv.distanceFromEdge < -priv.foldingAreaHeight) {
102  return -0.3
103  }
104 
105  // We started moving, fade to 0.3
106  if (priv.distanceFromEdge < 0) {
107  return -0.3 * (-priv.distanceFromEdge / (priv.foldingAreaHeight))
108  }
109  return 0;
110  }
111 
112  // We stopped folding? Stop brightness change at 0.3
113  if (priv.overlapWithFoldedArea > 0) {
114  return -0.3;
115  }
116 
117  // We are overlapping with the folding area, fade out to 0.3
118  if (priv.overlapWithFoldingArea > 0) {
119  return - (priv.overlapWithFoldingArea * 0.3 / priv.listView.foldingStartHeight);
120  }
121  return 0;
122  }
123 
124  QtObject {
125  id: priv
126 
127  property ListView listView: root.ListView.view
128  property real totalUnfoldedHeight: listView.itemHeight + listView.spacing
129  property real totalEffectiveHeight: effectiveHeight + listView.spacing
130  property real effectiveContentY: listView.contentY - listView.originY
131  property real effectiveY: y - listView.originY
132  property real bottomDraggingDistanceOffset: listView.draggedIndex > index ? totalUnfoldedHeight : 0
133  property real distanceFromTopEdge: -(effectiveContentY + listView.topMargin - index*totalUnfoldedHeight)
134  property real distanceFromBottomEdge: listView.height - listView.bottomMargin - (effectiveY+height) + effectiveContentY + bottomDraggingDistanceOffset
135 
136  property real distanceFromEdge: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? distanceFromBottomEdge : distanceFromTopEdge
137  property real orientationFlag: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? -1 : 1
138 
139  property real overlapWithFoldingArea: listView.foldingStartHeight - distanceFromEdge
140  property real overlapWithFoldedArea: listView.foldingStopHeight - distanceFromEdge
141  property real foldingAreaHeight: listView.foldingStartHeight - listView.foldingStopHeight
142  }
143 
144 }