I need to create a screen where the user will swipe right or left and top or down and on each of these I will present another screen. It would be like a cross where the center and each end is another screen of the system.
I tried using GestureArea, but its only event that worked was onTapAndHold, other events like onSwipe don't run. I later found out that Qt 4.8 has a bug in GestureArea and other events don't work. The problem is that the onTapAndHold event runs on click as well and I just want it to run with the swipe event.
Done!
How I did it:
import QtQuick 1.1
import Qt.labs.gestures 1.0
import "module"
Rectangle {
id: recMainWindow
width: 800
height: 480
color: "#00000000"
property string strActualScreen: "screenCenter"
function funSwipeScreens(swipeArea)
{
if ((!panBottomCenter.running) && (!panCenterBottom.running) &&
(!panCenterLeft.running) && (!panCenterRight.running) &&
(!panCenterTop.running) && (!panLeftCenter.running) &&
(!panRightCenter.running) && (!panTopCenter.running))
{
if (swipeArea == "top")
{
if (strActualScreen == "screenBottom")
{
strActualScreen = "screenCenter";
marLeft.enabled = true;
marRight.enabled = true;
marBottom.enabled = true;
panBottomCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenTop";
marTop.enabled = false;
marLeft.enabled = false;
marRight.enabled = false;
panCenterTop.start();
}
}
else if (swipeArea == "bottom")
{
if (strActualScreen == "screenTop")
{
strActualScreen = "screenCenter";
marTop.enabled = true;
marLeft.enabled = true;
marRight.enabled = true;
panTopCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenBottom";
marLeft.enabled = false;
marRight.enabled = false;
marBottom.enabled = false;
panCenterBottom.start();
}
}
else if (swipeArea == "left")
{
if (strActualScreen == "screenRight")
{
strActualScreen = "screenCenter";
marBottom.enabled = true;
marRight.enabled = true;
marTop.enabled = true;
panRightCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenLeft";
marLeft.enabled = false;
marBottom.enabled = false;
marTop.enabled = false;
panCenterLeft.start();
}
}
else if (swipeArea == "right")
{
if (strActualScreen == "screenLeft")
{
strActualScreen = "screenCenter";
marLeft.enabled = true;
marBottom.enabled = true;
marTop.enabled = true;
panLeftCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenRight";
marBottom.enabled = false;
marRight.enabled = false;
marTop.enabled = false;
panCenterRight.start();
}
}
}
}
Loader {
id: loaCenter
x: 0
y: 0
source: "qrc:/qml/centerScreen"
}
Loader {
id: loaTop
x: 0
y: -480
source: "qrc:/qml/topScreen"
}
Loader {
id: loaBottom
x: 0
y: 480
source: "qrc:/qml/bottomScreen"
}
Loader {
id: loaLeft
x: -800
y: 0
source: "qrc:/qml/leftScreen"
}
Loader {
id: loaRight
x: 800
y: 0
source: "qrc:/qml/rightScreen"
}
GestureArea {
id: marLeft
x: 0
y: 100
width: 100
height: 280
focus: true
onTapAndHold: {
funSwipeScreens("left");
}
}
GestureArea {
id: marRight
x: 700
y: 100
width: 100
height: 280
focus: true
onTapAndHold: {
funSwipeScreens("right");
}
}
GestureArea {
id: marTop
x: 100
y: 0
width: 600
height: 100
focus: true
onTapAndHold: {
funSwipeScreens("top");
}
}
GestureArea {
id: marBottom
x: 100
y: 380
width: 600
height: 100
focus: true
onTapAndHold: {
funSwipeScreens("bottom");
}
}
// TOP ANIMATIONS
ParallelAnimation {
id: panCenterTop
NumberAnimation { target: loaCenter; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaTop; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panTopCenter
NumberAnimation { target: loaTop; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// BOTTOM ANIMATIONS
ParallelAnimation {
id: panCenterBottom
NumberAnimation { target: loaCenter; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaBottom; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panBottomCenter
NumberAnimation { target: loaBottom; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// LEFT ANIMATIONS
ParallelAnimation {
id: panCenterLeft
NumberAnimation { target: loaCenter; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaLeft; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panLeftCenter
NumberAnimation { target: loaLeft; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// RIGHT ANIMATIONS
ParallelAnimation {
id: panCenterRight
NumberAnimation { target: loaCenter; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaRight; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panRightCenter
NumberAnimation { target: loaRight; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
}
EDIT:
Well ... after checking the wrong behaviors that the GestureArea I used above caused, because they respond to the click on the onTapAndHold event and I just wanted the answer to the swipe event, I decided to remove them and make a swipe simulation using MouseArea. .
The swipe action has greatly improved and the click event issue presented by GestureArea has been resolved but has caused the MouseAreas overlay issue.
This did not exist when using GestureArea as it did not prevent a click on a MouseArea positioned below it and MouseAreas overlap prevents it.
Anyway, the solution for the GestureArea swipe event I describe below:
MouseArea {
anchors.fill: parent
preventStealing: true
property real reaSpeed: 0.0 // calculates drag speed for swipe to run
property int intStartY: 0 // starting point pressed by the user's finger
property bool booTracing: false //controls the analyzed drag length
onPressed: {
intStartY = mouse.y;
reaSpeed = 0;
booTracing = true;
}
onPositionChanged: {
if (!booTracing)
{
return;
}
reaSpeed = (intStartY - mouse.y) / 2.0;
if ((reaSpeed > 50) && (mouse.y < (parent.height * 0.2)))
{
booTracing = false;
if (booIsShowMenu)
{
sigStartHideMenu();
}
funSwipeScreens("bottom");
}
}
}
I am checking a way to handle MouseAreas overlay.