2 * Copyright (C) 2014-2015 Canonical Ltd.
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.
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.
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/>.
18import Lomiri.Components 1.3
23 height: clickToAct ? leftButton.height : row.height
25 signal leftTriggered()
26 signal rightTriggered()
28 property string leftIconName
29 property string rightIconName
31 property bool clickToAct
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: theme.palette.normal.base
40 readonly property color sliderBGColor: theme.palette.normal.background
41 readonly property double halfWay: mouseArea.drag.maximumX / 2
43 LomiriNumberAnimation on opacityDelta {
46 loops: Animation.Infinite
47 duration: LomiriAnimation.SleepyDuration
48 easing.type: Easing.Linear
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
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)
71 objectName: "leftButton"
72 anchors.verticalCenter: parent.verticalCenter
73 anchors.left: parent.left
74 iconName: leftIconName
77 width: (parent.width / 2) - priv.gap / 2
78 color: theme.palette.normal.negative
79 onClicked: leftTriggered()
84 objectName: "rightButton"
85 anchors.verticalCenter: parent.verticalCenter
86 anchors.right: parent.right
87 iconName: rightIconName
90 width: (parent.width / 2) - priv.gap / 2
91 color: theme.palette.normal.positive
92 onClicked: rightTriggered()
98 height: priv.sliderHeight
99 backgroundColor: priv.sliderBGColor
100 aspect: LomiriShape.Flat
105 objectName: "leftArea"
106 anchors.top: parent.top
107 anchors.left: parent.left
108 anchors.margins: priv.gap
109 backgroundColor: theme.palette.normal.negative
110 aspect: LomiriShape.Flat
115 opacity: slider.x <= priv.halfWay ? 1.0 : 1.0 - ((slider.x - priv.halfWay) / priv.halfWay)
118 anchors.centerIn: parent
120 height: units.gu(3.5)
127 anchors.verticalCenter: parent.verticalCenter
128 anchors.right: slider.left
129 anchors.rightMargin: units.gu(1.5)
130 spacing: -units.gu(1)
131 visible: slider.x === priv.halfWay
134 height: units.gu(2.5)
135 color: priv.sliderMainColor
136 opacity: .5 + priv.opacityDelta
140 height: units.gu(2.5)
141 color: priv.sliderMainColor
142 opacity: 1 - priv.opacityDelta
149 anchors.top: parent.top
150 anchors.margins: priv.gap
153 // Used by the tests to determine when the slider is ready to move
154 readonly property bool atRest: ((x === priv.halfWay) && (!mouseArea.dragging) && (!sliderXAnimation.running))
156 Component.onCompleted: {
157 xBehavior.enabled = true
163 LomiriNumberAnimation {
165 duration: LomiriAnimation.FastDuration
166 easing.type: Easing.OutBounce
170 Behavior on opacity {
171 LomiriNumberAnimation {
172 duration: LomiriAnimation.FastDuration
178 if (slider.x <= priv.gap + leftShape.width)
180 factor = (slider.x - priv.gap) / leftShape.width
181 slider.color = priv.interpolate(leftShape.color, priv.sliderMainColor, factor)
182 } else if (slider.x >= rightShape.x - slider.width) {
183 factor = (slider.x - rightShape.x + rightShape.width) / rightShape.width
184 slider.color = priv.interpolate(priv.sliderMainColor, rightShape.color, factor)
186 slider.color = priv.sliderMainColor
191 backgroundColor: priv.sliderMainColor
194 aspect: LomiriShape.Flat
198 anchors.margins: units.gu(1.5)
205 anchors.verticalCenter: parent.verticalCenter
206 anchors.left: slider.right
207 anchors.leftMargin: units.gu(1.5)
208 spacing: -units.gu(1)
209 visible: slider.x === priv.halfWay
212 height: units.gu(2.5)
213 color: priv.sliderMainColor
214 opacity: 1 - priv.opacityDelta
218 height: units.gu(2.5)
219 color: priv.sliderMainColor
220 opacity: 0.5 + priv.opacityDelta
226 objectName: "rightArea"
227 anchors.top: parent.top
228 anchors.right: parent.right
229 anchors.margins: priv.gap
230 backgroundColor: theme.palette.normal.positive
231 aspect: LomiriShape.Flat
236 opacity: slider.x >= priv.halfWay ? 1.0 : slider.x / priv.halfWay
239 anchors.centerIn: parent
241 height: units.gu(3.5)
250 objectName: "swipeMouseArea"
255 drag.axis: Drag.XAxis
256 drag.minimumX: priv.gap
257 drag.maximumX: row.width - slider.width - priv.gap
260 if (slider.x !== drag.minimumX || slider.x !== drag.maximumX) {
261 slider.x = priv.halfWay
263 if (slider.x === drag.minimumX) {
264 slider.x = drag.minimumX
268 if (slider.x === drag.maximumX) {
269 slider.x = drag.maximumX