Re: [Interest] Mouse event propagation in Qt Quick

2016-10-16 Thread Mitch Curtis
> -Original Message-
> From: J-P Nurmi
> Sent: Sunday, 16 October 2016 4:06 PM
> To: Mitch Curtis ; Qt Project 
> Subject: Re: Mouse event propagation in Qt Quick
> 
> Hey Mitch,

Hey!

> 
> > - In example #2, why is Flickable happy to steal events that it doesn't do
> anything with? Shouldn't it see that it wasn't a "flick" and ignore the 
> event, so
> that it goes to the next highest item in the stacking order (the mouse area)?
> 
> An interactive Flickable always accepts mouse press events, because it needs
> to become the "mouse grabber item" ie. the item that receives the
> consequent mouse move events. This way Flickable can detect drags and
> flicks.

I was about to reply to myself after realising exactly this, hahaha. It would 
be too late to propagate press events by the time it receives the final 
release...

> > - Why aren't the scroll bars blocked by the mouse area in example #3?
> 
> The MouseArea is under the ScrollBar, because its parent is under the
> ScrollBar. The MouseArea is a child of Flickable::contentItem, whereas
> ScrollBars are children of the Flickable they are attached to. ScrollBar and
> Flickable::contentItem are siblings, ScrollBar being higher in the stacking
> order.

A. That makes perfect sense, thanks!

> > - Why does example #3 work if I remove "preventStealing: true"?
> 
> What do you mean? That's the exact use case "preventStealing" is meant for.
> :) When the MouseArea's preventStealing is true, Flickable honors it and
> won't be able to flick or drag since it's not allowed to steal events from the
> MouseArea. When preventStealing is false, Flickable's
> childMouseEventFilter() steals the press from the MouseArea when it
> detects a flick or drag.

Because of the other misunderstandings that I had, I thought that 
preventStealing was the only thing allowing the MouseArea to get events, which 
is why I thought it was strange that leaving it as false allowed the example to 
continue working. :D
 
> --
> J-P Nurmi
> 
[snip]
> ___
> Interest mailing list
> Interest@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Mouse event propagation in Qt Quick

2016-10-16 Thread J-P Nurmi
Hey Mitch,

> - In example #2, why is Flickable happy to steal events that it doesn't do 
> anything with? Shouldn't it see that it wasn't a "flick" and ignore the 
> event, so that it goes to the next highest item in the stacking order (the 
> mouse area)?

An interactive Flickable always accepts mouse press events, because it needs to 
become the "mouse grabber item" ie. the item that receives the consequent mouse 
move events. This way Flickable can detect drags and flicks.

> - Why aren't the scroll bars blocked by the mouse area in example #3?

The MouseArea is under the ScrollBar, because its parent is under the 
ScrollBar. The MouseArea is a child of Flickable::contentItem, whereas 
ScrollBars are children of the Flickable they are attached to. ScrollBar and 
Flickable::contentItem are siblings, ScrollBar being higher in the stacking 
order.

> - Why does example #3 work if I remove "preventStealing: true"?

What do you mean? That's the exact use case "preventStealing" is meant for. :) 
When the MouseArea's preventStealing is true, Flickable honors it and won't be 
able to flick or drag since it's not allowed to steal events from the 
MouseArea. When preventStealing is false, Flickable's childMouseEventFilter() 
steals the press from the MouseArea when it detects a flick or drag.

--
J-P Nurmi


From: Interest  on behalf of 
Mitch Curtis 
Sent: Sunday, October 16, 2016 3:42:35 PM
To: Qt Project
Subject: [Interest] Mouse event propagation in Qt Quick

Hi.

In the following example (#1), I want both the MouseArea to be clickable and 
the scroll bars to be draggable:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
id: root

Flickable {
anchors.fill: parent
contentWidth: rect.width
contentHeight: rect.height
boundsBehavior: Flickable.StopAtBounds

ScrollBar.vertical: ScrollBar {
id: verticalScrollBar
Binding {
target: verticalScrollBar
property: "active"
value: verticalScrollBar.hovered
}
}

Rectangle {
id: rect
width: 640
height: 1000
gradient: Gradient {
GradientStop {
position: 0
color: "#e03389"
}
GradientStop {
position: 1
color: "#20ae24"
}
}
}
}

MouseArea {
id: mouseArea
anchors.fill: parent
}

Rectangle {
id: mouseAreaRect
anchors.fill: parent
color: "transparent"
border.color: mouseArea.pressed ? "red" : "darkorange"
}
}

