Reputation: 635
Can someone help me to understand behaviour of this code? I wrote simple example of side panel menu (just template now) and there is problem to use onMenuVisibleChanged slot (but all I need actually works, just want to understand why another way don't). Logically it should change x of panel rectangle to specified values, but it didn't. Please help me ot understand correct approach for this thing.
main.qml
import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
menuBar: MenuBar{
Menu{
title: "File"
MenuItem{
text: "Exit"
onTriggered: Qt.quit()
}
}
}
SidePane{
id: sidePane
menuWidth: 350
z: 2
}
}
SidePane.qml
import QtQuick 2.3
import QtQuick.Window 2.2
Item {
id: screenItem
anchors.fill: parent
function show() {
rect.x = 0
menuVisible = true
}
function hide() {
rect.x = -rect.width
menuVisible = false
}
property int animationDuration: 200
property bool menuVisible: false
property int dragThreshold: 120
property int menuWidth: 300
Rectangle {
id: rect
width: menuWidth
x: -rect.width
height: Screen.height
color: "lightsteelblue"
Drag.active: menuDragArea.drag.active
Behavior on x {
NumberAnimation {
duration: animationDuration
easing.type: Easing.InOutQuad
}
}
MouseArea {
property int dragX: 0
property int startX: 0
property int diffX: 0
id: menuDragArea
hoverEnabled: true
height: rect.height
width: rect.width + 40
anchors.left: rect.left
drag.target: rect
drag.axis: Drag.XAxis
drag.minimumX: -rect.width
drag.maximumX: 0
onPressed: startX = rect.x + rect.width
onReleased: {
dragX = rect.x + rect.width
diffX = Math.abs(startX - dragX)
if ((diffX > dragThreshold) && (startX == 0)){
rect.x = 0
menuVisible = true
} else if ((diffX < dragThreshold) && (startX == 0)){
rect.x = -rect.width
menuVisible = false
}
if ((diffX > dragThreshold) && (startX == rect.width)){
rect.x = -rect.width
menuVisible = false
} else if ((diffX < dragThreshold) && (startX == rect.width)){
rect.x = 0
menuVisible = true
}
}
}
}
Rectangle{
id: shadowRect
anchors.left: rect.right
anchors.right: screenItem.right
opacity: (rect.x + rect.width) / (rect.width * 2.2)
color: "black"
height: screenItem.height
MouseArea{
id: shadowArea
anchors.fill: shadowRect
visible: menuVisible ? true : false
hoverEnabled: true
onClicked: {
if (menuVisible == true){
rect.x = -rect.width
menuVisible = false
}
}
}
Rectangle{
id: shadowRect2
color: "black"
anchors.left: parent.left
width: 5
opacity: (rect.x + rect.width) / (rect.width * 2)
height: screenItem.height
}
Rectangle{
id: shadowRect3
color: "black"
anchors.left: parent.left
width: 3
opacity: (rect.x + rect.width) / (rect.width * 1.9)
height: screenItem.height
}
}
onMenuVisibleChanged: menuVisible ? rect.x = 0 : rect.x = -rect.width
}
Appreciate any help. Just a QML beginner. The most purpose is to use this panel in android application. Feel free to use this code if you want.
Upvotes: 3
Views: 1600
Reputation: 1070
The property drag
make the x value draggable
if you implement it by mouseX
onPressed/onReleased, rect.x
will be 0
or -rect.width
onMenuVisibleChanged
MouseArea {
property int dragX: 0
property int startX: 0
property int diffX: 0
id: menuDragArea
hoverEnabled: true
height: rect.height
width: rect.width + 40
anchors.left: rect.left
onPressed: {
startX = mouseX;
console.log(rect.x)
}
onReleased: {
diffX = Math.abs(startX - mouseX)
console.log("diff:"+diffX)
if ((diffX > dragThreshold) && (mouseX > startX) && (rect.x !=0 )){
rect.x = 0
menuVisible = true
} else if ((diffX > dragThreshold) && (mouseX < startX) && (rect.x == 0)){
rect.x = -rect.width
menuVisible = false
}
}
}
with visual drag ,sorry it's ugly:
MouseArea {
property int startX: 0
property int diffX: 0
property int startRectX: 0
property bool isPressed: false
id: menuDragArea
hoverEnabled: true
height: rect.height
width: rect.width + 40
anchors.left: rect.left
onPressed: {
startX = mouseX;
startRectX = rect.x
isPressed = true
console.log(rect.x)}
onMouseXChanged: {
if(isPressed)
rect.x = (mouseX>rect.width)? 0 : (mouseX-rect.width)
}
onReleased: {
isPressed = false
diffX = Math.abs(startX - mouseX)
console.log("diff:"+diffX)
if ((mouseX >= startX) && (startRectX == -rect.width )){
if(diffX > dragThreshold)
{
rect.x = 0
menuVisible = true
}
else
rect.x = startRectX
} else if ((mouseX <= startX) && (startRectX == 0)){
if(diffX > dragThreshold)
{
rect.x = -rect.width
menuVisible = false
}
else
rect.x = startRectX
}
else
rect.x = startRectX
}
}
Upvotes: 2