From d8c6997f847c39aedf7da57362b36e20b4e500a2 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Wed, 15 Jan 2025 19:40:01 +0330 Subject: [PATCH 1/4] **NEW** snapping to every angle and tolerance user interface. --- src/qml/CoordinateLocator.qml | 1 + src/qml/qgismobileapp.qml | 144 +++++++++++++++++++++++++++++----- 2 files changed, 126 insertions(+), 19 deletions(-) diff --git a/src/qml/CoordinateLocator.qml b/src/qml/CoordinateLocator.qml index 7c134ab66d..5a1c5174ea 100644 --- a/src/qml/CoordinateLocator.qml +++ b/src/qml/CoordinateLocator.qml @@ -33,6 +33,7 @@ Item { property bool snapToCommonAngles: false property bool snappingIsRelative: false property real snappingAngleDegrees: 45.0 + property real snappingTolerance: 0 /** * Overrides any possibility for the user to modify the coordinate. diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml index 555d978131..ff5606d8f2 100644 --- a/src/qml/qgismobileapp.qml +++ b/src/qml/qgismobileapp.qml @@ -1697,6 +1697,7 @@ ApplicationWindow { coordinateLocator.snapToCommonAngles = settings.valueBool("/QField/Digitizing/SnapToCommonAngleIsEnabled", false); coordinateLocator.snappingIsRelative = settings.valueBool("/QField/Digitizing/SnapToCommonAngleIsRelative", true); coordinateLocator.snappingAngleDegrees = settings.valueInt("/QField/Digitizing/SnapToCommonAngleDegrees", 45); + coordinateLocator.snappingTolerance = settings.valueInt("/QField/Digitizing/SnappingTolerance", 0); } Menu { @@ -1721,31 +1722,136 @@ ApplicationWindow { width: parent.width } - Repeater { - // list of common angles to snap to + Text { + text: qsTr("Snapping to every") + color: Theme.mainTextColor + font: Theme.defaultFont + leftPadding: 8 + } + + Item { + width: 1 + height: 8 + } + + ListView { + id: angles + height: 35 + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 4 + spacing: 3 + orientation: ListView.Horizontal model: [10, 15, 30, 45, 90] - delegate: MenuItem { - required property int modelData + delegate: Rectangle { + width: (angles.width - ((angles.count - 1) * angles.spacing)) / angles.count + height: width + radius: width / 2 + color: selected ? Theme.mainColor : Theme.darkTheme ? Theme.gray : Theme.lightGray + enabled: !selected + + property bool selected: modelData === coordinateLocator.snappingAngleDegrees + + Text { + text: qsTr("%1°").arg(modelData) + font: parent.selected ? Theme.strongTipFont : Theme.tipFont + anchors.centerIn: parent + color: Theme.mainTextColor + } - text: qsTr("Snap every %1°").arg(modelData) + Ripple { + clip: true + anchors.fill: parent + clipRadius: width / 2 + pressed: angleMouseArea.pressed + anchor: parent + active: angleMouseArea.pressed + color: "#22aaaaaa" + } - font: Theme.defaultFont - height: 48 - leftPadding: Theme.menuItemCheckLeftPadding + MouseArea { + id: angleMouseArea + anchors.fill: parent + onClicked: { + if (parent.selected) { + return; + } + coordinateLocator.snapToCommonAngles = true; + coordinateLocator.snappingAngleDegrees = modelData; + settings.setValue("/QField/Digitizing/SnapToCommonAngleDegrees", coordinateLocator.snappingAngleDegrees); + displayToast(qsTr("Snap to %1° angle turned on").arg(modelData)); + snapToCommonAngleMenu.close(); + } + } + } + } - checkable: true - checked: modelData === coordinateLocator.snappingAngleDegrees - enabled: modelData !== coordinateLocator.snappingAngleDegrees + Item { + width: 1 + height: 8 + } + + Text { + text: qsTr("Snapping tolerance") + color: Theme.mainTextColor + font: Theme.defaultFont + leftPadding: 8 + } + + Item { + width: 1 + height: 8 + } + + ListView { + id: tolorences + height: 35 + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 4 + spacing: 3 + orientation: ListView.Horizontal + model: [qsTr("Narrow"), qsTr("Normal"), qsTr("Large")] + + delegate: Rectangle { + width: (tolorences.width - (tolorences.spacing * (tolorences.count - 1))) / tolorences.count + height: 35 + radius: 4 + color: selected ? Theme.mainColor : Theme.darkTheme ? Theme.gray : Theme.lightGray + enabled: !selected + + property bool selected: index === coordinateLocator.snappingTolerance + + Text { + text: modelData + font: parent.selected ? Theme.strongTipFont : Theme.tipFont + anchors.centerIn: parent + color: Theme.mainTextColor + } + + Ripple { + clip: true + anchors.fill: parent + clipRadius: 4 + pressed: tolerancesMouseArea.pressed + anchor: parent + active: tolerancesMouseArea.pressed + color: "#22aaaaaa" + } - onTriggered: { - if (!checked) { - return; + MouseArea { + id: tolerancesMouseArea + anchors.fill: parent + onClicked: { + if (parent.selected) { + return; + } + coordinateLocator.snapToCommonAngles = true; + coordinateLocator.snappingTolerance = index; + settings.setValue("/QField/Digitizing/SnappingTolerance", coordinateLocator.snappingTolerance); + displayToast(qsTr("Snappin tolerance setted to %1").arg(modelData)); + snapToCommonAngleMenu.close(); } - coordinateLocator.snapToCommonAngles = true; - coordinateLocator.snappingAngleDegrees = modelData; - settings.setValue("/QField/Digitizing/SnapToCommonAngleDegrees", coordinateLocator.snappingAngleDegrees); - displayToast(qsTr("Snap to %1° angle turned on").arg(modelData)); - snapToCommonAngleMenu.close(); } } } From aa21c3314730c948a0064ca97cb2db6ac943c321 Mon Sep 17 00:00:00 2001 From: Mohsen Date: Mon, 20 Jan 2025 17:23:04 +0330 Subject: [PATCH 2/4] Add getToleranceMultiplier. --- src/qml/CoordinateLocator.qml | 28 +++++++++++++++++++++++++--- src/qml/qgismobileapp.qml | 5 +++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/qml/CoordinateLocator.qml b/src/qml/CoordinateLocator.qml index 5a1c5174ea..d12b357bac 100644 --- a/src/qml/CoordinateLocator.qml +++ b/src/qml/CoordinateLocator.qml @@ -407,9 +407,9 @@ Item { if (!rubberbandModel) { return; } - const MINIMAL_PIXEL_DISTANCE_TRESHOLD = 20; - const SOFT_CONSTRAINT_TOLERANCE_DEGREES = 20; - const SOFT_CONSTRAINT_TOLERANCE_PIXEL = 40; + const MINIMAL_PIXEL_DISTANCE_TRESHOLD = 20 * getToleranceMultiplier(); + const SOFT_CONSTRAINT_TOLERANCE_DEGREES = 20 * getToleranceMultiplier(); + const SOFT_CONSTRAINT_TOLERANCE_PIXEL = 40 * getToleranceMultiplier(); const rubberbandPointsCount = rubberbandModel.vertexCount; const targetPoint = mapCanvas.mapSettings.coordinateToScreen(forwardMode ? rubberbandModel.firstCoordinate : rubberbandModel.lastCoordinate); const minimumDigitizedPoints = forwardMode ? 3 : 2; @@ -446,6 +446,28 @@ Item { } } + /** Function to get the multiplier based on the selected tolerance + * + * - Narrow tolerance (index 0) divides by 2. + * - Normal tolerance (index 1) keeps unchanged. + * - Large tolerance (index 2) multiplies by 4. + */ + function getToleranceMultiplier() { + switch (snappingTolerance) { + case 0 // Narrow + : + return 0.5; + case 1 // Normal + : + return 1; + case 2 // Large + : + return 4; + default: + return 1; + } + } + /** * Computes a new point that forms a common angle * diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml index ff5606d8f2..812dce932a 100644 --- a/src/qml/qgismobileapp.qml +++ b/src/qml/qgismobileapp.qml @@ -1747,9 +1747,10 @@ ApplicationWindow { width: (angles.width - ((angles.count - 1) * angles.spacing)) / angles.count height: width radius: width / 2 - color: selected ? Theme.mainColor : Theme.darkTheme ? Theme.gray : Theme.lightGray + color: selected ? Theme.mainColor : "transparent" // Theme.darkTheme ? Theme.gray : Theme.lightGray enabled: !selected + // border.color: Theme.darkTheme ? Theme.gray : Theme.lightGray property bool selected: modelData === coordinateLocator.snappingAngleDegrees Text { @@ -1817,7 +1818,7 @@ ApplicationWindow { width: (tolorences.width - (tolorences.spacing * (tolorences.count - 1))) / tolorences.count height: 35 radius: 4 - color: selected ? Theme.mainColor : Theme.darkTheme ? Theme.gray : Theme.lightGray + color: selected ? Theme.mainColor : "transparent" enabled: !selected property bool selected: index === coordinateLocator.snappingTolerance From b8d7c3dd3403aed91c3d303ae67ec4947892997a Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 31 Jan 2025 13:43:32 +0330 Subject: [PATCH 3/4] Default snappingTolerance on Normal. --- src/qml/CoordinateLocator.qml | 46 +++++++++++++++++------------------ src/qml/qgismobileapp.qml | 8 +++--- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/qml/CoordinateLocator.qml b/src/qml/CoordinateLocator.qml index d12b357bac..cd97632029 100644 --- a/src/qml/CoordinateLocator.qml +++ b/src/qml/CoordinateLocator.qml @@ -33,7 +33,7 @@ Item { property bool snapToCommonAngles: false property bool snappingIsRelative: false property real snappingAngleDegrees: 45.0 - property real snappingTolerance: 0 + property real snappingTolerance: 1 /** * Overrides any possibility for the user to modify the coordinate. @@ -393,6 +393,28 @@ Item { flashAnimation.start(); } + /** Function to get the multiplier based on the selected tolerance + * + * - Narrow tolerance (index 0) divides by 2. + * - Normal tolerance (index 1) keeps unchanged. + * - Large tolerance (index 2) multiplies by 4. + */ + function getToleranceMultiplier() { + switch (snappingTolerance) { + case 0 // Narrow + : + return 0.5; + case 1 // Normal + : + return 1; + case 2 // Large + : + return 4; + default: + return 1; + } + } + /** * Computes the possible common angle * @@ -446,28 +468,6 @@ Item { } } - /** Function to get the multiplier based on the selected tolerance - * - * - Narrow tolerance (index 0) divides by 2. - * - Normal tolerance (index 1) keeps unchanged. - * - Large tolerance (index 2) multiplies by 4. - */ - function getToleranceMultiplier() { - switch (snappingTolerance) { - case 0 // Narrow - : - return 0.5; - case 1 // Normal - : - return 1; - case 2 // Large - : - return 4; - default: - return 1; - } - } - /** * Computes a new point that forms a common angle * diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml index 812dce932a..61a47ce754 100644 --- a/src/qml/qgismobileapp.qml +++ b/src/qml/qgismobileapp.qml @@ -1697,7 +1697,7 @@ ApplicationWindow { coordinateLocator.snapToCommonAngles = settings.valueBool("/QField/Digitizing/SnapToCommonAngleIsEnabled", false); coordinateLocator.snappingIsRelative = settings.valueBool("/QField/Digitizing/SnapToCommonAngleIsRelative", true); coordinateLocator.snappingAngleDegrees = settings.valueInt("/QField/Digitizing/SnapToCommonAngleDegrees", 45); - coordinateLocator.snappingTolerance = settings.valueInt("/QField/Digitizing/SnappingTolerance", 0); + coordinateLocator.snappingTolerance = settings.valueInt("/QField/Digitizing/SnappingTolerance", 1); } Menu { @@ -1747,10 +1747,9 @@ ApplicationWindow { width: (angles.width - ((angles.count - 1) * angles.spacing)) / angles.count height: width radius: width / 2 - color: selected ? Theme.mainColor : "transparent" // Theme.darkTheme ? Theme.gray : Theme.lightGray + color: selected ? Theme.mainColor : "transparent" enabled: !selected - // border.color: Theme.darkTheme ? Theme.gray : Theme.lightGray property bool selected: modelData === coordinateLocator.snappingAngleDegrees Text { @@ -1828,6 +1827,9 @@ ApplicationWindow { font: parent.selected ? Theme.strongTipFont : Theme.tipFont anchors.centerIn: parent color: Theme.mainTextColor + elide: Text.ElideRight + width: parent.width + horizontalAlignment: Text.AlignHCenter } Ripple { From d0f8a2a26304d51c3cd631a576faac12df0354ad Mon Sep 17 00:00:00 2001 From: Mohsen Date: Tue, 4 Feb 2025 16:22:39 +0330 Subject: [PATCH 4/4] Show snapping config until clicked outside, smooth movement of options. Add padding, fix typo, fix formatting, try to fix logic. --- src/qml/CoordinateLocator.qml | 14 +++----- src/qml/qgismobileapp.qml | 60 +++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/qml/CoordinateLocator.qml b/src/qml/CoordinateLocator.qml index cd97632029..698d49ef82 100644 --- a/src/qml/CoordinateLocator.qml +++ b/src/qml/CoordinateLocator.qml @@ -401,15 +401,11 @@ Item { */ function getToleranceMultiplier() { switch (snappingTolerance) { - case 0 // Narrow - : + case 0: return 0.5; - case 1 // Normal - : - return 1; - case 2 // Large - : + case 2: return 4; + case 1: default: return 1; } @@ -429,9 +425,9 @@ Item { if (!rubberbandModel) { return; } - const MINIMAL_PIXEL_DISTANCE_TRESHOLD = 20 * getToleranceMultiplier(); + const MINIMAL_PIXEL_DISTANCE_TRESHOLD = 20; const SOFT_CONSTRAINT_TOLERANCE_DEGREES = 20 * getToleranceMultiplier(); - const SOFT_CONSTRAINT_TOLERANCE_PIXEL = 40 * getToleranceMultiplier(); + const SOFT_CONSTRAINT_TOLERANCE_PIXEL = 40; const rubberbandPointsCount = rubberbandModel.vertexCount; const targetPoint = mapCanvas.mapSettings.coordinateToScreen(forwardMode ? rubberbandModel.firstCoordinate : rubberbandModel.lastCoordinate); const minimumDigitizedPoints = forwardMode ? 3 : 2; diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml index 61a47ce754..f21aca29ee 100644 --- a/src/qml/qgismobileapp.qml +++ b/src/qml/qgismobileapp.qml @@ -600,7 +600,7 @@ ApplicationWindow { id: mapCanvasMap property bool isEnabled: !dashBoard.opened && !aboutDialog.visible && !welcomeScreen.visible && !qfieldSettings.visible && !qfieldLocalDataPickerScreen.visible && !qfieldCloudScreen.visible && !qfieldCloudPopup.visible && !codeReader.visible && !sketcher.visible && !overlayFeatureFormDrawer.visible && !rotateFeaturesToolbar.rotateFeaturesRequested - interactive: isEnabled && !screenLocker.enabled + interactive: isEnabled && !screenLocker.enabled && !snapToCommonAngleMenu.visible isMapRotationEnabled: qfieldSettings.enableMapRotation incrementalRendering: true quality: qfieldSettings.quality @@ -1702,6 +1702,7 @@ ApplicationWindow { Menu { id: snapToCommonAngleMenu + width: Theme.menuItemIconlessLeftPadding + Math.max(angles.count * 35, tolorences.count * 55) + 24 MenuItem { text: qsTr("Relative angle") @@ -1726,7 +1727,7 @@ ApplicationWindow { text: qsTr("Snapping to every") color: Theme.mainTextColor font: Theme.defaultFont - leftPadding: 8 + leftPadding: Theme.menuItemIconlessLeftPadding } Item { @@ -1737,17 +1738,27 @@ ApplicationWindow { ListView { id: angles height: 35 - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 4 + anchors { + left: parent.left + leftMargin: Theme.menuItemIconlessLeftPadding + rightMargin: 4 + } spacing: 3 orientation: ListView.Horizontal model: [10, 15, 30, 45, 90] - delegate: Rectangle { - width: (angles.width - ((angles.count - 1) * angles.spacing)) / angles.count - height: width + currentIndex: Math.max(model.findIndex(q => q === coordinateLocator.snappingAngleDegrees), 0) + highlightFollowsCurrentItem: true + + highlight: Rectangle { + width: 35 + height: parent.height + color: Theme.mainColor radius: width / 2 - color: selected ? Theme.mainColor : "transparent" + } + + delegate: Item { + width: 35 + height: width enabled: !selected property bool selected: modelData === coordinateLocator.snappingAngleDegrees @@ -1780,7 +1791,6 @@ ApplicationWindow { coordinateLocator.snappingAngleDegrees = modelData; settings.setValue("/QField/Digitizing/SnapToCommonAngleDegrees", coordinateLocator.snappingAngleDegrees); displayToast(qsTr("Snap to %1° angle turned on").arg(modelData)); - snapToCommonAngleMenu.close(); } } } @@ -1795,7 +1805,7 @@ ApplicationWindow { text: qsTr("Snapping tolerance") color: Theme.mainTextColor font: Theme.defaultFont - leftPadding: 8 + leftPadding: Theme.menuItemIconlessLeftPadding } Item { @@ -1806,23 +1816,32 @@ ApplicationWindow { ListView { id: tolorences height: 35 - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 4 + anchors { + left: parent.left + leftMargin: Theme.menuItemIconlessLeftPadding + rightMargin: 4 + } spacing: 3 orientation: ListView.Horizontal model: [qsTr("Narrow"), qsTr("Normal"), qsTr("Large")] - - delegate: Rectangle { - width: (tolorences.width - (tolorences.spacing * (tolorences.count - 1))) / tolorences.count - height: 35 + highlight: Rectangle { + width: 35 + height: parent.height + color: Theme.mainColor radius: 4 - color: selected ? Theme.mainColor : "transparent" + } + currentIndex: coordinateLocator.snappingTolerance + highlightFollowsCurrentItem: true + delegate: Item { + id: tolorenceDelegate + width: (angles.contentWidth) / 3 + height: 35 enabled: !selected property bool selected: index === coordinateLocator.snappingTolerance Text { + id: tolorenceText text: modelData font: parent.selected ? Theme.strongTipFont : Theme.tipFont anchors.centerIn: parent @@ -1852,8 +1871,7 @@ ApplicationWindow { coordinateLocator.snapToCommonAngles = true; coordinateLocator.snappingTolerance = index; settings.setValue("/QField/Digitizing/SnappingTolerance", coordinateLocator.snappingTolerance); - displayToast(qsTr("Snappin tolerance setted to %1").arg(modelData)); - snapToCommonAngleMenu.close(); + displayToast(qsTr("Snapping tolerance setted to %1").arg(modelData)); } } }