Lomiri
Loading...
Searching...
No Matches
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
17import QtQuick 2.12
18import Lomiri.Components 1.3
19
20LauncherDelegate {
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}