@@ -16,7 +16,7 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19−
19+import QtGraphicalEffects 1.0
2020Item {
2121 id: root
2222
@@ -37,17 +37,21 @@ Item {
3737
3838 property bool dragging:false
3939
40+ property alias brightness: brightnessEffect.brightness
41+
4042 signal clicked()
4143 signal longtap()
4244 signal released()
4345
46+ onYChanged: print("y is", y)
47+
4448 UbuntuShape {
4549 id: iconItem
4650 color: Qt.rgba(0, 0, 1, 0.5)
4751 width: parent.width
4852 height: parent.height
4953 anchors.centerIn: parent
50− anchors.verticalCenterOffset: root.offset + (height - root.effectiveHeight)/2 * (angle < 0 ? -1 : 1)
54+ anchors.verticalCenterOffset: root.offset + (height - root.effectiveHeight)/2 * (angle < 0 ? 1 : -1)
5155 rotation: root.inverted ? 180 : 0
5256 radius: "medium"
5357
@@ -58,6 +62,7 @@ Item {
5862 }
5963
6064 image: Image {
65+ id: iconImage
6166 source: "../graphics/applicationIcons/" + root.iconName + ".png"
6267 }
6368
@@ -84,6 +89,27 @@ Item {
8489 width: iconItem.width + units.gu(1.5)
8590 height: width
8691 }
92+
93+ BrightnessContrast {
94+ id: brightnessEffect
95+ anchors.fill: parent
96+ source: parent
97+ brightness: 0
98+ }
99+ }
100+
101+ QtObject {
102+ id: priv
103+ property real totalUnfoldedHeight: launcherFlickable.itemSize + launcherColumn.spacing
104+ property real totalEffectiveHeight: effectiveHeight + launcherColumn.spacing
105+ property real distanceFromTopEdge: -(launcherFlickable.contentY - itemsBeforeThis*totalUnfoldedHeight)
106+ property real distanceFromBottomEdge: launcherFlickable.height - (y+height) + launcherFlickable.contentY
107+
108+ property real distanceFromEdge: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? distanceFromBottomEdge : distanceFromTopEdge
109+ property real orientationFlag: Math.abs(distanceFromBottomEdge) < Math.abs(distanceFromTopEdge) ? -1 : 1
110+
111+ property real overlapWithFoldingArea: totalUnfoldedHeight - distanceFromEdge
112+
87113 }
88114
89115 states: [
@@ -91,15 +117,97 @@ Item {
91117 name: "docked"
92118 PropertyChanges {
93119 target: root
94− offset: if (launcherFlickable.contentY > itemsBeforeThis * (foldedHeight + launcherColumn.spacing*2)) {
95− return launcherFlickable.contentY - (index * (foldedHeight + launcherColumn.spacing*2));
96− } else if (y + height - launcherFlickable.contentY > launcherFlickable.height - (itemsAfterThis*(foldedHeight - launcherColumn.spacing))) {
97− return launcherFlickable.height - (y+height) + launcherFlickable.contentY - (itemsAfterThis*(foldedHeight - launcherColumn.spacing));
98− } else {
99− return 0;
120+
121+ offset: {
122+ // First/last items are special
123+ if (index == 0 || index == iconRepeater.count-1) {
124+ // Just keep them bound to the edges in case they're outside of the visible area
125+ if (priv.distanceFromEdge < 0) {
126+ return (-priv.distanceFromEdge - (height - effectiveHeight)) * priv.orientationFlag;
100127 }
101− angle: -Math.min(Math.max(offset * maxAngle / foldedHeight, -maxAngle), maxAngle)
128+ return 0;
129+ }
130+
131+ // Are we already completely outside the flickable? Stop the icon here.
132+ if (priv.distanceFromEdge < -priv.totalUnfoldedHeight) {
133+ return (-priv.distanceFromEdge - effectiveHeight) * priv.orientationFlag
134+ }
135+
136+ // We're touching the edge, move slower than the actual flicking speed.
137+ if (priv.distanceFromEdge < 0) {
138+ return (Math.abs(priv.distanceFromEdge) * priv.totalEffectiveHeight / priv.totalUnfoldedHeight) * priv.orientationFlag
139+ }
140+
141+ return 0;
102142
143+ }
144+
145+ angle: {
146+ // First item is special
147+ if (index == 0 || index == iconRepeater.count-1) {
148+ if (priv.distanceFromEdge < 0) {
149+ // distanceFromTopEdge : angle = totalUnfoldedHeight/2 : maxAngle
150+ return Math.max(-maxAngle, priv.distanceFromEdge * maxAngle / (priv.totalUnfoldedHeight)) * priv.orientationFlag
151+ }
152+ return 0; // Don't fold first item as long as inside the view
153+ }
154+
155+ // Are we in the already completely outside the flickable? Fold for the last 5 degrees
156+ if (priv.distanceFromEdge < 0) {
157+ // -distanceFromTopEdge : angle = totalUnfoldedHeight : 5
158+ return Math.max(-maxAngle, (priv.distanceFromEdge * 5 / priv.totalUnfoldedHeight) - (maxAngle-5)) * priv.orientationFlag
159+ }
160+
161+ // We are overlapping with the folding area, fold the icon to maxAngle - 5 degrees
162+ if (priv.overlapWithFoldingArea > 0) {
163+ // overlap: totalHeight = angle : (maxAngle - 5)
164+ return -priv.overlapWithFoldingArea * (maxAngle -5) / priv.totalUnfoldedHeight * priv.orientationFlag;
165+
166+ }
167+
168+ return 0;
169+ }
170+
171+ opacity: {
172+ // First item is special
173+ if (index == 0 || index == iconRepeater.count-1) {
174+ if (priv.distanceFromEdge < 0) {
175+ // Fade from 1 to 0 in the distance of 2 items height (which is when the next item reaches the edge)
176+ return 1.0 - (-priv.distanceFromEdge / (priv.totalUnfoldedHeight * 2))
177+ }
178+ return 1; // Don't make first/last item transparent as long as inside the view
179+ }
180+
181+ // Are we in the already completely outside the flickable? Fade to from 0.75 to 0 in twice 2 items height
182+ if (priv.distanceFromEdge < 0) {
183+ // -distanceFromEdge : 1-opacity = totalUnfoldedHeight : 0.75
184+ return 0.75 - (-priv.distanceFromEdge * 0.75 / (priv.totalUnfoldedHeight*2))
185+ }
186+
187+ // We are overlapping with the folding area, fade out to 0.75
188+ if (priv.overlapWithFoldingArea > 0) {
189+ // overlap : totalHeight = 1-opacity : 0.25
190+ return 1 - (priv.overlapWithFoldingArea * 0.25 / priv.totalUnfoldedHeight)
191+ }
192+ return 1;
193+ }
194+
195+ brightness: {
196+ if (index == 0 || index == iconRepeater.count-1) {
197+ if (priv.distanceFromEdge < 0) {
198+ return -(-priv.distanceFromEdge / (priv.totalUnfoldedHeight * 2))
199+ }
200+ return 0;
201+ }
202+ if (priv.distanceFromEdge < 0) {
203+ return -0.3 - (-priv.distanceFromEdge * 0.1 / (priv.totalUnfoldedHeight*2))
204+ }
205+
206+ if (priv.overlapWithFoldingArea > 0) {
207+ return - (priv.overlapWithFoldingArea * 0.3 / priv.totalUnfoldedHeight)
208+ }
209+ return 0;
210+ }
103211 }
104212 },
105213