The mouse area can be clicked, but the scroll bars can't be dragged.

If I move the mouse area below the flickable, the opposite problem occurs: the 
scroll bars can be dragged, but the mouse area can't be clicked. Example #2:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
id: root

MouseArea {
id: mouseArea
anchors.fill: parent
}

Flickable {
anchors.fill: parent
contentWidth: rect.width
contentHeight: rect.height
boundsBehavior: Flickable.StopAtBounds

ScrollBar.vertical: ScrollBar {
id: verticalScrollBar
Binding {
target: verticalScrollBar
property: "active"
value: verticalScrollBar.hovered
}
}

Rectangle {
id: rect
width: 640
height: 1000
gradient: Gradient {
GradientStop {
position: 0
color: "#e03389"
}
GradientStop {
position: 1
color: "#20ae24"
}
}
}
}

Rectangle {
id: mouseAreaRect
anchors.fill: parent
color: "transparent"
border.color: mouseArea.pressed ? "red" : "darkorange"
}
}

I remembered that MouseArea has a preventSteal

[Interest] Mouse event propagation in Qt Quick

2016-10-16 Thread Mitch Curtis
Hi.

In the following example (#1), I want both the MouseArea to be clickable and 
the scroll bars to be draggable:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
id: root

Flickable {
anchors.fill: parent
contentWidth: rect.width
contentHeight: rect.height
boundsBehavior: Flickable.StopAtBounds

ScrollBar.vertical: ScrollBar {
id: verticalScrollBar
Binding {
target: verticalScrollBar
property: "active"
value: verticalScrollBar.hovered
}
}

Rectangle {
id: rect
width: 640
height: 1000
gradient: Gradient {
GradientStop {
position: 0
color: "#e03389"
}
GradientStop {
position: 1
color: "#20ae24"
}
}
}
}

MouseArea {
id: mouseArea
anchors.fill: parent
}

Rectangle {
id: mouseAreaRect
anchors.fill: parent
color: "transparent"
border.color: mouseArea.pressed ? "red" : "darkorange"
}
}

The mouse area can be clicked, but the scroll bars can't be dragged.

If I move the mouse area below the flickable, the opposite problem occurs: the 
scroll bars can be dragged, but the mouse area can't be clicked. Example #2:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
id: root

MouseArea {
id: mouseArea
anchors.fill: parent
}

Flickable {
anchors.fill: parent
contentWidth: rect.width
contentHeight: rect.height
boundsBehavior: Flickable.StopAtBounds

ScrollBar.vertical: ScrollBar {
id: verticalScrollBar
Binding {
target: verticalScrollBar
property: "active"
value: verticalScrollBar.hovered
}
}

Rectangle {
id: rect
width: 640
height: 1000
gradient: Gradient {
GradientStop {
position: 0
color: "#e03389"
}
GradientStop {
position: 1
color: "#20ae24"
}
}
}
}
   
Rectangle {
id: mouseAreaRect
anchors.fill: parent
color: "transparent"
border.color: mouseArea.pressed ? "red" : "darkorange"
}
}

I remembered that MouseArea has a preventStealing property. Its documentation 
says:

This property holds whether the mouse events may be stolen from this 
MouseArea.

If a MouseArea is placed within an item that filters child mouse events, 
such as Flickable, the mouse events may be stolen from the MouseArea if a 
gesture is recognized by the parent item, e.g. a flick gesture. If 
preventStealing is set to true, no item will steal the mouse events.

I only want the gradient rectangle to be the child of the flickable, but I was 
curious if it would work, so I moved the mouse area in there anyway. Example #3:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
id: root

Flickable {
anchors.fill: parent
contentWidth: rect.width
contentHeight: rect.height
boundsBehavior: Flickable.StopAtBounds

ScrollBar.vertical: ScrollBar {
id: verticalScrollBar
Binding {
target: verticalScrollBar
property: "active"
value: verticalScrollBar.hovered
}
}

Rectangle {
id: rect
width: 640
height: 1000
gradient: Gradient {
GradientStop {
position: 0
color: "#e03389"
}
GradientStop {
position: 1
color: "#20ae24"
}
}
}