Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix mapcanvas UX issues #2864

Merged
merged 3 commits into from
Oct 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 64 additions & 32 deletions app/qml/map/MMMapCanvas.qml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ Item {
property alias mapSettings: mapRenderer.mapSettings
property alias isRendering: mapRenderer.isRendering

// Number of miliseconds to differentiate between normal click (select feature) and double-click (zoom)
property int doubleClickThresholdMilis: 350

// Requests map redraw
function refresh() {
mapRenderer.clearCache()
Expand Down Expand Up @@ -121,7 +118,7 @@ Item {
}

function vectorDistance( a, b ) {
return Math.sqrt( Math.pow( a.x - b.x, 2 ), Math.pow( a.y - b.y, 2 ) )
return Math.sqrt( Math.pow( b.x - a.x, 2 ) + Math.pow( b.y - a.y, 2 ) )
}
}
}
Expand Down Expand Up @@ -166,41 +163,58 @@ Item {
onPressed: function ( mouse ) {
initialPosition = Qt.point( mouse.x, mouse.y )
rendererPrivate.freeze( mouseArea.freezeId )

dragDifferentiatorTimer.start()
}

onReleased: function ( mouse ) {
let clickPosition = Qt.point( mouse.x, mouse.y )

if ( !clickDifferentiatorTimer.running ) {
// this is a simple click

clickDifferentiatorTimer.clickedPoint = Qt.point( mouse.x, mouse.y )
}
else {
if ( clickDifferentiatorTimer.running ) {
//
// n-th click in a row (second, third,..)
// this can be double click if it is in a reasonable
// distance from the previous click
//

let isDoubleClick = false
let previousTapPosition = clickDifferentiatorTimer.clickedPoint

// do not emit clicked signal for the second click
mouse.accepted = true
if ( previousTapPosition ) {
let tapDistance = rendererPrivate.vectorDistance( clickPosition, previousTapPosition )
isDoubleClick = tapDistance < mouseArea.drag.threshold
}

clickDifferentiatorTimer.invalidate = true
if ( isDoubleClick ) {
// do not emit clicked signal when zooming
clickDifferentiatorTimer.ignoreNextTrigger = true

mapRenderer.zoom( Qt.point( mouse.x, mouse.y ), 0.4 )
}
mapRenderer.zoom( Qt.point( mouse.x, mouse.y ), 0.4 )
}

if ( !isDragging ) {
clickDifferentiatorTimer.restart()
}
else if ( !isDragging )
{
// this is a simple click

clickDifferentiatorTimer.clickedPoint = clickPosition
clickDifferentiatorTimer.ignoreNextTrigger = false // just in case
clickDifferentiatorTimer.start()
}

previousPosition = null
initialPosition = null
isDragging = false

rendererPrivate.unfreeze( mouseArea.freezeId )

dragDifferentiatorTimer.stop()
}

onPressAndHold: function ( mouse ) {
mapRoot.longPressed( Qt.point( mouse.x, mouse.y ) )
clickDifferentiatorTimer.invalidate = true
clickDifferentiatorTimer.ignoreNextTrigger = true
}

onWheel: function ( wheel ) {
Expand Down Expand Up @@ -230,12 +244,27 @@ Item {

previousPosition = target

let dragDistance = rendererPrivate.vectorDistance( initialPosition, target )
if ( dragDistance > drag.threshold ) {
isDragging = true
if ( !isDragging ) {
// do not compute if we are already dragging

let dragDistance = rendererPrivate.vectorDistance( initialPosition, target )

if ( dragDistance > Application.styleHints.startDragDistance ) {
// Drag distance threshold is hit, this is dragging!
isDragging = true
}

if ( !dragDifferentiatorTimer.running ) {
// User is panning the map for too long (timer already elapsed), this is dragging now!
isDragging = true
}

if ( isDragging ) {
// do not emit click after drag

// do not emit click after drag
clickDifferentiatorTimer.reset()
clickDifferentiatorTimer.stop()
clickDifferentiatorTimer.ignoreNextTrigger = false
}
}
}

Expand All @@ -250,29 +279,32 @@ Item {
previousPosition = null
initialPosition = null
isDragging = false

rendererPrivate.unfreeze( mouseArea.freezeId )
dragDifferentiatorTimer.stop()
}

Timer {
id: clickDifferentiatorTimer

property point clickedPoint
property bool invalidate
property var clickedPoint
property bool ignoreNextTrigger

interval: mapRoot.doubleClickThresholdMilis
repeat: false
interval: Application.styleHints.mouseDoubleClickInterval

onTriggered: {
if ( !invalidate ) {
if ( !ignoreNextTrigger ) {
mapRoot.clicked( clickedPoint )
}
invalidate = false
ignoreNextTrigger = false
clickedPoint = null
}
}

function reset() {
clickDifferentiatorTimer.stop()
clickDifferentiatorTimer.invalidate = false
}
Timer {
id: dragDifferentiatorTimer

interval: Application.styleHints.startDragTime
}
}
}
Expand Down
Loading