diff --git a/app/qml/CMakeLists.txt b/app/qml/CMakeLists.txt index 3f90dd817..d432d20dd 100644 --- a/app/qml/CMakeLists.txt +++ b/app/qml/CMakeLists.txt @@ -73,7 +73,7 @@ set(MM_QML map/Crosshair.qml map/Highlight.qml map/LoadingIndicator.qml - map/MapCanvas.qml + map/MMMapCanvas.qml map/MapWrapper.qml map/PositionMarker.qml map/RecordingToolbar.qml diff --git a/app/qml/NumberSpin.qml b/app/qml/NumberSpin.qml index 3a0320e3a..5309f8cdd 100644 --- a/app/qml/NumberSpin.qml +++ b/app/qml/NumberSpin.qml @@ -73,9 +73,11 @@ Item { width: imageDecrease.width * 3 height: imageDecrease.height * 3 - TapHandler { - onTapped: function(eventPoint, button) { - if (minValue <= root.value - 1) root.value -=1 + MouseArea { + anchors.fill: parent + + onClicked: { + if (minValue <= root.value - 1) root.value -=1 } } } @@ -86,9 +88,11 @@ Item { width: imageIncrease.width * 3 height: imageIncrease.height * 3 - TapHandler { - onTapped: function(eventPoint, button) { - if (maxValue >= root.value + 1) root.value +=1 + MouseArea { + anchors.fill: parent + + onClicked: { + if (maxValue >= root.value + 1) root.value +=1 } } } diff --git a/app/qml/SettingsPanel.qml b/app/qml/SettingsPanel.qml index 35426d332..dc1c900af 100644 --- a/app/qml/SettingsPanel.qml +++ b/app/qml/SettingsPanel.qml @@ -114,8 +114,10 @@ Item { onCheckedChanged: __appSettings.autoCenterMapChecked = checked } - TapHandler { - onTapped: function(eventPoint, button) { + MouseArea { + anchors.fill: parent + + onClicked: { autoCenterMapSwitch.toggle() } } @@ -217,8 +219,10 @@ Item { onCheckedChanged: __appSettings.gpsAccuracyWarning = checked } - TapHandler { - onTapped: function(eventPoint, button) { + MouseArea { + anchors.fill: parent + + onClicked: { accuracyWarningSwitch.toggle() } } @@ -300,8 +304,10 @@ Item { onCheckedChanged: __appSettings.reuseLastEnteredValues = checked } - TapHandler { - onTapped: function(eventPoint, button) { + MouseArea { + anchors.fill: parent + + onClicked: { rememberValuesSwitch.toggle() } } @@ -320,8 +326,10 @@ Item { onCheckedChanged: __appSettings.autosyncAllowed = checked } - TapHandler { - onTapped: function(eventPoint, button) { + MouseArea { + anchors.fill: parent + + onClicked: { autosyncSwitch.toggle() } } diff --git a/app/qml/components/MainPanelButton.qml b/app/qml/components/MainPanelButton.qml index d60beeede..0dccc13bc 100644 --- a/app/qml/components/MainPanelButton.qml +++ b/app/qml/components/MainPanelButton.qml @@ -38,14 +38,16 @@ Rectangle { anchors.fill: parent enabled: root.enabled && handleClicks - TapHandler { - onTapped: function(eventPoint, button) { - root.activated() - } + MouseArea { + anchors.fill: parent - onLongPressed: { - root.activatedOnHold() - } + onClicked: { + root.activated() + } + + onPressAndHold: { + root.activatedOnHold() + } } } diff --git a/app/qml/components/MapFloatButton.qml b/app/qml/components/MapFloatButton.qml index 75ce4f8b4..2f8f14579 100644 --- a/app/qml/components/MapFloatButton.qml +++ b/app/qml/components/MapFloatButton.qml @@ -50,12 +50,14 @@ Item { Item { anchors.fill: parent - TapHandler { - onTapped: function(eventPoint, button) { + MouseArea { + anchors.fill: parent + + onClicked: { root.clicked() } - onLongPressed: function() { + onPressAndHold: { root.pressAndHold() } } diff --git a/app/qml/editor/AbstractEditor.qml b/app/qml/editor/AbstractEditor.qml index b97d24933..143557980 100644 --- a/app/qml/editor/AbstractEditor.qml +++ b/app/qml/editor/AbstractEditor.qml @@ -60,11 +60,11 @@ Item { x: leftActionContainer.actionAllowed ? parent.x - customStyle.fields.sideMargin : parent.x height: parent.height - TapHandler { - onPressedChanged: { - if ( !pressed ) { - root.leftActionClicked() - } + MouseArea { + anchors.fill: parent + + onReleased: { + root.leftActionClicked() } } } @@ -79,8 +79,10 @@ Item { height: parent.height width: parent.width - ( leftActionContainer.width + rightActionContainer.width ) - TapHandler { - onSingleTapped: { + MouseArea { + anchors.fill: parent + + onClicked: { root.contentClicked() } } @@ -101,11 +103,11 @@ Item { width: rightActionContainer.actionAllowed ? parent.width + customStyle.fields.sideMargin : parent.width height: parent.height - TapHandler { - onPressedChanged: { - if ( !pressed ) { - root.rightActionClicked() - } + MouseArea { + anchors.fill: parent + + onReleased: { + root.rightActionClicked() } } } diff --git a/app/qml/main.qml b/app/qml/main.qml index 190cff047..8499d6a49 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -147,21 +147,6 @@ ApplicationWindow { // if feature preview panel is opened return formsStackManager.takenVerticalSpace - mainPanel.height } - else if ( stateManager.state === "projects" || stateManager.state === "misc" ) - { - // - // Due to an upstream bug in Qt, see #2387 and #2425 for more info - // - return window.height - } - else if ( gpsDataPageLoader.active ) - { - // - // Block also GPS data page clicks propagation. - // Due to an upstream bug in Qt, see #2387 and #2425 for more info - // - return window.height - } return 0 } @@ -253,11 +238,6 @@ ApplicationWindow { width: window.width height: InputStyle.rowHeightHeader - // - // In order to workaround the QTBUG-108689 - we need to disable main panel's buttons when something else occupies the space - // - enabled: mainPanel.height > map.mapExtentOffset - y: window.height - height visible: map.state === "view" diff --git a/app/qml/map/MMMapCanvas.qml b/app/qml/map/MMMapCanvas.qml new file mode 100644 index 000000000..188d7c7f0 --- /dev/null +++ b/app/qml/map/MMMapCanvas.qml @@ -0,0 +1,279 @@ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +import QtQuick +import QtCore +import QtQuick.Controls + +import Input 0.1 as Input + +// +// MapCanvas QML object is a utility class for rendering map layers and handling user interaction +// + +Item { + id: mapRoot + + // Clicked signal is sent 350ms after click (to avoid mixing it with double click) + signal clicked( point p ) + + signal longPressed( point p ) + + // UserInteractedWithMap signal is sent each time user pans/zooms the map + signal userInteractedWithMap() + + 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() + mapRenderer.refresh() + } + + // Animates movement of map canvas from the current center to newPos. + function jumpTo( newPos ) + { + rendererPrivate.freeze('jumpTo') + + let newPosMapCRS = mapRenderer.mapSettings.screenToCoordinate( newPos ) + let oldPosMapCRS = mapRenderer.mapSettings.center + + // Disable animation until initial position is set + jumpAnimator.enabled = false + + jumpAnimator.px = oldPosMapCRS.x + jumpAnimator.py = oldPosMapCRS.y + + jumpAnimator.enabled = true + + jumpAnimator.px = newPosMapCRS.x + jumpAnimator.py = newPosMapCRS.y + + rendererPrivate.unfreeze('jumpTo') + } + + Item { + id: jumpAnimator + + property double px: 0 + property double py: 0 + + Behavior on py { + SmoothedAnimation { + duration: 200 + reversingMode: SmoothedAnimation.Immediate + } + enabled: jumpAnimator.enabled + } + + Behavior on px { + SmoothedAnimation { + duration: 200 + reversingMode: SmoothedAnimation.Immediate + } + enabled: jumpAnimator.enabled + } + + onPxChanged: { + if ( enabled ) { + mapRenderer.mapSettings.center = mapRenderer.mapSettings.toQgsPoint( Qt.point( px, py ) ) + } + } + + onPyChanged: { + if ( enabled ) { + mapRenderer.mapSettings.center = mapRenderer.mapSettings.toQgsPoint( Qt.point( px, py ) ) + } + } + } + + Input.MapCanvasMap { + id: mapRenderer + + width: mapRoot.width + height: mapRoot.height + + freeze: false + + QtObject { + id: rendererPrivate + + property var _freezeMap: ({}) + + function freeze( id ) { + _freezeMap[ id ] = true + mapRenderer.freeze = true + } + + function unfreeze( id ) { + delete _freezeMap[ id ] + mapRenderer.freeze = Object.keys( _freezeMap ).length !== 0 + } + + function vectorDistance( a, b ) { + return Math.sqrt( Math.pow( a.x - b.x, 2 ), Math.pow( a.y - b.y, 2 ) ) + } + } + } + + PinchArea { + id: pinchArea + + property string freezeId: 'pinch' + + anchors.fill: parent + + onPinchStarted: { + mapRoot.userInteractedWithMap() + rendererPrivate.freeze( freezeId ) + } + + onPinchFinished: { + rendererPrivate.unfreeze( freezeId ) + } + + onPinchUpdated: function ( pinch ) { + mapRenderer.pan( pinch.center, pinch.previousCenter ) + mapRenderer.zoom( pinch.center, pinch.previousScale / pinch.scale ) + } + + MouseArea { + id: mouseArea + + property var initialPosition + property var previousPosition + + property bool isDragging: false + + property string freezeId: 'drag' + + anchors.fill: parent + enabled: !pinchArea.pinch.active + + // ignore touchpad scroll, listen only to the mouse wheel + scrollGestureEnabled: false + + onPressed: function ( mouse ) { + initialPosition = Qt.point( mouse.x, mouse.y ) + rendererPrivate.freeze( mouseArea.freezeId ) + } + + 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 { + // n-th click in a row (second, third,..) + + // do not emit clicked signal for the second click + mouse.accepted = true + + clickDifferentiatorTimer.invalidate = true + + mapRenderer.zoom( Qt.point( mouse.x, mouse.y ), 0.4 ) + } + + if ( !isDragging ) { + clickDifferentiatorTimer.restart() + } + + previousPosition = null + initialPosition = null + isDragging = false + + rendererPrivate.unfreeze( mouseArea.freezeId ) + } + + onPressAndHold: function ( mouse ) { + mapRoot.longPressed( Qt.point( mouse.x, mouse.y ) ) + clickDifferentiatorTimer.invalidate = true + } + + onWheel: function ( wheel ) { + if ( wheel.angleDelta.y > 0 ) { + mapRenderer.zoom( Qt.point( wheel.x, wheel.y ), 0.67 ) + } + else { + mapRenderer.zoom( Qt.point( wheel.x, wheel.y ), 1.5 ) + } + } + + // drag map canvas + onPositionChanged: function ( mouse ) { + let target = Qt.point( mouse.x, mouse.y ) + + if ( !previousPosition ) { + previousPosition = target + initialPosition = target + return + } + + // we need to simulate natural scroll ~> revert movement on x and y + let reverted_x = previousPosition.x - ( mouse.x - previousPosition.x ) + let reverted_y = previousPosition.y - ( mouse.y - previousPosition.y ) + + mapRenderer.pan( previousPosition, Qt.point( reverted_x, reverted_y ) ) + + previousPosition = target + + let dragDistance = rendererPrivate.vectorDistance( initialPosition, target ) + if ( dragDistance > drag.threshold ) { + isDragging = true + + // do not emit click after drag + clickDifferentiatorTimer.reset() + } + } + + onIsDraggingChanged: { + if ( isDragging ) { + mapRoot.userInteractedWithMap() + } + } + + onCanceled: { + // pinch took over + previousPosition = null + initialPosition = null + isDragging = false + rendererPrivate.unfreeze( mouseArea.freezeId ) + } + + Timer { + id: clickDifferentiatorTimer + + property point clickedPoint + property bool invalidate + + interval: mapRoot.doubleClickThresholdMilis + repeat: false + + onTriggered: { + if ( !invalidate ) { + mapRoot.clicked( clickedPoint ) + } + invalidate = false + } + + function reset() { + clickDifferentiatorTimer.stop() + clickDifferentiatorTimer.invalidate = false + } + } + } + } +} diff --git a/app/qml/map/MapCanvas.qml b/app/qml/map/MapCanvas.qml deleted file mode 100644 index 005cfe04a..000000000 --- a/app/qml/map/MapCanvas.qml +++ /dev/null @@ -1,449 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -/* - * The source code forked from https://github.com/qgis/QGIS on 25th Nov 2022 - * File: qgsquickmapcanvas.qml by (C) 2014 by Matthias Kuhn - */ - -import QtQuick -import QtQuick.Controls -import QtQml - -import Input 0.1 as Input - -Item { - id: root - - /** - * The mapSettings property contains configuration for rendering of the map. - * - * It should be used as a primary source of map settings (and project) for - * all other components in the application. - * - * This is a readonly property. - * - * See also InputMapCanvasMap::mapSettings - */ - property alias mapSettings: mapCanvasWrapper.mapSettings - - /** - * The isRendering property is set to true while a rendering job is pending for this map canvas map. - * It can be used to show a notification icon about an ongoing rendering job. - * - * This is a readonly property. - * - * See also InputMapCanvasMap::mapSettings - */ - property alias isRendering: mapCanvasWrapper.isRendering - - /** - * When the incrementalRendering property is set to true, the automatic refresh of map canvas during rendering is allowed. - */ - property alias incrementalRendering: mapCanvasWrapper.incrementalRendering - - //! Consider mouse as a touchscreen device. If disabled, the mouse will act as a stylus pen. - property bool mouseAsTouchScreen: false - - property real mapExtentOffset: 0 - - //! This signal is emitted independently of double tap / click - signal clicked(var point) - - //! Signal emitted when user holds pointer on map - signal longPressed(var point) - - //! Emitted when a release happens after a long press - signal longPressReleased() - - //! Emitted when user does some interaction with map canvas (pan, zoom) - signal userInteractedWithMap() - - /** - * Freezes the map canvas refreshes. - * - * In case of repeated geometry changes (animated resizes, pinch, pan...) - * triggering refreshes all the time can cause severe performance impacts. - * - * If freeze is called, an internal counter is incremented and only when the - * counter is 0, refreshes will happen. - * It is therefore important to call freeze() and unfreeze() exactly the same - * number of times. - */ - function freeze(id) { - mapCanvasWrapper.__freezecount[id] = true - mapCanvasWrapper.freeze = true - - userInteractedWithMap() - } - - function unfreeze(id) { - delete mapCanvasWrapper.__freezecount[id] - mapCanvasWrapper.freeze = Object.keys(mapCanvasWrapper.__freezecount).length !== 0 - } - - function zoomIn(point) { - mapCanvasWrapper.zoom(point, 0.67) - } - - function zoomOut(point) { - mapCanvasWrapper.zoom(point, 1.5) - } - - function refresh() { - mapCanvasWrapper.clearCache() - mapCanvasWrapper.refresh() - } - - /** - * Animates movement of map canvas from the current center to newPos. - * - * newPos needs to be in device pixels. - */ - function moveTo( newPos ) - { - freeze('moveTo') - - let newPosMapCRS = mapCanvasWrapper.mapSettings.screenToCoordinate( newPos ) - let oldPosMapCRS = mapCanvasWrapper.mapSettings.center - - // Disable animation until initial position is set - jumpAnimator.enabled = false - - jumpAnimator.px = oldPosMapCRS.x - jumpAnimator.py = oldPosMapCRS.y - - jumpAnimator.enabled = true - - jumpAnimator.px = newPosMapCRS.x - jumpAnimator.py = newPosMapCRS.y - - unfreeze('moveTo') - } - - Input.MapCanvasMap { - id: mapCanvasWrapper - - width: root.width - height: root.height - - property var __freezecount: ({}) - - freeze: false - } - - Item { - id: jumpAnimator - - property double px: 0 - property double py: 0 - - Behavior on py { - SmoothedAnimation { - duration: 200 - reversingMode: SmoothedAnimation.Immediate - } - enabled: jumpAnimator.enabled - } - - Behavior on px { - SmoothedAnimation { - duration: 200 - reversingMode: SmoothedAnimation.Immediate - } - enabled: jumpAnimator.enabled - } - - onPxChanged: { - if ( enabled ) { - mapCanvasWrapper.mapSettings.center = mapCanvasWrapper.mapSettings.toQgsPoint( Qt.point( px, py ) ) - } - } - - onPyChanged: { - if ( enabled ) { - mapCanvasWrapper.mapSettings.center = mapCanvasWrapper.mapSettings.toQgsPoint( Qt.point( px, py ) ) - } - } - } - - // - // Qt6.0+ does not work well when PinchHandler is combined with TapHandler. - // Sometimes, after map is zoomed in/out a few times, TapHandler ends in an invalid state - - // it does not clear some internal pointer and results in ignoring all the following touch - // interactions. - // Thus, we reset the TapHandler each time pinch is completed to keep TapHandler working properly. - // - // See QTBUG-108689 - // - Timer { - id: repairHandlersTimer - - interval: 50 - - onTriggered: { - handlersLoader.active = false - handlersLoader.active = true - } - } - - Loader { - id: handlersLoader - - width: root.width - - // - // Subtract space that is occupied by feature form from TapHandler's active area height - // - height: root.height - root.mapExtentOffset - - sourceComponent: handlersComponent - } - - Component { - id: handlersComponent - - Item { - - // 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 bool longPressActive: false - property bool doublePressed: false - - property var timer: Timer { - property var tapPoint - - interval: 200 - repeat: false - - onTriggered: { - root.clicked(tapPoint) - } - } - - acceptedDevices: mouseAsTouchScreen ? PointerDevice.AllDevices : PointerDevice.TouchScreen - - onSingleTapped: { - if(point.modifiers === Qt.RightButton) - { - mapCanvasWrapper.zoom(point.position, 1.25) - } - else - { - timer.tapPoint = point.position - timer.restart() - } - } - - onDoubleTapped: { - mapCanvasWrapper.zoom(point.position, 0.8) - } - - 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 - } - } - - // Mouse, stylus and other pointer devices handler - TapHandler { - id: stylusClick - - property bool longPressActive: false - - enabled: !mouseAsTouchScreen - acceptedDevices: PointerDevice.AllDevices & ~PointerDevice.TouchScreen - - onSingleTapped: { - root.clicked(point.position) - } - - onLongPressed: { - root.longPressed(point.position) - longPressActive = true - } - - onPressedChanged: { - if (longPressActive) - root.longPressReleased() - longPressActive = false - } - } - - // Used to handle map panning (both touch and mouse) - DragHandler { - id: dragHandler - - target: null - grabPermissions: PointerHandler.ApprovesTakeOverByHandlersOfSameType | PointerHandler.ApprovesTakeOverByHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByItems - - property var oldPos - property real oldTranslationY - - property bool isZooming: false - property point zoomCenter - - onActiveChanged: { - if ( active ) - { - if ( tapHandler.doublePressed ) - { - oldTranslationY = 0; - zoomCenter = centroid.position; - isZooming = true; - freeze('zoom'); - } - else - { - 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 - - property real oldTranslationY - property point zoomCenter - - onActiveChanged: { - if (active) - { - oldTranslationY = 0 - zoomCenter = centroid.position - } - - if ( active ) - freeze('zoom') - else - unfreeze('zoom') - } - - onTranslationChanged: { - if (active) - { - mapCanvasWrapper.zoom(zoomCenter, Math.pow(0.8, (oldTranslationY - translation.y)/60)) - } - - 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') - - // See comment for repairHandlersTimer to understand why we need to call this - repairHandlersTimer.restart() - } - } - - 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: function( event ) { - if (event.angleDelta.y > 0) - { - zoomIn(point.position) - } - else - { - zoomOut(point.position) - } - - userInteractedWithMap() - } - } -} diff --git a/app/qml/map/MapWrapper.qml b/app/qml/map/MapWrapper.qml index 465b40da5..a66a01904 100644 --- a/app/qml/map/MapWrapper.qml +++ b/app/qml/map/MapWrapper.qml @@ -199,24 +199,11 @@ Item { anchors.fill: parent } - MapCanvas { + MMMapCanvas { id: mapCanvas anchors.fill: canvasRoot - /** - * We need to do a little hack here. - * Qt 6.4.1 falsely propagates events to all handlers event if the mouse event is accepted. - * Thus, mouse clicks were propagated to map canvas even if feature form was opened - - * resulting in undefined behaviour. - * - * As a workaround, we pass mapExtentOffset to map canvas and alter the TapHandler's height based on it. - * This way canvas still reacts to clicks when form is opened in preview. - * - * See https://bugreports.qt.io/browse/QTBUG-108821 - */ - mapExtentOffset: root.mapExtentOffset - mapSettings.project: __activeProject.qgsProject IdentifyKit { diff --git a/app/qml/map/RecordingTools.qml b/app/qml/map/RecordingTools.qml index b5fdf1e92..aef1bf3ee 100644 --- a/app/qml/map/RecordingTools.qml +++ b/app/qml/map/RecordingTools.qml @@ -62,7 +62,7 @@ Item { if ( !isNaN( newCenter.x ) && !isNaN( newCenter.y ) ) { - root.map.moveTo( /*crosshair.screenPoint,*/ root.map.mapSettings.coordinateToScreen( newCenter ) ) + root.map.jumpTo( /*crosshair.screenPoint,*/ root.map.mapSettings.coordinateToScreen( newCenter ) ) } } }