-
Notifications
You must be signed in to change notification settings - Fork 0
/
MySwitch.qml
278 lines (210 loc) · 7.73 KB
/
MySwitch.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
import QtQuick 2.5
import QtGraphicalEffects 1.0
import QtQuick.Window 2.0
import QuickAndroid 0.1
import QuickAndroid.Private 0.1
//import ".."
/*
USING
MySwitch{
id:commentsSwitch
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 16*A.dp
}
*/
/*!
\qmltype AppSwitch
\inqmlmodule VPlayApps 1.0
\ingroup apps-controls
\brief An on/off button-like control
This displays a slide-able switch which can be used to toggle some functionality on or off.
It has a \l checked property, that can be modified by the user, either by sliding the
switch to the left (off) or to the right (on), or by simply tapping on it (toggles on/off).
It will emit the signal \l toggled, when the \l checked state has changed.
By default, the styling of the button is changed to match different platforms.
*/
Item {
id: control
// Public API
/*!
A Boolean property that determines the off/on state of the switch. Set this property to \c true or \c false to
change the switch's state.
\sa toggle()
\sa setChecked()
*/
property bool checked: false
/*!
The background color when the switch is on.
\since V-Play 2.6.2
*/
property color backgroundColorOn: "skyblue"//Theme.isAndroid ? Theme.tintLightColor : Theme.tintColor
/*!
The background color when the switch is on and pressed.
\since V-Play 2.6.2
*/
property color backgroundColorOnPressed: "skyblue" //Theme.tintLightColor
/*!
The background color when the switch is off.
\since V-Play 2.6.2
*/
property color backgroundColorOff: "#ccc"//Theme.isAndroid ? "#ccc" : "white"
/*!
The background color when the switch is off and pressed.
\since V-Play 2.6.2
*/
property color backgroundColorOffPressed: "#ccc"//Theme.isAndroid ? "#ccc" : "#E5E5E5"
/*!
The knob color when the switch is off.
\since V-Play 2.6.2
*/
property color knobColorOff: "white"
/*!
The knob color when the switch is on.
\since V-Play 2.6.2
*/
property color knobColorOn: "dodgerblue"//Theme.isAndroid ? Theme.tintColor : "white"
/*!
The border color of the knob.
\since V-Play 2.6.2
*/
property color knobBorderColor: knob.color//Theme.isAndroid ? knob.color : "#E5E5E5"
/*!
\internal
Whether the knob should drop a shadow.
Internal for now, as changing that property on iOS leads to a broken control
\since V-Play 2.6.2
*/
property bool dropShadow: true//Theme.isAndroid
/*!
\internal
If set to false, the checked property is not changed when this control is toggled. Can be useful if it is bound
to some other value.
*/
property bool updateChecked: true
/*!
Emitted each time the \l checked state of the switch changes. This is the case when the user toggles the button or
it gets set from within your code.
*/
signal toggled()
/*!
Call this method to toggle the current \l checked state of the switch. If the switch is currently off it changes to
on and vice-versa.
\sa checked
\sa setChecked()
*/
function toggle() {
setChecked(!control.checked)
}
/*!
Call this method to set the current \l checked state of the switch. This has the same effect as setting the
\l{checked} property directly.
\sa checked
\sa toggle()
*/
function setChecked(checked) {
if(checked !== control.checked) {
if(updateChecked) {
control.checked = checked
}
control.toggled()
}
}
// Public API end
height: 22*Device.dp//dp(Theme.isAndroid ? 22 : 30)
width: height / 0.55//Theme.isAndroid ? height / 0.65 : height / 0.59
Rectangle {
id: background
radius: height
width: control.width
height: control.height/1.5 //Theme.isAndroid ? control.height / 1.5 : control.height
anchors.verticalCenter: parent.verticalCenter
color: knobContainer.effectiveChecked
? (innerArea.pressed ? backgroundColorOnPressed : backgroundColorOn)
: (innerArea.pressed ? backgroundColorOffPressed : backgroundColorOff)
border.color: control.checked ? backgroundColorOn : backgroundColorOffPressed
border.width: control.height * 0.04//(Theme.isAndroid ? 0.04 : 0.048)
Behavior on color {
ColorAnimation { duration: 150 }
}
Behavior on border.color {
ColorAnimation { duration: 150 }
}
// the container for the knob (needed because of knob shadow)
Item {
id: knobContainer
width: knobWidth + (2 * knobShadow.radius)
height: knobWidth + (2 * knobShadow.radius)
visible: !dropShadow
readonly property bool dragChecked: x > xMiddle
readonly property bool effectiveChecked: innerArea.drag.active ? dragChecked : control.checked
readonly property real offset: background.border.width
property color knobColor: effectiveChecked ? control.knobColorOn : control.knobColorOff
readonly property real knobWidth: control.height - background.border.width * 2
readonly property real xLeft: offset - 2 * knobShadow.radius
readonly property real xRight: control.width - offset - knobContainer.width + 2 * knobShadow.radius
readonly property real xMiddle: (xLeft + xRight) / 2
readonly property real xDefault: (control.checked ? xRight : xLeft)
x: xDefault
y: offset - background.y - knobShadow.radius
// Inner knob
Rectangle {
id: knob
anchors.centerIn: parent
width: parent.knobWidth
height: parent.knobWidth
radius: height * 0.5
color: parent.knobColor
border.color: control.knobBorderColor
border.width: control.height * 0.04
}
Behavior on knobColor {
ColorAnimation { duration: 150 }
}
Behavior on x {
NumberAnimation { easing.type: Easing.InOutQuad; duration: 150 }
}
}
// add drop shadow
DropShadow {
id: knobShadow
radius: dropShadow ? control.height * 0.1 : 0
samples: radius * 2
verticalOffset: radius * 0.5
anchors.fill: source
source: knobContainer
color: Qt.rgba(0, 0, 0, 0.2)
visible: control.dropShadow
}
}
MouseArea {
id: innerArea
anchors.fill: parent
//radius: control.height
// move ripple effect with knob
property real knobX: background.x + knobContainer.x + knob.x + knob.width / 2
property real knobY: background.y + knobContainer.y + knob.y + knob.height / 2
//touchPoint: Qt.point(knobX, knobY)
//fixedPosition: false // always follow touch point
//centerAnimation: true // always center fill animation
// don't cancel events if mouse moved too much (because of because of dragging feature)
//cancelOnMouseMove: false
// configure mouse area drag and toggle
property bool dragged: false
drag.onActiveChanged: if(drag.active) dragged = true
drag.target: knobContainer
drag.axis: Drag.XAxis
drag.minimumX: knobContainer.xLeft
drag.maximumX: knobContainer.xRight
onReleased: {
if(dragged) {
control.setChecked(knobContainer.dragChecked)
//MouseArea's drag and drop overrides x binding -> set it again
knobContainer.x = Qt.binding(function() { return knobContainer.xDefault })
}
else
toggle()
dragged = false
}
}
}