PDA

View Full Version : Swipe (Edge Swipe) in QML



sedi
21st November 2016, 13:22
To pull in a side menu on touch devices, I'd like to react to a (preferably single finger) slide gesture starting from outside of the screen. Google's material style seems to call this an "Edge swipe (https://material.google.com/patterns/gestures.html#gestures-drag-swipe-or-fling-details)"

I have looked into SwipeView QML Type (http://doc.qt.io/qt-5/qml-qtquick-controls2-swipeview.html), but this seems to be targeted for entirely different needs. Customizing the SwipeDelegate (http://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-swipedelegate) appears to be used with "normal" in-screen swipes.

Any starting point or documentation hint would be very welcome!

sedi
21st November 2016, 19:25
UPDATE: I've found this (https://gist.github.com/kovrov/1742405) meanwhile, seems to be a good way to do it. I have added an "edgeSwipe(string fromDirection)" signal and updated onReleased this way:


onReleased: {
switch (drag.axis) {
case Drag.XAndYAxis:
canceled(mouse)
break
case Drag.XAxis:
if (detectEdgeSwipe && origin.x <= 5) {
edgeSwipe("fromLeft")
} else if (detectEdgeSwipe && origin.x >= parent.parent.width-5){
edgeSwipe("fromRight")
} else {
swipe(mouse.x - origin.x < 0 ? "left" : "right")
}
break
case Drag.YAxis:
if (detectEdgeSwipe && origin.y <= 5) {
edgeSwipe("fromTop")
} else if (detectEdgeSwipe && origin.y >= parent.parent.height-5) {
edgeSwipe("fromBottom")
} else {
swipe(mouse.y - origin.y < 0 ? "up" : "down")
}
break
}
}

The problem is, that swipes that originate from outside the screen are not being registered at all. Any ideas?

john_god
18th January 2017, 10:50
I have done something like that in the past before swipeview was available, something like this should work:




import QtQuick 2.4

Rectangle {
id: root
width: 400
height: 380
color: "yellow"

Rectangle {
id: panel
width: parent.width * 0.8
height: parent.height * 0.8
radius: 20
color: "orange"
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: panel
drag.minimumY: 0
drag.maximumY: 0
drag.minimumX: -panel.width
drag.maximumX: 0
onReleased: {
//if the panel is swiped more than 30% it will hide
//else it will go back to the original position
//this makes a pretty nice effect :)
if (panel.x < -panel.width * 0.3) {
//we need to make sure that a state change happens to
//fire the transition animation
root.state = "show"
root.state = "hide"
}
else {
root.state = "hide"
root.state = "show"
}
}
}
onXChanged: {
console.log(x)
}
}

Rectangle {
id: button
width: 45
height: width
radius: 5
color: "lightblue"
anchors.bottom: parent.bottom
anchors.left: parent.left
MouseArea {
anchors.fill: parent
onClicked: {
root.state = root.state === "show" ? "hide" : "show"
}
}
}

state: "show"
states: [
State {
name: "hide"
PropertyChanges { target: panel; x: -panel.width }
},
State {
name: "show"
PropertyChanges { target: panel; x: 0 }
}
]

transitions: Transition {
NumberAnimation {
target: panel
property: "x"
duration: 1000
easing.type: Easing.OutCubic
}
}
}

GrecKo
25th January 2017, 14:18
So, something like Drawer (http://doc.qt.io/qt-5/qml-qtquick-controls2-drawer.html) ?