@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 20014-2015 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -16,12 +16,10 @@
1616
1717import QtQuick 2.3
1818import Ubuntu.Components 1.1
19−import QtGraphicalEffects 1.0
2019
2120Item {
2221 id: swipeToAct
2322
24− width: parent.width
2523 height: childrenRect.height
2624
2725 signal leftTriggered()
@@ -29,280 +27,213 @@ Item {
2927
3028 property string leftIconName
3129 property string rightIconName
32− readonly property double sliderHeight: units.gu(6)
33− readonly property double gap: units.gu(1)
34− readonly property double halfWay: mouseArea.drag.maximumX / 2
3530
36− Rectangle {
37− id: gradient
38− width: parent.width * 5
39− height: sliderHeight
40− visible: false
41− LinearGradient {
42− anchors.fill: parent
43− start: Qt.point(parent.x, parent.y)
44− end: Qt.point(parent.width, parent.y)
45− gradient: Gradient {
46− GradientStop { position: 0.0; color: UbuntuColors.red }
47− GradientStop { position: 0.2; color: UbuntuColors.red }
48− GradientStop { position: 0.4; color: "#dddddd" }
49− GradientStop { position: 0.6; color: "#dddddd" }
50− GradientStop { position: 0.8; color: UbuntuColors.green }
51− GradientStop { position: 1.0; color: UbuntuColors.green }
52− }
31+ QtObject {
32+ id: priv
33+
34+ property double opacityDelta
35+ readonly property double sliderHeight: units.gu(8)
36+ readonly property double gap: units.gu(1)
37+ readonly property color sliderMainColor: "#b2b2b2"
38+ readonly property color sliderBGColor: "#f4f4f4"
39+ readonly property double halfWay: mouseArea.drag.maximumX / 2
40+
41+ UbuntuNumberAnimation on opacityDelta {
42+ from: 0
43+ to: .5
44+ loops: Animation.Infinite
45+ duration: UbuntuAnimation.SleepyDuration
46+ easing.type: Easing.Linear
5347 }
54− }
5548
56− ShaderEffectSource {
57− id: effectSourceGradient
58− sourceItem: gradient
59− width: gradient.width
60− height: gradient.height
61− sourceRect: Qt.rect(0.4 * gradient.width * (slider.x / halfWay), 0, mask.width, mask.height)
62− visible: false
63− hideSource: true
49+ // linearly interpolate between start- and end-color
50+ // with a normalized weight-factor
51+ // 0.0 meaning just the start-color being taken into
52+ // account and 1.0 only taking the end-color into
53+ // account
54+ function interpolate(start, end, factor) {
55+ var rdiff = start.r > end.r ? end.r - start.r : end.r - start.r
56+ var gdiff = start.g > end.g ? end.g - start.g : end.g - start.g
57+ var bdiff = start.b > end.b ? end.b - start.b : end.b - start.b
58+ var adiff = start.a > end.a ? end.a - start.a : end.a - start.a
59+ var r = start.r + factor * rdiff
60+ var g = start.g + factor * gdiff
61+ var b = start.b + factor * bdiff
62+ var a = start.a + factor * adiff
63+ return Qt.rgba(r,g,b,a)
64+ }
6465 }
6566
6667 UbuntuShape {
67− id: mask
68− color: "black"
68+ id: row
6969 width: parent.width
70− height: sliderHeight
70+ height: priv.sliderHeight
71+ color: priv.sliderBGColor
7172 borderSource: "none"
72− visible: false
73− }
7473
75− ShaderEffectSource {
76− id: effectSourceMask
77− sourceItem: mask
78− width: mask.width
79− height: mask.height
80− visible: false
81− hideSource: true
82− }
83−
84− ShaderEffect {
85− width: parent.width
86− height: sliderHeight
87− property variant mask: effectSourceMask
88− property variant gradient: effectSourceGradient
89− vertexShader: "
90− uniform highp mat4 qt_Matrix;
91− attribute highp vec4 qt_Vertex;
92− attribute highp vec2 qt_MultiTexCoord0;
93− varying highp vec2 coord;
94− void main() {
95− coord = qt_MultiTexCoord0;
96− gl_Position = qt_Matrix * qt_Vertex;
97− }"
98− fragmentShader: "
99− varying highp vec2 coord;
100− uniform sampler2D mask;
101− uniform sampler2D gradient;
102− void main() {
103− lowp vec4 texMask = texture2D(mask, coord);
104− lowp vec4 texGradient = texture2D(gradient, coord);
105− gl_FragColor = texGradient.rgba * texMask.a ;
106− }"
74+ UbuntuShape {
75+ id: leftShape
76+ anchors.top: parent.top
77+ anchors.left: parent.left
78+ anchors.margins: priv.gap
79+ color: UbuntuColors.red
80+ borderSource: "none"
81+
82+ state: "normal"
83+ height: units.gu(6)
84+ width: units.gu(6)
85+ radius: "medium"
86+ opacity: slider.x <= priv.halfWay ? 1.0 : 1.0 - ((slider.x - priv.halfWay) / priv.halfWay)
87+
88+ Icon {
89+ anchors.centerIn: parent
90+ width: units.gu(3.5)
91+ height: units.gu(3.5)
92+ name: leftIconName
93+ color: "white"
94+ }
95+ }
10796
10897 Row {
109− id: row
110− anchors.fill: parent
111− spacing: gap
112− anchors.margins: gap
113−
114− UbuntuShape {
115− id: leftShape
116− states: [
117− State {
118− name: "normal"
119− PropertyChanges {
120− target: leftShape
121− color: UbuntuColors.red
122− }
123− PropertyChanges {
124− target: innerLeftShape
125− color: UbuntuColors.red
126− visible: false
127− }
128− },
129− State {
130− name: "selected"
131− PropertyChanges {
132− target: leftShape
133− color: "white"
134− }
135− PropertyChanges {
136− target: innerLeftShape
137− color: UbuntuColors.red
138− visible: true
139− }
140− }
141− ]
142− state: "normal"
143− height: units.gu(4)
144− width: units.gu(7)
145− borderSource: "none"
146− opacity: slider.x <= halfWay ? 1.0 : 1.0 - ((slider.x - halfWay) / halfWay)
147− UbuntuShape {
148− id: innerLeftShape
149− anchors.centerIn: parent
150− borderSource: "none"
151− width: parent.width - units.gu(.5)
152− height: parent.height - units.gu(.5)
153− }
154− Icon {
155− anchors.centerIn: parent
156− width: units.gu(2)
157− height: units.gu(2)
158− name: leftIconName
159− color: "white"
160− }
98+ anchors.verticalCenter: parent.verticalCenter
99+ anchors.right: slider.left
100+ anchors.rightMargin: units.gu(1.5)
101+ spacing: -units.gu(1)
102+ visible: slider.x === priv.halfWay
103+ Icon {
104+ name: "back"
105+ height: units.gu(2.5)
106+ color: priv.sliderMainColor
107+ opacity: .5 + priv.opacityDelta
161108 }
162−
163− Rectangle {
164− id: leftSpacer
165− width: (row.width - (leftShape.width + slider.width + rightShape.width + 4 * row.spacing)) / 2
166− height: units.gu(4)
167− opacity: 0
109+ Icon {
110+ name: "back"
111+ height: units.gu(2.5)
112+ color: priv.sliderMainColor
113+ opacity: 1 - priv.opacityDelta
168114 }
115+ }
169116
170− UbuntuShape {
171− id: slider
172− objectName: "slider"
117+ UbuntuShape {
118+ id: slider
119+ objectName: "slider"
120+ anchors.top: parent.top
121+ anchors.margins: priv.gap
122+ x: priv.halfWay
173123
174− Behavior on x {
175− UbuntuNumberAnimation {
176− duration: UbuntuAnimation.FastDuration
177− easing.type: Easing.OutBounce
178− }
179− }
124+ Component.onCompleted: {
125+ xBehavior.enabled = true
126+ }
180127
181− Behavior on opacity {
182− UbuntuNumberAnimation {
183− duration: UbuntuAnimation.FastDuration
184− }
128+ Behavior on x {
129+ id: xBehavior
130+ enabled: false
131+ UbuntuNumberAnimation {
132+ duration: UbuntuAnimation.FastDuration
133+ easing.type: Easing.OutBounce
185134 }
135+ }
186136
187− onOpacityChanged: {
188− if (opacity === 0) {
189− if (rightShape.state === "selected") {
190− rightTriggered()
191− }
192− if (leftShape.state === "selected") {
193− leftTriggered()
194− }
195− }
137+ Behavior on opacity {
138+ UbuntuNumberAnimation {
139+ duration: UbuntuAnimation.FastDuration
196140 }
141+ }
197142
198− z: 1
199− color: "white"
200− height: units.gu(4)
201− width: units.gu(7)
202− borderSource: "none"
203− Row {
204− anchors.fill: parent
205− spacing: 2 * gap
206− anchors.leftMargin: units.gu(.5)
207− anchors.rightMargin: units.gu(.5)
208− Icon {
209− anchors.verticalCenter: parent.verticalCenter
210− name: "back"
211− width: units.gu(2)
212− height: units.gu(2)
213− }
214− Icon {
215− anchors.verticalCenter: parent.verticalCenter
216− name: "next"
217− width: units.gu(2)
218− height: units.gu(2)
219− }
143+ onXChanged: {
144+ var factor
145+ if (slider.x <= priv.gap + leftShape.width)
146+ {
147+ factor = (slider.x - priv.gap) / leftShape.width
148+ slider.color = priv.interpolate(leftShape.color, priv.sliderMainColor, factor)
149+ } else if (slider.x >= rightShape.x - slider.width) {
150+ factor = (slider.x - rightShape.x + rightShape.width) / rightShape.width
151+ slider.color = priv.interpolate(priv.sliderMainColor, rightShape.color, factor)
152+ } else {
153+ slider.color = priv.sliderMainColor
220154 }
221155 }
222156
223− Rectangle {
224− id: rightSpacer
225− width: leftSpacer.width
226− height: units.gu(4)
227− opacity: 0
157+ z: 1
158+ color: priv.sliderMainColor
159+ height: units.gu(6)
160+ width: units.gu(6)
161+ borderSource: "none"
162+ radius: "medium"
163+ Icon {
164+ anchors.fill: parent
165+ anchors.margins: units.gu(1.5)
166+ source: "grip-large.svg"
167+ color: "white"
228168 }
169+ }
170+ Row {
171+ anchors.verticalCenter: parent.verticalCenter
172+ anchors.left: slider.right
173+ anchors.leftMargin: units.gu(1.5)
174+ spacing: -units.gu(1)
175+ visible: slider.x === priv.halfWay
176+ Icon {
177+ name: "next"
178+ height: units.gu(2.5)
179+ color: priv.sliderMainColor
180+ opacity: 1 - priv.opacityDelta
181+ }
182+ Icon {
183+ name: "next"
184+ height: units.gu(2.5)
185+ color: priv.sliderMainColor
186+ opacity: 0.5 + priv.opacityDelta
187+ }
188+ }
229189
230− UbuntuShape {
231− id: rightShape
232− states: [
233− State {
234− name: "normal"
235− PropertyChanges {
236− target: rightShape
237− color: UbuntuColors.green
238− }
239− PropertyChanges {
240− target: innerRightShape
241− color: UbuntuColors.green
242− visible: false
243− }
244− },
245− State {
246− name: "selected"
247− PropertyChanges {
248− target: rightShape
249− color: "white"
250− }
251− PropertyChanges {
252− target: innerRightShape
253− color: UbuntuColors.green
254− visible: true
255− }
256− }
257− ]
258− state: "normal"
259− height: units.gu(4)
260− width: units.gu(7)
261− borderSource: "none"
262− opacity: slider.x >= halfWay ? 1.0 : slider.x / halfWay
263− UbuntuShape {
264− id: innerRightShape
265− anchors.centerIn: parent
266− borderSource: "none"
267− width: parent.width - units.gu(.5)
268− height: parent.height - units.gu(.5)
269− }
270− Icon {
271− anchors.centerIn: parent
272− width: units.gu(2)
273− height: units.gu(2)
274− name: rightIconName
275− color: "white"
276− }
190+ UbuntuShape {
191+ id: rightShape
192+ anchors.top: parent.top
193+ anchors.right: parent.right
194+ anchors.margins: priv.gap
195+ color: UbuntuColors.green
196+ borderSource: "none"
197+
198+ state: "normal"
199+ height: units.gu(6)
200+ width: units.gu(6)
201+ radius: "medium"
202+ opacity: slider.x >= priv.halfWay ? 1.0 : slider.x / priv.halfWay
203+
204+ Icon {
205+ anchors.centerIn: parent
206+ width: units.gu(3.5)
207+ height: units.gu(3.5)
208+ name: rightIconName
209+ color: "white"
277210 }
278211 }
212+ }
279213
280− MouseArea {
281− id: mouseArea
282− objectName: "swipeMouseArea"
214+ MouseArea {
215+ id: mouseArea
216+ objectName: "swipeMouseArea"
283217
284− anchors.fill: row
285− drag.target: slider
286− drag.axis: Drag.XAxis
287− drag.minimumX: 0
288− drag.maximumX: row.width - slider.width
218+ anchors.fill: row
219+ drag.target: slider
220+ drag.axis: Drag.XAxis
221+ drag.minimumX: priv.gap
222+ drag.maximumX: row.width - slider.width - priv.gap
289223
290− onReleased: {
291− if (slider.x !== drag.minimumX || slider.x !== drag.maximumX) {
292− slider.x = halfWay
293− }
294− if (slider.x === drag.minimumX) {
295− slider.x = drag.minimumX
296− slider.opacity = 0
297− enabled = false
298− leftShape.state = "selected"
299− }
300− if (slider.x === drag.maximumX) {
301− slider.x = drag.maximumX
302− slider.opacity = 0
303− enabled = false
304− rightShape.state = "selected"
305− }
224+ onReleased: {
225+ if (slider.x !== drag.minimumX || slider.x !== drag.maximumX) {
226+ slider.x = priv.halfWay
227+ }
228+ if (slider.x === drag.minimumX) {
229+ slider.x = drag.minimumX
230+ enabled = false
231+ leftTriggered()
232+ }
233+ if (slider.x === drag.maximumX) {
234+ slider.x = drag.maximumX
235+ enabled = false
236+ rightTriggered()
306237 }
307238 }
308239 }