on bf4f7ea help sign in
unity8/Components/Revealer.qml
241 lines 7.6 kB history raw
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 */
17import QtQuick 2.0
18import Ubuntu.Components 0.1
20Item {
21 id: revealer
23 property Showable target
24 property var hintingAnimation: hintingAnimation
25 property string boundProperty: orientation == Qt.Vertical ? "y" : "x"
26 property int orientation: Qt.Vertical
27 property int direction: Qt.LeftToRight
28 property real openedValue: orientation == Qt.Vertical ? y : x
29 property real closedValue: orientation == Qt.Vertical ? y + (direction == Qt.LeftToRight ? -height : height) : x + (direction == Qt.LeftToRight ? -width : width)
30 property real hintDisplacement: 0
31 property real handleSize: units.gu(2)
32 property real dragVelocity: draggingArea.dragVelocity != 0 ? Math.abs(draggingArea.dragVelocity) : -1
33 property real dragVelocityThreshold: units.gu(5)
34 property bool dragging: false
35 property bool pressed: draggingArea.pressed
36 property int lateralPosition: draggingArea.lateralPosition
37 property real dragPosition
38 property bool openOnPress: true
40 signal openPressed(int mouseX, int mouseY)
41 signal openReleased(int mouseX, int mouseY)
42 signal closePressed
43 signal openClicked
44 signal closeClicked
46 dragPosition: {
47 var value
48 if (orientation == Qt.Vertical) {
49 value = draggingArea.dragValue + draggingArea.y
50 if (direction == Qt.RightToLeft) {
51 value += draggingArea.height - height
52 }
53 } else {
54 value = draggingArea.dragValue + draggingArea.x
55 if (direction == Qt.RightToLeft) {
56 value += draggingArea.width - width
57 }
58 }
59 if (__opened) {
60 if (direction == Qt.LeftToRight) {
61 value += handleSize
62 } else {
63 value -= handleSize
64 }
65 } else if (dragging) {
66 if (direction == Qt.LeftToRight) {
67 value += hintDisplacement
68 } else {
69 value -= hintDisplacement
70 }
71 }
73 return value
74 }
75 property var draggingArea: leftDraggingArea.enabled ? leftDraggingArea : rightDraggingArea
77 property real __hintValue: closedValue + (direction == Qt.LeftToRight ? hintDisplacement : -hintDisplacement)
79 function dragToValue(dragPosition) {
80 return dragPosition + closedValue
81 }
83 property bool __opened: target.shown
84 enabled: target.available
86 // Can be replaced with a fake implementation during tests
87 // property var __getCurrentTimeMs: function () { return new Date().getTime() }
88 property var __dateTime: new function() {
89 this.getCurrentTimeMs = function() {return new Date().getTime()}
90 }
92 Component.onCompleted: target[boundProperty] = __opened ? openedValue : closedValue
93 onOpenedValueChanged: if (__opened && !dragging) target[boundProperty] = openedValue
94 onClosedValueChanged: if (!__opened && !dragging) target[boundProperty] = closedValue
96 function __computeValue(dragPosition) {
97 return MathUtils.clamp(dragToValue(dragPosition), __hintValue, openedValue)
98 }
100 function __open() {
101 hintingAnimation.stop()
102 target.show()
103 }
105 function __close() {
106 hintingAnimation.stop()
107 target.hide()
108 }
110 function __hint() {
111 target.showAnimation.stop()
112 target.hideAnimation.stop()
113 hintingAnimation.restart()
114 }
116 function __settle() {
117 hintingAnimation.stop()
118 if (__opened) target.show()
119 else target.hide()
120 }
122 function __startDragging() {
123 hintingAnimation.stop()
124 dragging = true
125 }
127 function __endDragging(dragVelocity) {
128 dragging = false
129 if (revealer.direction == Qt.RightToLeft) {
130 dragVelocity = -dragVelocity
131 }
132 if (Math.abs(dragVelocity) >= dragVelocityThreshold) {
133 if (dragVelocity > 0) __open()
134 else __close()
135 } else {
136 __settle()
137 }
138 }
140 Binding {
141 id: dragBinding
143 target: revealer.target
144 property: revealer.boundProperty
145 value: __computeValue(dragPosition)
146 when: dragging
147 }
149 SmoothedAnimation {
150 id: hintingAnimation
152 target: revealer.target
153 property: revealer.boundProperty
154 duration: 150
155 to: revealer.__hintValue
156 }
158 DraggingArea {
159 id: leftDraggingArea
161 property bool isOpeningArea: revealer.direction == Qt.LeftToRight
163 height: orientation == Qt.Vertical ? handleSize : parent.height
164 width: orientation == Qt.Horizontal ? handleSize : parent.width
165 orientation: revealer.orientation
166 enabled: isOpeningArea ? !revealer.__opened : revealer.__opened
168 __dateTime: revealer.__dateTime
170 onPressed: {
171 if (isOpeningArea) {
172 if (revealer.openOnPress) {
173 revealer.openPressed(mouseX, mouseY)
174 __hint()
175 }
176 } else {
177 revealer.closePressed()
178 }
179 }
180 onReleased: {
181 if (isOpeningArea && revealer.openOnPress) {
182 revealer.openReleased(mouseX, mouseY)
183 __settle()
184 }
185 }
186 onDragStart: __startDragging()
187 onDragEnd: __endDragging(dragVelocity)
188 onClicked: {
189 if (clickValidated) {
190 if (isOpeningArea) {
191 if (revealer.openOnPress) revealer.openClicked()
192 } else {
193 revealer.closeClicked()
194 }
195 }
196 }
197 }
199 DraggingArea {
200 id: rightDraggingArea
202 property bool isOpeningArea: revealer.direction == Qt.RightToLeft
204 x: orientation == Qt.Vertical ? 0 : parent.width - width
205 y: orientation == Qt.Vertical ? parent.height - height : 0
206 height: orientation == Qt.Vertical ? handleSize : parent.height
207 width: orientation == Qt.Horizontal ? handleSize : parent.width
208 orientation: revealer.orientation
209 enabled: isOpeningArea ? !revealer.__opened : revealer.__opened
211 __dateTime: revealer.__dateTime
213 onPressed: {
214 if (isOpeningArea) {
215 if (revealer.openOnPress) {
216 revealer.openPressed(mouseX, mouseY)
217 __hint()
218 }
219 } else {
220 revealer.closePressed()
221 }
222 }
223 onReleased: {
224 if (isOpeningArea && revealer.openOnPress) {
225 revealer.openReleased(mouseX, mouseY)
226 __settle()
227 }
228 }
229 onDragStart: __startDragging()
230 onDragEnd: __endDragging(dragVelocity)
231 onClicked: {
232 if (clickValidated) {
233 if (isOpeningArea) {
234 if (revealer.openOnPress) revealer.openClicked()
235 } else {
236 revealer.closeClicked()
237 }
238 }
239 }
240 }