Skip to content

Commit

Permalink
[Backport release-3_22] [QuickGui] Fix MapCanvas by adapting to cpp c…
Browse files Browse the repository at this point in the history
…hanges and remove utils (#46571)

remove redundant class qgsquickutils
bugfix qgsquick mapcanvas

Co-authored-by: tomasMizera <tomas.mizera@lutraconsulting.co.uk>
  • Loading branch information
qgis-bot and tomasMizera committed Dec 21, 2021
1 parent c88ea90 commit e46de3c
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 236 deletions.
2 changes: 0 additions & 2 deletions src/quickgui/CMakeLists.txt
Expand Up @@ -5,15 +5,13 @@ set(QGIS_QUICK_GUI_MOC_HDRS
qgsquickmapcanvasmap.h
qgsquickmapsettings.h
qgsquickmaptransform.h
qgsquickutils.h
)

set(QGIS_QUICK_GUI_SRC
qgsquickcoordinatetransformer.cpp
qgsquickmapcanvasmap.cpp
qgsquickmapsettings.cpp
qgsquickmaptransform.cpp
qgsquickutils.cpp
)

include_directories(
Expand Down
300 changes: 227 additions & 73 deletions src/quickgui/plugin/qgsquickmapcanvas.qml
Expand Up @@ -12,13 +12,15 @@
* (at your option) any later version. *
* *
***************************************************************************/
import QtQuick 2.3
import QtQuick.Controls 2.2
import QtQml 2.2

import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQml 2.14

import QgsQuick 0.1 as QgsQuick

Item {
id: mapArea
id: root

/**
* The mapSettings property contains configuration for rendering of the map.
Expand Down Expand Up @@ -47,12 +49,20 @@ Item {
*/
property alias incrementalRendering: mapCanvasWrapper.incrementalRendering

/**
* What is the minimum distance (in pixels) in order to start dragging map
*/
property real minimumStartDragDistance: 5 * QgsQuick.Utils.dp
//! Consider mouse as a touchscreen device. If disabled, the mouse will act as a stylus pen.
property bool mouseAsTouchScreen: false

signal clicked(var mouse)
//! This signal is emitted independently of double tap / click
signal clicked(var point)

//! This signal is only emitted if there is no double tap/click coming after a short delay
// signal confirmedClicked(var point) // TODO: ideally get rid of this one

//! Signal emitted when user holds pointer on map
signal longPressed(var point)

//! Emitted when a release happens after a long press
signal longPressReleased()

/**
* Freezes the map canvas refreshes.
Expand All @@ -72,108 +82,252 @@ Item {

function unfreeze(id) {
delete mapCanvasWrapper.__freezecount[id]
mapCanvasWrapper.freeze = Object.keys(
mapCanvasWrapper.__freezecount).length !== 0
mapCanvasWrapper.freeze = Object.keys(mapCanvasWrapper.__freezecount).length !== 0
}

function zoomIn(point) {
mapCanvasWrapper.zoom(point, 0.67)
}

function zoomOut(point) {
mapCanvasWrapper.zoom(point, 1.5)
}

QgsQuick.MapCanvasMap {
id: mapCanvasWrapper

anchors.fill: parent

property var __freezecount: ({
width: root.width
height: root.height

})
property var __freezecount: ({})

freeze: false
}

PinchArea {
id: pinchArea
// Mouse, stylus and other pointer devices handler
TapHandler {
id: stylusClick

anchors.fill: parent
property bool longPressActive: false

onPinchStarted: {
freeze('pinch')
enabled: !mouseAsTouchScreen
acceptedDevices: PointerDevice.AllDevices & ~PointerDevice.TouchScreen

onSingleTapped: {
root.clicked(point.position)
}

onPinchUpdated: {
mapCanvasWrapper.zoom(pinch.center, pinch.previousScale / pinch.scale)
mapCanvasWrapper.pan(pinch.center, pinch.previousCenter)
onLongPressed: {
root.longPressed(point.position)
longPressActive = true
}

onPinchFinished: {
unfreeze('pinch')
mapCanvasWrapper.refresh()
onPressedChanged: {
if (longPressActive)
root.longPressReleased()
longPressActive = false
}
}

MouseArea {
id: mouseArea
// Map actions - select, long press, double tap - with fingers
// Extra gesture - tap and hold - will forward grabPermissions to grabHandler to zoom in/out
TapHandler {
id: tapHandler

property point __initialPosition
property point __lastPosition
property bool __dragging: false
property bool longPressActive: false
property bool doublePressed: false
property var timer: Timer {
property var tapPoint

anchors.fill: parent
interval: 350
repeat: false

onDoubleClicked: {
var center = Qt.point(mouse.x, mouse.y)
mapCanvasWrapper.zoom(center, 0.8)
onTriggered: {
root.clicked(tapPoint)
}
}

onClicked: {
if (mouse.button === Qt.RightButton) {
var center = Qt.point(mouse.x, mouse.y)
mapCanvasWrapper.zoom(center, 1.2)
} else {
var distance = Math.abs(mouse.x - __initialPosition.x) + Math.abs(
mouse.y - __initialPosition.y)
acceptedDevices: mouseAsTouchScreen ? PointerDevice.AllDevices : PointerDevice.TouchScreen

if (distance < minimumStartDragDistance)
mapArea.clicked(mouse)
}
onSingleTapped: {
if(point.modifiers === Qt.RightButton)
{
mapCanvasWrapper.zoom(point.position, 1.25)
}

onPressed: {
__lastPosition = Qt.point(mouse.x, mouse.y)
__initialPosition = __lastPosition
__dragging = false
freeze('pan')
else
{
timer.tapPoint = point.position
timer.restart()
}
}

onDoubleTapped: {
mapCanvasWrapper.zoom(point.position, 0.8)
}

onReleased: {
unfreeze('pan')
onLongPressed: {
root.longPressed(point.position)
longPressActive = true
}

onPressedChanged: {
if ( pressed && timer.running )
{
timer.stop()
doublePressed = true
dragHandler.grabPermissions = PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
}
else
{
doublePressed = false
dragHandler.grabPermissions = PointerHandler.ApprovesTakeOverByHandlersOfSameType | PointerHandler.ApprovesTakeOverByHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByItems
}

if (longPressActive)
root.longPressReleased()
longPressActive = false
}
}

// Map panning with fingers and an extra gesture to zoom in/out after double tap (tap and hold)
DragHandler {
id: dragHandler

target: null
grabPermissions: PointerHandler.ApprovesTakeOverByHandlersOfSameType | PointerHandler.ApprovesTakeOverByHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByItems

onPositionChanged: {
// are we far enough to start dragging map? (we want to avoid tiny map moves)
var distance = Math.abs(mouse.x - __initialPosition.x) + Math.abs(mouse.y - __initialPosition.y)
if (distance >= minimumStartDragDistance)
__dragging = true
property var oldPos
property real oldTranslationY

if (__dragging)
property bool isZooming: false
property point zoomCenter

onActiveChanged: {
if ( active )
{
if ( tapHandler.doublePressed )
{
oldTranslationY = 0;
zoomCenter = centroid.position;
isZooming = true;
freeze('zoom');
}
else
{
var currentPosition = Qt.point(mouse.x, mouse.y)
mapCanvasWrapper.pan(currentPosition, __lastPosition)
__lastPosition = currentPosition
freeze('pan');
}
}
else
{
unfreeze(isZooming ? 'zoom' : 'pan');
isZooming = false;
}
}

onCentroidChanged: {
var oldPos1 = oldPos;
oldPos = centroid.position;
if ( active )
{
if ( isZooming )
{
mapCanvasWrapper.zoom(zoomCenter, Math.pow(0.8, (translation.y - oldTranslationY)/60))
oldTranslationY = translation.y
}
else
{
mapCanvasWrapper.pan(centroid.position, oldPos1)
}
}
}
}

// Mouse or stylus map zooming with action buttons
DragHandler {
target: null
acceptedDevices: PointerDevice.Stylus | PointerDevice.Mouse
grabPermissions: PointerHandler.TakeOverForbidden
acceptedButtons: Qt.MiddleButton | Qt.RightButton

onCanceled: {
unfreezePanTimer.start()
property real oldTranslationY
property point zoomCenter

onActiveChanged: {
if (active)
{
oldTranslationY = 0
zoomCenter = centroid.position
}

onWheel: {
mapCanvasWrapper.zoom(Qt.point(wheel.x, wheel.y),
Math.pow(0.8, wheel.angleDelta.y / 60))
if ( active )
freeze('zoom')
else
unfreeze('zoom')
}

onTranslationChanged: {
if (active)
{
mapCanvasWrapper.zoom(zoomCenter, Math.pow(0.8, (oldTranslationY - translation.y)/60))
}

Timer {
id: unfreezePanTimer
interval: 500
running: false
repeat: false
onTriggered: unfreeze('pan')
oldTranslationY = translation.y
}
}

// Two fingers pinch zooming
PinchHandler {
id: pinch
target: null
acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad
grabPermissions: PointerHandler.TakeOverForbidden

property var oldPos
property real oldScale: 1.0

onActiveChanged: {
if ( active ) {
freeze('pinch')
oldScale = 1.0
oldPos = centroid.position
} else {
unfreeze('pinch')
}
}

onCentroidChanged: {
var oldPos1 = oldPos
oldPos = centroid.position
if ( active )
{
mapCanvasWrapper.pan(centroid.position, oldPos1)
}
}

onActiveScaleChanged: {
if ( oldScale !== 1 )
{
mapCanvasWrapper.zoom( pinch.centroid.position, oldScale / pinch.activeScale )
mapCanvasWrapper.pan( pinch.centroid.position, oldPos )

}
oldScale = pinch.activeScale
}
}

// Mouse wheel zooming
WheelHandler {
target: null
grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByItems

onWheel: {
if (event.angleDelta.y > 0)
{
zoomIn(point.position)
}
else
{
zoomOut(point.position)
}
}
}
Expand Down

0 comments on commit e46de3c

Please sign in to comment.