on bbbdccd help sign in
unity8/qml/Notifications/SwipeToAct.qml
275 lines 8.6 kB history raw
1/*
2 * Copyright (C) 2014-2015 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 */
17import QtQuick 2.4
18import Ubuntu.Components 1.3
20Item {
21 id: swipeToAct
23 height: clickToAct ? leftButton.height : childrenRect.height
25 signal leftTriggered()
26 signal rightTriggered()
28 property string leftIconName
29 property string rightIconName
31 property bool clickToAct
33 QtObject {
34 id: priv
36 property double opacityDelta
37 readonly property double sliderHeight: units.gu(8)
38 readonly property double gap: units.gu(1)
39 readonly property color sliderMainColor: "#b2b2b2"
40 readonly property color sliderBGColor: "#f4f4f4"
41 readonly property double halfWay: mouseArea.drag.maximumX / 2
43 UbuntuNumberAnimation on opacityDelta {
44 from: 0
45 to: .5
46 loops: Animation.Infinite
47 duration: UbuntuAnimation.SleepyDuration
48 easing.type: Easing.Linear
49 }
51 // linearly interpolate between start- and end-color
52 // with a normalized weight-factor
53 // 0.0 meaning just the start-color being taken into
54 // account and 1.0 only taking the end-color into
55 // account
56 function interpolate(start, end, factor) {
57 var rdiff = start.r > end.r ? end.r - start.r : end.r - start.r
58 var gdiff = start.g > end.g ? end.g - start.g : end.g - start.g
59 var bdiff = start.b > end.b ? end.b - start.b : end.b - start.b
60 var adiff = start.a > end.a ? end.a - start.a : end.a - start.a
61 var r = start.r + factor * rdiff
62 var g = start.g + factor * gdiff
63 var b = start.b + factor * bdiff
64 var a = start.a + factor * adiff
65 return Qt.rgba(r,g,b,a)
66 }
67 }
69 Button {
70 id: leftButton
71 objectName: "leftButton"
72 anchors.verticalCenter: parent.verticalCenter
73 anchors.left: parent.left
74 iconName: leftIconName
75 visible: clickToAct
76 width: (parent.width / 2) - priv.gap
77 color: UbuntuColors.red
78 onClicked: {
79 leftTriggered()
80 }
81 }
83 Button {
84 id: rightButton
85 objectName: "rightButton"
86 anchors.verticalCenter: parent.verticalCenter
87 anchors.right: parent.right
88 iconName: rightIconName
89 visible: clickToAct
90 width: (parent.width / 2) - priv.gap
91 color: UbuntuColors.green
92 onClicked: {
93 rightTriggered()
94 }
95 }
97 UbuntuShape {
98 id: row
99 width: parent.width
100 height: priv.sliderHeight
101 backgroundColor: priv.sliderBGColor
102 aspect: UbuntuShape.Flat
103 visible: !clickToAct
105 UbuntuShape {
106 id: leftShape
107 objectName: "leftArea"
108 anchors.top: parent.top
109 anchors.left: parent.left
110 anchors.margins: priv.gap
111 backgroundColor: UbuntuColors.red
112 aspect: UbuntuShape.Flat
114 state: "normal"
115 height: units.gu(6)
116 width: units.gu(6)
117 radius: "medium"
118 opacity: slider.x <= priv.halfWay ? 1.0 : 1.0 - ((slider.x - priv.halfWay) / priv.halfWay)
120 Icon {
121 anchors.centerIn: parent
122 width: units.gu(3.5)
123 height: units.gu(3.5)
124 name: leftIconName
125 color: "white"
126 }
127 }
129 Row {
130 anchors.verticalCenter: parent.verticalCenter
131 anchors.right: slider.left
132 anchors.rightMargin: units.gu(1.5)
133 spacing: -units.gu(1)
134 visible: slider.x === priv.halfWay
135 Icon {
136 name: "back"
137 height: units.gu(2.5)
138 color: priv.sliderMainColor
139 opacity: .5 + priv.opacityDelta
140 }
141 Icon {
142 name: "back"
143 height: units.gu(2.5)
144 color: priv.sliderMainColor
145 opacity: 1 - priv.opacityDelta
146 }
147 }
149 UbuntuShape {
150 id: slider
151 objectName: "slider"
152 anchors.top: parent.top
153 anchors.margins: priv.gap
154 x: priv.halfWay
156 Component.onCompleted: {
157 xBehavior.enabled = true
158 }
160 Behavior on x {
161 id: xBehavior
162 enabled: false
163 UbuntuNumberAnimation {
164 duration: UbuntuAnimation.FastDuration
165 easing.type: Easing.OutBounce
166 }
167 }
169 Behavior on opacity {
170 UbuntuNumberAnimation {
171 duration: UbuntuAnimation.FastDuration
172 }
173 }
175 onXChanged: {
176 var factor
177 if (slider.x <= priv.gap + leftShape.width)
178 {
179 factor = (slider.x - priv.gap) / leftShape.width
180 slider.color = priv.interpolate(leftShape.color, priv.sliderMainColor, factor)
181 } else if (slider.x >= rightShape.x - slider.width) {
182 factor = (slider.x - rightShape.x + rightShape.width) / rightShape.width
183 slider.color = priv.interpolate(priv.sliderMainColor, rightShape.color, factor)
184 } else {
185 slider.color = priv.sliderMainColor
186 }
187 }
189 z: 1
190 backgroundColor: priv.sliderMainColor
191 height: units.gu(6)
192 width: units.gu(6)
193 aspect: UbuntuShape.Flat
194 radius: "medium"
195 Icon {
196 anchors.fill: parent
197 anchors.margins: units.gu(1.5)
198 source: "grip-large.svg"
199 color: "white"
200 }
201 }
203 Row {
204 anchors.verticalCenter: parent.verticalCenter
205 anchors.left: slider.right
206 anchors.leftMargin: units.gu(1.5)
207 spacing: -units.gu(1)
208 visible: slider.x === priv.halfWay
209 Icon {
210 name: "next"
211 height: units.gu(2.5)
212 color: priv.sliderMainColor
213 opacity: 1 - priv.opacityDelta
214 }
215 Icon {
216 name: "next"
217 height: units.gu(2.5)
218 color: priv.sliderMainColor
219 opacity: 0.5 + priv.opacityDelta
220 }
221 }
223 UbuntuShape {
224 id: rightShape
225 objectName: "rightArea"
226 anchors.top: parent.top
227 anchors.right: parent.right
228 anchors.margins: priv.gap
229 backgroundColor: UbuntuColors.green
230 aspect: UbuntuShape.Flat
232 state: "normal"
233 height: units.gu(6)
234 width: units.gu(6)
235 radius: "medium"
236 opacity: slider.x >= priv.halfWay ? 1.0 : slider.x / priv.halfWay
238 Icon {
239 anchors.centerIn: parent
240 width: units.gu(3.5)
241 height: units.gu(3.5)
242 name: rightIconName
243 color: "white"
244 }
245 }
246 }
248 MouseArea {
249 id: mouseArea
250 objectName: "swipeMouseArea"
251 enabled: !clickToAct
253 anchors.fill: row
254 drag.target: slider
255 drag.axis: Drag.XAxis
256 drag.minimumX: priv.gap
257 drag.maximumX: row.width - slider.width - priv.gap
259 onReleased: {
260 if (slider.x !== drag.minimumX || slider.x !== drag.maximumX) {
261 slider.x = priv.halfWay
262 }
263 if (slider.x === drag.minimumX) {
264 slider.x = drag.minimumX
265 enabled = false
266 leftTriggered()
267 }
268 if (slider.x === drag.maximumX) {
269 slider.x = drag.maximumX
270 enabled = false
271 rightTriggered()
272 }
273 }
274 }