From e770809db4b6c92ee4be22b5ea021ccc505cec8f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 7 Dec 2022 16:28:01 +0100 Subject: Update location examples to work with MapView/Handlers MapView replaces Map in the examples to reintroduce event handling. Some of the functionality is still in mapview.map and the code has to be adjusted respectivly. The following examples are affected: mapviewer, places, places_map. The mapviewer example has a new menu to draw mapitems. The places example draws places icons instead of a fixed marker. Fixes: QTBUG-111005 Change-Id: I15ca2b3d3ecb7c35684b9fd4c2b7a86249add11c Reviewed-by: Volker Hilsheimer --- examples/location/mapviewer/CMakeLists.txt | 1 - .../location/mapviewer/forms/RouteListDelegate.qml | 2 +- examples/location/mapviewer/main.cpp | 1 + examples/location/mapviewer/map/CircleItem.qml | 25 +- examples/location/mapviewer/map/ImageItem.qml | 20 +- examples/location/mapviewer/map/MapComponent.qml | 339 ++++++++------------- examples/location/mapviewer/map/Marker.qml | 65 ++-- examples/location/mapviewer/map/MiniMap.qml | 28 +- examples/location/mapviewer/map/PolygonItem.qml | 32 +- examples/location/mapviewer/map/PolylineItem.qml | 26 +- examples/location/mapviewer/map/RectangleItem.qml | 23 +- examples/location/mapviewer/mapviewer.qml | 177 +++++------ examples/location/mapviewer/menus/MapPopupMenu.qml | 25 ++ .../location/mapviewer/menus/MarkerPopupMenu.qml | 28 -- examples/location/places/items/MapComponent.qml | 32 +- examples/location/places/items/SearchBar.qml | 9 +- examples/location/places/places.qml | 101 +++--- examples/location/places/resources/left.png | Bin 141 -> 6466 bytes examples/location/places/resources/right.png | Bin 147 -> 6417 bytes examples/location/places/resources/search.png | Bin 259 -> 7154 bytes .../location/places/views/CategoryDelegate.qml | 28 +- examples/location/places/views/CategoryView.qml | 2 +- examples/location/places_map/places_map.qml | 11 +- 23 files changed, 470 insertions(+), 505 deletions(-) diff --git a/examples/location/mapviewer/CMakeLists.txt b/examples/location/mapviewer/CMakeLists.txt index fa15dca4..5db82ee4 100644 --- a/examples/location/mapviewer/CMakeLists.txt +++ b/examples/location/mapviewer/CMakeLists.txt @@ -36,7 +36,6 @@ target_link_libraries(qml_location_mapviewer PUBLIC Qt::Quick ) - # Resources: set(mapviewer_resource_files "forms/Geocode.qml" diff --git a/examples/location/mapviewer/forms/RouteListDelegate.qml b/examples/location/mapviewer/forms/RouteListDelegate.qml index 5ba6e40c..30e43503 100644 --- a/examples/location/mapviewer/forms/RouteListDelegate.qml +++ b/examples/location/mapviewer/forms/RouteListDelegate.qml @@ -12,7 +12,7 @@ Item { property alias routeDistance: distanceLabel property alias routeIndex: indexLabel - width: parent.width + width: appWindow.width height: indexLabel.height * 2 RowLayout { diff --git a/examples/location/mapviewer/main.cpp b/examples/location/mapviewer/main.cpp index 203346f7..cc3a465f 100644 --- a/examples/location/mapviewer/main.cpp +++ b/examples/location/mapviewer/main.cpp @@ -102,5 +102,6 @@ int main(int argc, char *argv[]) QMetaObject::invokeMethod(item, "initializeProviders", Q_ARG(QVariant, QVariant::fromValue(parameters))); + return application.exec(); } diff --git a/examples/location/mapviewer/map/CircleItem.qml b/examples/location/mapviewer/map/CircleItem.qml index e647d248..a5cae752 100644 --- a/examples/location/mapviewer/map/CircleItem.qml +++ b/examples/location/mapviewer/map/CircleItem.qml @@ -3,19 +3,26 @@ import QtQuick import QtLocation -//TODO: remove/refactor me when items are integrated - MapCircle { - color: "#46a2da" - border.color: "#190a33" + color: "#da5546" + border.color: "#330a0a" border.width: 2 smooth: true - opacity: 0.25 + opacity: 0.75 + + function setGeometry(anchorCoordinate) { + center = anchorCoordinate + } + + function addGeometry(newCoordinate, changeLast){ + radius = center.distanceTo(newCoordinate) + return true + } - function setGeometry(markers, index){ - center.latitude = markers[index].coordinate.latitude - center.longitude = markers[index].coordinate.longitude - radius= center.distanceTo(markers[index + 1].coordinate) + function finishAddGeometry(){ + color = "#46a2da" + border.color = "#190a33" + opacity = 0.25 } } diff --git a/examples/location/mapviewer/map/ImageItem.qml b/examples/location/mapviewer/map/ImageItem.qml index ca8de2b5..433b12ef 100644 --- a/examples/location/mapviewer/map/ImageItem.qml +++ b/examples/location/mapviewer/map/ImageItem.qml @@ -6,14 +6,22 @@ import QtLocation MapQuickItem { //to be used inside MapComponent only id: imageItem - MouseArea { - anchors.fill: parent - drag.target: parent + anchorPoint.x: testImage.width/2 + anchorPoint.y: testImage.height/2 + + function setGeometry(anchorCoordinate) { + coordinate = anchorCoordinate + } + + function addGeometry(newCoordinate, changeLast){ + var p1 = view.map.fromCoordinate(coordinate, false); + var p2 = view.map.fromCoordinate(newCoordinate, false); + var size = Math.max(Math.abs((p1.x-p2.x)), Math.abs((p1.y-p2.y))); + testImage.scale = Math.max(0.1, size/Math.max(testImage.height, testImage.width))*2 + return true } - function setGeometry(markers, index) { - coordinate.latitude = markers[index].coordinate.latitude - coordinate.longitude = markers[index].coordinate.longitude + function finishAddGeometry(){ } sourceItem: Image { diff --git a/examples/location/mapviewer/map/MapComponent.qml b/examples/location/mapviewer/map/MapComponent.qml index 036738d1..149c0e47 100644 --- a/examples/location/mapviewer/map/MapComponent.qml +++ b/examples/location/mapviewer/map/MapComponent.qml @@ -7,24 +7,20 @@ import QtPositioning import "../helper.js" as Helper //! [top] -Map { - id: map +MapView { + id: view //! [top] property variant markers property variant mapItems property int markerCounter: 0 // counter for total amount of markers. Resets to 0 when number of markers = 0 property int currentMarker - property int lastX : -1 - property int lastY : -1 - property int pressX : -1 - property int pressY : -1 - property int jitterThreshold : 30 property bool followme: false property variant scaleLengths: [5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000] property alias routeQuery: routeQuery property alias routeModel: routeModel property alias geocodeModel: geocodeModel property alias slidersExpanded: sliders.expanded + property variant unfinishedItem: 'undefined' signal showGeocodeInfo() signal geocodeFinished() @@ -67,8 +63,8 @@ Map { { var coord1, coord2, dist, text, f f = 0 - coord1 = map.toCoordinate(Qt.point(0,scale.y)) - coord2 = map.toCoordinate(Qt.point(0+scaleImage.sourceSize.width,scale.y)) + coord1 = view.map.toCoordinate(Qt.point(0,scale.y)) + coord2 = view.map.toCoordinate(Qt.point(0+scaleImage.sourceSize.width,scale.y)) dist = Math.round(coord1.distanceTo(coord2)) if (dist === 0) { @@ -94,59 +90,43 @@ Map { function deleteMarkers() { - var count = map.markers.length - for (var i = 0; i=0; i--){ + view.map.removeMapItem(view.markers[i]) } - map.markers = [] - markerCounter = 0 + view.markers = [] } function deleteMapItems() { - var count = map.mapItems.length - for (var i = 0; i=0; i--){ + view.map.removeMapItem(view.mapItems[i]) } - map.mapItems = [] + view.mapItems = [] } function addMarker() { - var count = map.markers.length + var count = view.markers.length markerCounter++ var marker = Qt.createQmlObject ('Marker {}', map) - map.addMapItem(marker) - marker.z = map.z+1 - marker.coordinate = mouseArea.lastCoordinate - - //update list of markers - var myArray = new Array() - for (var i = 0; i { if (event.key === Qt.Key_Plus) { - map.zoomLevel++; + view.map.zoomLevel++; } else if (event.key === Qt.Key_Minus) { - map.zoomLevel--; + view.map.zoomLevel--; } else if (event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Up || event.key === Qt.Key_Down) { var dx = 0; @@ -276,15 +239,18 @@ Map { switch (event.key) { - case Qt.Key_Left: dx = map.width / 4; break; - case Qt.Key_Right: dx = -map.width / 4; break; - case Qt.Key_Up: dy = map.height / 4; break; - case Qt.Key_Down: dy = -map.height / 4; break; + case Qt.Key_Left: dx = view.map.width / 4; break; + case Qt.Key_Right: dx = -view.map.width / 4; break; + case Qt.Key_Up: dy = view.map.height / 4; break; + case Qt.Key_Down: dy = -view.map.height / 4; break; } - var mapCenterPoint = Qt.point(map.width / 2.0 - dx, map.height / 2.0 - dy); - map.center = map.toCoordinate(mapCenterPoint); + var mapCenterPoint = Qt.point(view.map.width / 2.0 - dx, view.map.height / 2.0 - dy); + view.map.center = view.map.toCoordinate(mapCenterPoint); + } else if (event.key === Qt.Key_Escape) { + mapview.unfinishedItem.finishAddGeometry() + mapview.unfinishedItem = 'undefined' } } @@ -301,12 +267,13 @@ Map { active: followme onPositionChanged: { - map.center = positionSource.position.coordinate + view.map.center = positionSource.position.coordinate } } MapQuickItem { id: poiTheQtComapny + parent: view.map sourceItem: Rectangle { width: 14; height: 14; color: "#e41e25"; border.width: 2; border.color: "white"; smooth: true; radius: 7 } coordinate { latitude: 59.9485 @@ -317,6 +284,7 @@ Map { } MapQuickItem { + parent: view.map sourceItem: Text{ text: "The Qt Company" color:"#242424" @@ -330,15 +298,15 @@ Map { MapSliders { id: sliders - z: map.z + 3 + z: view.map.z + 3 mapSource: map edge: Qt.LeftEdge } Item { id: scale - z: map.z + 3 - visible: scaleText.text != "0 m" + z: view.map.z + 3 + visible: scaleText.text !== "0 m" anchors.bottom: parent.bottom; anchors.right: parent.right anchors.margins: 20 @@ -370,14 +338,14 @@ Map { text: "0 m" } Component.onCompleted: { - map.calculateScale(); + view.calculateScale(); } } //! [routemodel0] RouteModel { id: routeModel - plugin : map.plugin + plugin : view.map.plugin query: RouteQuery { id: routeQuery } @@ -386,14 +354,14 @@ Map { switch (count) { case 0: // technically not an error - map.routeError() + view.routeError() break case 1: - map.showRouteList() + view.showRouteList() break } } else if (status == RouteModel.Error) { - map.routeError() + view.routeError() } } } @@ -411,53 +379,30 @@ Map { smooth: true opacity: 0.8 //! [routedelegate0] - MouseArea { - id: routeMouseArea - anchors.fill: parent - hoverEnabled: false - property variant lastCoordinate - - onPressed : (mouse) => { - map.lastX = mouse.x + parent.x - map.lastY = mouse.y + parent.y - map.pressX = mouse.x + parent.x - map.pressY = mouse.y + parent.y - lastCoordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y)) - } - - onPositionChanged: (mouse) => { - if (mouse.button == Qt.LeftButton) { - map.lastX = mouse.x + parent.x - map.lastY = mouse.y + parent.y - } - } - - onPressAndHold:{ - if (Math.abs(map.pressX - parent.x- mouse.x ) < map.jitterThreshold - && Math.abs(map.pressY - parent.y - mouse.y ) < map.jitterThreshold) { - showRouteMenu(lastCoordinate); - } + TapHandler { + acceptedButtons: Qt.LeftButton | Qt.RightButton + onLongPressed: showRouteMenu(view.map.toCoordinate(tapHandler.point.position)) + onSingleTapped: (eventPoint, button) => { + if (button === Qt.RightButton) + showRouteMenu(view.map.toCoordinate(tapHandler.point.position)) } - } - //! [routedelegate1] } } - //! [routedelegate1] //! [geocodemodel0] GeocodeModel { id: geocodeModel - plugin: map.plugin + plugin: view.map.plugin onStatusChanged: { if ((status == GeocodeModel.Ready) || (status == GeocodeModel.Error)) - map.geocodeFinished() + view.geocodeFinished() } onLocationsChanged: { - if (count == 1) { - map.center.latitude = get(0).coordinate.latitude - map.center.longitude = get(0).coordinate.longitude + if (count === 1) { + view.map.center.latitude = get(0).coordinate.latitude + view.map.center.longitude = get(0).coordinate.longitude } } } @@ -469,6 +414,7 @@ Map { MapCircle { id: point + parent: view.map radius: 1000 color: "#46a2da" border.color: "#190a33" @@ -477,39 +423,17 @@ Map { opacity: 0.25 center: locationData.coordinate //! [pointdel0] - MouseArea { - anchors.fill:parent - id: circleMouseArea - hoverEnabled: false - property variant lastCoordinate - - onPressed : (mouse) => { - map.lastX = mouse.x + parent.x - map.lastY = mouse.y + parent.y - map.pressX = mouse.x + parent.x - map.pressY = mouse.y + parent.y - lastCoordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y)) - } - - onPositionChanged: (mouse) => { - if (Math.abs(map.pressX - parent.x- mouse.x ) > map.jitterThreshold || - Math.abs(map.pressY - parent.y -mouse.y ) > map.jitterThreshold) { - if (pressed) parent.radius = parent.center.distanceTo( - map.toCoordinate(Qt.point(mouse.x, mouse.y))) - } - if (mouse.button == Qt.LeftButton) { - map.lastX = mouse.x + parent.x - map.lastY = mouse.y + parent.y + /* TapHandler { + point.onPositionChanged: { + if (Math.abs(view.map.pressX - parent.x - point.position.x) > view.map.jitterThreshold || + Math.abs(view.map.pressY - parent.y - point.position.y) > view.map.jitterThreshold) { + if (pressed) + parent.radius = parent.center.distanceTo(view.map.toCoordinate(point.position)) } } - onPressAndHold: (mouse) => { - if (Math.abs(map.pressX - parent.x- mouse.x ) < map.jitterThreshold - && Math.abs(map.pressY - parent.y - mouse.y ) < map.jitterThreshold) { - showPointMenu(lastCoordinate); - } - } - } + onLongPressed: showPointMenu(view.map.toCoordinate(point.position)) + }*/ //! [pointdel1] } } @@ -517,16 +441,16 @@ Map { //! [routeview0] MapItemView { + parent: view.map model: routeModel delegate: routeDelegate //! [routeview0] autoFitViewport: true - //! [routeview1] } - //! [routeview1] //! [geocodeview] MapItemView { + parent: view.map model: geocodeModel delegate: pointDelegate } @@ -537,56 +461,63 @@ Map { interval: 100 running: false repeat: false - onTriggered: { - map.calculateScale() + onTriggered: view.calculateScale() + } + + HoverHandler { + id: hoverHandler + property variant currentCoordinate + grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType + + onPointChanged: { + currentCoordinate = view.map.toCoordinate(hoverHandler.point.position) + if (mapview.unfinishedItem !== 'undefined') + mapview.unfinishedItem.addGeometry(view.map.toCoordinate(hoverHandler.point.position), true) } + } - MouseArea { - id: mouseArea + TapHandler { + id: tapHandler property variant lastCoordinate - anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton - onPressed: (mouse) => { - map.lastX = mouse.x - map.lastY = mouse.y - map.pressX = mouse.x - map.pressY = mouse.y - lastCoordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y)) - } - - onPositionChanged: (mouse) => { - if (mouse.button == Qt.LeftButton) { - map.lastX = mouse.x - map.lastY = mouse.y + onPressedChanged: (eventPoint, button) => { + if (pressed) { + lastCoordinate = view.map.toCoordinate(tapHandler.point.position) } } - onDoubleClicked: (mouse) => { - var mouseGeoPos = map.toCoordinate(Qt.point(mouse.x, mouse.y)); - var preZoomPoint = map.fromCoordinate(mouseGeoPos, false); - if (mouse.button === Qt.LeftButton) { - map.zoomLevel = Math.floor(map.zoomLevel + 1) - } else if (mouse.button === Qt.RightButton) { - map.zoomLevel = Math.floor(map.zoomLevel - 1) - } - var postZoomPoint = map.fromCoordinate(mouseGeoPos, false); - var dx = postZoomPoint.x - preZoomPoint.x; - var dy = postZoomPoint.y - preZoomPoint.y; - - var mapCenterPoint = Qt.point(map.width / 2.0 + dx, map.height / 2.0 + dy); - map.center = map.toCoordinate(mapCenterPoint); - - lastX = -1; - lastY = -1; + onSingleTapped: (eventPoint, button) => { + if (button === Qt.RightButton) { + if (mapview.unfinishedItem !== 'undefined') { + mapview.unfinishedItem.finishAddGeometry() + mapview.unfinishedItem = 'undefined' + } else + showMainMenu(lastCoordinate) + } else if (button === Qt.LeftButton) { + if (mapview.unfinishedItem !== 'undefined') { + if (mapview.unfinishedItem.addGeometry(view.map.toCoordinate(tapHandler.point.position), false)) { + mapview.unfinishedItem.finishAddGeometry() + mapview.unfinishedItem = 'undefined' + } + } + } } - onPressAndHold: (mouse) => { - if (Math.abs(map.pressX - mouse.x ) < map.jitterThreshold - && Math.abs(map.pressY - mouse.y ) < map.jitterThreshold) { - showMainMenu(lastCoordinate); + onDoubleTapped: (eventPoint, button) => { + var preZoomPoint = view.map.toCoordinate(eventPoint.position); + if (button === Qt.LeftButton) { + view.map.zoomLevel = Math.floor(view.map.zoomLevel + 1) + } else if (button === Qt.RightButton) { + view.map.zoomLevel = Math.floor(view.map.zoomLevel - 1) } + var postZoomPoint = view.map.toCoordinate(eventPoint.position); + var dx = postZoomPoint.latitude - preZoomPoint.latitude; + var dy = postZoomPoint.longitude - preZoomPoint.longitude; + + view.map.center = QtPositioning.coordinate(view.map.center.latitude - dx, + view.map.center.longitude - dy); } } //! [end] diff --git a/examples/location/mapviewer/map/Marker.qml b/examples/location/mapviewer/map/Marker.qml index 8c548fd4..ee3e1a0d 100644 --- a/examples/location/mapviewer/map/Marker.qml +++ b/examples/location/mapviewer/map/Marker.qml @@ -8,52 +8,39 @@ import QtLocation MapQuickItem { id: marker //! [mqi-top] - property alias lastMouseX: markerMouseArea.lastX - property alias lastMouseY: markerMouseArea.lastY //! [mqi-anchor] anchorPoint.x: image.width/4 anchorPoint.y: image.height + HoverHandler { + id: hoverHandler + } + TapHandler { + id: tapHandler + acceptedButtons: Qt.RightButton + gesturePolicy: TapHandler.WithinBounds + onTapped: { + mapview.currentMarker = -1 + for (var i = 0; i< mapview.markers.length; i++){ + if (marker == mapview.markers[i]){ + mapview.currentMarker = i + break + } + } + mapview.showMarkerMenu(marker.coordinate) + } + } + DragHandler { + id: dragHandler + grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType + } + sourceItem: Image { id: image //! [mqi-anchor] source: "../resources/marker.png" - opacity: markerMouseArea.pressed ? 0.6 : 1.0 - MouseArea { - id: markerMouseArea - property int pressX : -1 - property int pressY : -1 - property int jitterThreshold : 10 - property int lastX: -1 - property int lastY: -1 - anchors.fill: parent - hoverEnabled : false - drag.target: marker - preventStealing: true - - onPressed : (mouse) => { - map.pressX = mouse.x - map.pressY = mouse.y - map.currentMarker = -1 - for (var i = 0; i< map.markers.length; i++){ - if (marker == map.markers[i]){ - map.currentMarker = i - break - } - } - } - - onPressAndHold: (mouse) => { - if (Math.abs(map.pressX - mouse.x ) < map.jitterThreshold - && Math.abs(map.pressY - mouse.y ) < map.jitterThreshold) { - var p = map.fromCoordinate(marker.coordinate) - lastX = p.x - lastY = p.y - map.showMarkerMenu(marker.coordinate) - } - } - } + opacity: hoverHandler.hovered ? 0.6 : 1.0 Text{ id: number @@ -64,7 +51,7 @@ MapQuickItem { font.pixelSize: 14 horizontalAlignment: Text.AlignHCenter Component.onCompleted: { - text = map.markerCounter + text = mapview.markerCounter } } @@ -72,8 +59,6 @@ MapQuickItem { } //! [mqi-closeimage] - Component.onCompleted: coordinate = map.toCoordinate(Qt.point(markerMouseArea.mouseX, - markerMouseArea.mouseY)); //! [mqi-close] } //! [mqi-close] diff --git a/examples/location/mapviewer/map/MiniMap.qml b/examples/location/mapviewer/map/MiniMap.qml index 6ecd1d07..f12c913e 100644 --- a/examples/location/mapviewer/map/MiniMap.qml +++ b/examples/location/mapviewer/map/MiniMap.qml @@ -14,21 +14,21 @@ Rectangle{ function minimumScaleFactor() { - var hscalefactor = (400.0 / Math.max(Math.min(map.width, 1000), 400)) * 0.5 - var vscalefactor = (400.0 / Math.max(Math.min(map.height, 1000), 400)) * 0.5 + var hscalefactor = (400.0 / Math.max(Math.min(mapview.width, 1000), 400)) * 0.5 + var vscalefactor = (400.0 / Math.max(Math.min(mapview.height, 1000), 400)) * 0.5 return Math.min(hscalefactor,vscalefactor) } function avgScaleFactor() { - var hscalefactor = (400.0 / Math.max(Math.min(map.width, 1000), 400)) * 0.5 - var vscalefactor = (400.0 / Math.max(Math.min(map.height, 1000), 400)) * 0.5 + var hscalefactor = (400.0 / Math.max(Math.min(mapview.width, 1000), 400)) * 0.5 + var vscalefactor = (400.0 / Math.max(Math.min(mapview.height, 1000), 400)) * 0.5 return (hscalefactor+vscalefactor) * 0.5 } id: miniMapRect - width: Math.floor(map.width * avgScaleFactor()) + 2 - height: Math.floor(map.height * avgScaleFactor()) + 2 + width: Math.floor(mapview.width * avgScaleFactor()) + 2 + height: Math.floor(mapview.height * avgScaleFactor()) + 2 anchors.right: (parent) ? parent.right : undefined anchors.rightMargin: 10 anchors.top: (parent) ? parent.top : undefined @@ -40,14 +40,13 @@ Rectangle{ anchors.topMargin: 1 anchors.left: parent.left anchors.leftMargin: 1 - width: Math.floor(map.width * avgScaleFactor()) - height: Math.floor(map.height * avgScaleFactor()) - zoomLevel: clamp(map.zoomLevel - 4.5, 2.0, 5.0) //(map.zoomLevel > minimumZoomLevel + 3) ? minimumZoomLevel + 3 : 1.5 - center: map.center - plugin: map.plugin - gesture.enabled: false + width: Math.floor(mapview.width * avgScaleFactor()) + height: Math.floor(mapview.height * avgScaleFactor()) + zoomLevel: clamp(mapview.map.zoomLevel - 4.5, 1.0, 5.0) //(map.zoomLevel > minimumZoomLevel + 3) ? minimumZoomLevel + 3 : 1.5 + center: mapview.map.center + plugin: mapview.map.plugin copyrightsVisible: false - property double mapZoomLevel : map.zoomLevel + property double mapZoomLevel : mapview.map.zoomLevel // cannot use property bindings on map.visibleRegion in MapRectangle because it's non-NOTIFYable onCenterChanged: miniMapRectangle.updateCoordinates() @@ -60,10 +59,11 @@ Rectangle{ color: "#44ff0000" border.width: 1 border.color: "red" + autoFadeIn: false function getMapVisibleRegion() { - return QtPositioning.shapeToRectangle(map.visibleRegion) + return mapview.map.visibleRegion.boundingGeoRectangle() } function updateCoordinates() diff --git a/examples/location/mapviewer/map/PolygonItem.qml b/examples/location/mapviewer/map/PolygonItem.qml index 97f4e95c..d9a2be99 100644 --- a/examples/location/mapviewer/map/PolygonItem.qml +++ b/examples/location/mapviewer/map/PolygonItem.qml @@ -3,24 +3,30 @@ import QtQuick import QtLocation -//TODO: remove me when items are integrated - MapPolygon { - color: "#46a2da" - border.color: "#190a33" + color: "#da5546" + border.color: "#330a0a" border.width: 2 smooth: true - opacity: 0.25 + opacity: 0.75 + + function setGeometry(anchorCoordinate){ + addCoordinate(anchorCoordinate) + } - function setGeometry(markers, index){ - for (var i = index; i 0) + removeCoordinate(path[path.length-1]) + addCoordinate(newCoordinate) + return false } - MouseArea { - anchors.fill:parent - id: mousearea - drag.target: parent + + function finishAddGeometry(){ + if (path.length > 0) + removeCoordinate(path[path.length-1]) + color = "#46a2da" + border.color = "#190a33" + opacity = 0.25 } } diff --git a/examples/location/mapviewer/map/PolylineItem.qml b/examples/location/mapviewer/map/PolylineItem.qml index 03031707..727ce973 100644 --- a/examples/location/mapviewer/map/PolylineItem.qml +++ b/examples/location/mapviewer/map/PolylineItem.qml @@ -3,18 +3,28 @@ import QtQuick import QtLocation -//TODO: remove/refactor me when items are integrated - MapPolyline { - line.color: "#46a2da" + line.color: "#330a0a" line.width: 4 - opacity: 0.25 + opacity: 0.75 smooth: true - function setGeometry(markers, index){ - for (var i = index; i" + qsTr("Distance:") + " " + distance) break - case "drawImage": - map.addGeoItem("ImageItem") - break - case "drawRectangle": - map.addGeoItem("RectangleItem") - break - case "drawCircle": - map.addGeoItem("CircleItem") - break; - case "drawPolyline": - map.addGeoItem("PolylineItem") - break; - case "drawPolygonMenu": - map.addGeoItem("PolygonItem") - break default: - console.log("Unsupported operation") + console.log("Unsupported operation:", item) } } } @@ -359,13 +359,13 @@ ApplicationWindow { stackView.showRouteListPage() break; case "deleteRoute": - map.routeModel.reset(); + mapview.routeModel.reset(); break; case "showPointInfo": - map.showGeocodeInfo() + mapview.showGeocodeInfo() break; case "deletePoint": - map.geocodeModel.reset() + geocodeModel.reset() break; default: console.log("Unsupported operation") @@ -381,7 +381,7 @@ ApplicationWindow { id: page Text { - visible: !supportsSsl && map && map.activeMapType && activeMapType.metadata.isHTTPS + visible: !supportsSsl && map && mapview.activeMapType && activeMapType.metadata.isHTTPS text: "The active map type\n requires (missing) SSL\n support" @@ -419,7 +419,7 @@ support" { push("forms/RouteList.qml", { - "routeModel" : map.routeModel + "routeModel" : mapview.routeModel }) currentItem.closeForm.connect(closeForm) } @@ -428,26 +428,26 @@ support" Component { id: mapComponent - MapComponent{ + MapComponent { width: page.width height: page.height - onFollowmeChanged: mainMenu.isFollowMe = map.followme - onSupportedMapTypesChanged: mainMenu.mapTypeMenu.createMenu(map) + onFollowmeChanged: mainMenu.isFollowMe = followme + map.onSupportedMapTypesChanged: mainMenu.mapTypeMenu.createMenu(map) onCoordinatesCaptured: (latitude, longitude) => { var text = "" + qsTr("Latitude:") + " " + Helper.roundNumber(latitude,4) + "
" + qsTr("Longitude:") + " " + Helper.roundNumber(longitude,4) stackView.showMessage(qsTr("Coordinates"),text); } onGeocodeFinished:{ - if (map.geocodeModel.status == GeocodeModel.Ready) { - if (map.geocodeModel.count == 0) { + if (geocodeModel.status == GeocodeModel.Ready) { + if (geocodeModel.count == 0) { stackView.showMessage(qsTr("Geocode Error"),qsTr("Unsuccessful geocode")) - } else if (map.geocodeModel.count > 1) { - stackView.showMessage(qsTr("Ambiguous geocode"), map.geocodeModel.count + " " + + } else if (geocodeModel.count > 1) { + stackView.showMessage(qsTr("Ambiguous geocode"), geocodeModel.count + " " + qsTr("results found for the given address, please specify location")) } else { stackView.showMessage(qsTr("Location"), geocodeMessage(),page) } - } else if (map.geocodeModel.status == GeocodeModel.Error) { + } else if (geocodeModel.status == GeocodeModel.Error) { stackView.showMessage(qsTr("Geocode Error"),qsTr("Unsuccessful geocode")) } } @@ -455,11 +455,11 @@ support" onShowGeocodeInfo: stackView.showMessage(qsTr("Location"),geocodeMessage(),page) - onErrorChanged: { - if (map.error != Map.NoError) { + map.onErrorChanged: { + if (map.error != mapview.NoError) { var title = qsTr("ProviderError") - var message = map.errorString + "

" + qsTr("Try to select other provider") + "" - if (map.error == Map.MissingRequiredParameterError) + var message = mapview.errorString + "

" + qsTr("Try to select other provider") + "" + if (map.error == mapview.MissingRequiredParameterError) message += "
" + qsTr("or see") + " \'mapviewer --help\' " + qsTr("how to pass plugin parameters.") stackView.showMessage(title,message); @@ -470,6 +470,11 @@ support" onShowRouteMenu: (coordinate) => itemPopupMenu.show("Route",coordinate) onShowPointMenu: (coordinate) => itemPopupMenu.show("Point",coordinate) onShowRouteList: stackView.showRouteListPage() + + TapHandler { + onTapped: { + } + } } } } diff --git a/examples/location/mapviewer/menus/MapPopupMenu.qml b/examples/location/mapviewer/menus/MapPopupMenu.qml index e0d1bc61..cb0c8254 100644 --- a/examples/location/mapviewer/menus/MapPopupMenu.qml +++ b/examples/location/mapviewer/menus/MapPopupMenu.qml @@ -32,4 +32,29 @@ Menu { enabled: mapItemsCount > 0 onTriggered: itemClicked("deleteItems") } + + Menu { + title: qsTr("Draw...") + + MenuItem { + text: qsTr("Image") + onTriggered: itemClicked("drawImage") + } + MenuItem { + text: qsTr("Rectangle") + onTriggered: itemClicked("drawRectangle") + } + MenuItem { + text: qsTr("Circle") + onTriggered: itemClicked("drawCircle") + } + MenuItem { + text: qsTr("Polyline") + onTriggered: itemClicked("drawPolyline") + } + MenuItem { + text: qsTr("Polygon") + onTriggered: itemClicked("drawPolygonMenu") + } + } } diff --git a/examples/location/mapviewer/menus/MarkerPopupMenu.qml b/examples/location/mapviewer/menus/MarkerPopupMenu.qml index f16a9c1e..525c950c 100644 --- a/examples/location/mapviewer/menus/MarkerPopupMenu.qml +++ b/examples/location/mapviewer/menus/MarkerPopupMenu.qml @@ -35,32 +35,4 @@ Menu { onTriggered: currentMarker < markersCount-2 ? itemClicked("distanceToNextPoints") : itemClicked("distanceToNextPoint") } - Menu { - title: qsTr("Draw...") - - MenuItem { - text: qsTr("Image") - onTriggered: itemClicked("drawImage") - } - MenuItem { - text: qsTr("Rectangle") - enabled: currentMarker <= markersCount - 2 - onTriggered: itemClicked("drawRectangle") - } - MenuItem { - text: qsTr("Circle") - enabled: currentMarker <= markersCount - 2 - onTriggered: itemClicked("drawCircle") - } - MenuItem { - text: qsTr("Polyline") - enabled: currentMarker <= markersCount - 2 - onTriggered: itemClicked("drawPolyline") - } - MenuItem { - text: qsTr("Polygon") - enabled: currentMarker < markersCount-2 - onTriggered: itemClicked("drawPolygonMenu") - } - } } diff --git a/examples/location/places/items/MapComponent.qml b/examples/location/places/items/MapComponent.qml index fe282564..90ad0691 100644 --- a/examples/location/places/items/MapComponent.qml +++ b/examples/location/places/items/MapComponent.qml @@ -7,8 +7,8 @@ import QtPositioning import QtLocation import "../helper.js" as Helper -Map { - id: map +MapView { + id: view property bool followme: false property var scaleLengths: [5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000] @@ -41,32 +41,30 @@ Map { scaleText.text = text } - center { + map.center { // The Qt Company in Oslo latitude: 59.9485 longitude: 10.7686 } - gesture.flickDeceleration: 3000 - gesture.enabled: true - onCopyrightLinkActivated: Qt.openUrlExternally(link) + map.onCopyrightLinkActivated: Qt.openUrlExternally(link) - onCenterChanged:{ + map.onCenterChanged: { scaleTimer.restart() if (map.followme) if (map.center !== positionSource.position.coordinate) map.followme = false } - onZoomLevelChanged:{ + map.onZoomLevelChanged: { scaleTimer.restart() if (map.followme) map.center = positionSource.position.coordinate } - onWidthChanged:{ + onWidthChanged: { scaleTimer.restart() } - onHeightChanged:{ + onHeightChanged: { scaleTimer.restart() } @@ -84,7 +82,7 @@ Map { running: false repeat: false onTriggered: { - map.calculateScale() + view.calculateScale() } } @@ -123,12 +121,13 @@ Map { text: "0 m" } Component.onCompleted: { - map.calculateScale(); + view.calculateScale(); } } MapQuickItem { - id: poiTheQtComapny + parent: view.map + id: poiTheQtCompany sourceItem: Rectangle { width: 14; height: 14; color: "#e41e25"; border.width: 2; border.color: "white"; smooth: true; radius: 7 } coordinate { latitude: 59.9485 @@ -139,6 +138,7 @@ Map { } MapQuickItem { + parent: view.map sourceItem: Text{ text: "The Qt Company" color:"#242424" @@ -146,8 +146,8 @@ Map { styleColor: "#ECECEC" style: Text.Outline } - coordinate: poiTheQtComapny.coordinate - anchorPoint: Qt.point(-poiTheQtComapny.sourceItem.width * 0.5,poiTheQtComapny.sourceItem.height * 1.5) + coordinate: poiTheQtCompany.coordinate + anchorPoint: Qt.point(-poiTheQtCompany.sourceItem.width * 0.5,poiTheQtCompany.sourceItem.height * 1.5) } PositionSource{ @@ -155,7 +155,7 @@ Map { active: followme onPositionChanged: { - map.center = positionSource.position.coordinate + view.map.center = positionSource.position.coordinate } } diff --git a/examples/location/places/items/SearchBar.qml b/examples/location/places/items/SearchBar.qml index a06fdba2..706e40cf 100644 --- a/examples/location/places/items/SearchBar.qml +++ b/examples/location/places/items/SearchBar.qml @@ -29,10 +29,10 @@ ToolBar { } } + height: searchBar.height RowLayout { id: searchBar width: parent.width - height: parent.height Behavior on opacity { NumberAnimation{} } visible: opacity ? true : false TextField { @@ -42,6 +42,8 @@ ToolBar { property bool ignoreTextChange: false placeholderText: qsTr("Type place...") Layout.fillWidth: true + Layout.topMargin: 2 + Layout.bottomMargin: 2 onTextChanged: { if (!ignoreTextChange) searchTextChanged(text) @@ -52,11 +54,15 @@ ToolBar { id: searchButton icon.source: Qt.resolvedUrl("../resources/search.png") onClicked: doSearch(searchText.text) + Layout.topMargin: 2 + Layout.bottomMargin: 2 } ToolButton { id: categoryButton icon.source: Qt.resolvedUrl("../resources/categories.png") onClicked: showCategories() + Layout.topMargin: 2 + Layout.bottomMargin: 2 } } @@ -82,4 +88,3 @@ ToolBar { } } } - diff --git a/examples/location/places/places.qml b/examples/location/places/places.qml index 329cc685..2698a56c 100644 --- a/examples/location/places/places.qml +++ b/examples/location/places/places.qml @@ -10,14 +10,12 @@ import "items" ApplicationWindow { id: appWindow - property Map map + property MapView view property var parameters - property var searchLocation: map ? map.center : QtPositioning.coordinate() - property var searchRegion: QtPositioning.circle(searchLocation) + property var searchLocation: view ? view.map.center : QtPositioning.coordinate() + property var searchRegion: QtPositioning.circle(searchLocation, 5000) property var searchRegionItem - property Plugin favoritesPlugin - function getPlugins() { var plugin = Qt.createQmlObject('import QtLocation; Plugin {}', appWindow); var myArray = new Array; @@ -53,15 +51,21 @@ ApplicationWindow { else plugin = Qt.createQmlObject ('import QtLocation; Plugin{ name:"' + provider + '"}', appWindow) - if (map) - map.destroy(); - map = mapComponent.createObject(page); - map.plugin = plugin; - map.zoomLevel = (map.maximumZoomLevel - map.minimumZoomLevel)/2 + if (view) + view.destroy(); + view = mapComponent.createObject(page); + view.map.plugin = plugin; + view.map.zoomLevel = (view.map.maximumZoomLevel - view.map.minimumZoomLevel)/2 categoryModel.plugin = plugin; categoryModel.update(); placeSearchModel.plugin = plugin; suggestionModel.plugin = plugin; + + searchRegionItem = Qt.createQmlObject('import QtLocation; MapCircle { parent: view.map; color: "#46a2da"; border.color: "#190a33"; border.width: 2; opacity: 0.25 }', view.map); + searchRegionItem.center = searchRegion.center; + searchRegionItem.radius = searchRegion.radius; + view.map.addMapItem(searchRegionItem); + } title: qsTr("Places") @@ -82,7 +86,7 @@ ApplicationWindow { providerMenu.contentData[i].checked = providerMenu.contentData[i].text === providerName } createMap(providerName) - if (map.error === Map.NoError) { + if (view.map.error === Map.NoError) { settingsMenu.create(settings) } else { mainMenu.clearMenu(settingsMenu) @@ -93,7 +97,7 @@ ApplicationWindow { stackView.pop({item:page,immediate: true}) switch (setting) { case "Search Center": - stackView.push(Qt.resolvedUrl("forms/SearchCenter.qml"), { "coordinate": map.center }) + stackView.push(Qt.resolvedUrl("forms/SearchCenter.qml"), { "coordinate": view.map.center }) stackView.currentItem.changeSearchCenter.connect(stackView.changeSearchCenter) stackView.currentItem.closeForm.connect(stackView.closeForm) break @@ -108,7 +112,7 @@ ApplicationWindow { stackView.currentItem.closeForm.connect(stackView.closeForm) break case "Search Options": - stackView.push(Qt.resolvedUrl("forms/SearchOptions.qml"), { "plugin": map.plugin, "model": placeSearchModel }) + stackView.push(Qt.resolvedUrl("forms/SearchOptions.qml"), { "plugin": view.map.plugin, "model": placeSearchModel }) stackView.currentItem.changeSearchSettings.connect(stackView.changeSearchSettings) stackView.currentItem.closeForm.connect(stackView.closeForm) break @@ -127,8 +131,8 @@ ApplicationWindow { stackView.currentItem && stackView.currentItem.objectName != "suggestionView" ? false : true onShowCategories: { - if (map && map.plugin) { - stackView.pop({tem:page,immediate: true}) + if (view && view.map.plugin) { + stackView.pop({item: page,immediate: true}) stackView.enterCategory() } } @@ -288,9 +292,9 @@ ApplicationWindow { function changeSearchCenter(coordinate) { stackView.pop(page) - map.center = coordinate; + view.map.center = coordinate; if (searchRegionItem) { - map.removeMapItem(searchRegionItem); + view.map.removeMapItem(searchRegionItem); searchRegionItem.destroy(); } } @@ -298,51 +302,43 @@ ApplicationWindow { function changeSearchBoundingBox(coordinate,widthDeg,heightDeg) { stackView.pop(page) - map.center = coordinate - searchRegion = QtPositioning.rectangle(map.center, widthDeg, heightDeg) + view.map.center = coordinate + searchRegion = QtPositioning.rectangle(view.map.center, widthDeg, heightDeg) if (searchRegionItem) { - map.removeMapItem(searchRegionItem); + view.map.removeMapItem(searchRegionItem); searchRegionItem.destroy(); } - searchRegionItem = Qt.createQmlObject('import QtLocation; MapRectangle { color: "#46a2da"; border.color: "#190a33"; border.width: 2; opacity: 0.25 }', page, "MapRectangle"); + searchRegionItem = Qt.createQmlObject('import QtLocation; MapRectangle { parent: view.map; color: "#46a2da"; border.color: "#190a33"; border.width: 2; opacity: 0.25 }', page); searchRegionItem.topLeft = searchRegion.topLeft; searchRegionItem.bottomRight = searchRegion.bottomRight; - map.addMapItem(searchRegionItem); + view.map.addMapItem(searchRegionItem); } function changeSearchBoundingCircle(coordinate,radius) { stackView.pop(page) - map.center = coordinate; + view.map.center = coordinate; searchRegion = QtPositioning.circle(coordinate, radius) if (searchRegionItem) { - map.removeMapItem(searchRegionItem); + view.map.removeMapItem(searchRegionItem); searchRegionItem.destroy(); } - searchRegionItem = Qt.createQmlObject('import QtLocation; MapCircle { color: "#46a2da"; border.color: "#190a33"; border.width: 2; opacity: 0.25 }', page, "MapRectangle"); + searchRegionItem = Qt.createQmlObject('import QtLocation; MapCircle { parent: view.map; color: "#46a2da"; border.color: "#190a33"; border.width: 2; opacity: 0.25 }', page); searchRegionItem.center = searchRegion.center; searchRegionItem.radius = searchRegion.radius; - map.addMapItem(searchRegionItem); + view.map.addMapItem(searchRegionItem); } function changeSearchSettings(orderByDistance, orderByName, locales) { stackView.pop(page) - /*if (isFavoritesEnabled) { - if (favoritesPlugin == null) - favoritesPlugin = Qt.createQmlObject('import QtLocation; Plugin { name: "places_jsondb" }', page); - favoritesPlugin.parameters = pluginParametersFromMap(pluginParameters); - placeSearchModel.favoritesPlugin = favoritesPlugin; - } else { - placeSearchModel.favoritesPlugin = null; - }*/ placeSearchModel.favoritesPlugin = null; placeSearchModel.relevanceHint = orderByDistance ? PlaceSearchModel.DistanceHint : orderByName ? PlaceSearchModel.LexicalPlaceNameHint : PlaceSearchModel.UnspecifiedHint; - map.plugin.locales = locales.split(Qt.locale().groupSeparator); + view.map.plugin.locales = locales.split(Qt.locale().groupSeparator); } //! [PlaceRecommendationModel search] @@ -431,11 +427,12 @@ ApplicationWindow { MapComponent { width: page.width height: page.height + id: view - onErrorChanged: { + map.onErrorChanged: { if (map.error !== Map.NoError) { var title = qsTr("ProviderError"); - var message = map.errorString + "

" + qsTr("Try to select other provider") + ""; + var message = map.errorString + "

" + qsTr("Try to select other provider") + ""; if (map.error === Map.MissingRequiredParameterError) message += "
" + qsTr("or see") + " \'mapviewer --help\' " + qsTr("how to pass plugin parameters."); @@ -445,20 +442,32 @@ ApplicationWindow { MapItemView { model: placeSearchModel + parent: view.map + delegate: MapQuickItem { coordinate: model.type === PlaceSearchModel.PlaceResult ? place.location.coordinate : QtPositioning.coordinate() - visible: model.type === PlaceSearchModel.PlaceResult - anchorPoint.x: image.width * 0.28 - anchorPoint.y: image.height + anchorPoint.x: image.width * 0.5 + anchorPoint.y: image.height * 0.5 - sourceItem: Image { - id: image - source: "resources/marker.png" - MouseArea { - anchors.fill: parent - onClicked: stackView.showPlaceDatails(model.place,model.distance) + sourceItem: Column { + TapHandler { + onTapped: stackView.showPlaceDatails(model.place,model.distance) + } + HoverHandler { + cursorShape: Qt.PointingHandCursor + } + + Image { + id: image + source: place.icon.url(Qt.size(64,64)) + anchors.horizontalCenter: parent.horizontalCenter; + } + Text { + id: text + text: title; + font.bold: true } } } diff --git a/examples/location/places/resources/left.png b/examples/location/places/resources/left.png index 8241a47a..3badbac1 100644 Binary files a/examples/location/places/resources/left.png and b/examples/location/places/resources/left.png differ diff --git a/examples/location/places/resources/right.png b/examples/location/places/resources/right.png index 37a1b1d3..f4d34e70 100644 Binary files a/examples/location/places/resources/right.png and b/examples/location/places/resources/right.png differ diff --git a/examples/location/places/resources/search.png b/examples/location/places/resources/search.png index ce8c27aa..e2bbd134 100644 Binary files a/examples/location/places/resources/search.png and b/examples/location/places/resources/search.png differ diff --git a/examples/location/places/views/CategoryDelegate.qml b/examples/location/places/views/CategoryDelegate.qml index ef013de8..75ff071b 100644 --- a/examples/location/places/views/CategoryDelegate.qml +++ b/examples/location/places/views/CategoryDelegate.qml @@ -26,7 +26,7 @@ Item { Rectangle { anchors.fill: parent color: "#44ffffff" - visible: mouse.pressed + visible: tapHanlder.pressed } //! [CategoryModel delegate text] @@ -34,14 +34,19 @@ Item { id: labelItem text: category.name anchors.left: icon.right + anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - anchors.right: arrow.left } - MouseArea { - id: mouse - anchors.fill: parent - onClicked: root.searchCategory() + TapHandler { + id: tapHanlder + onTapped: { + if (model.hasModelChildren) { + root.showSubcategories() + } else { + root.searchCategory() + } + } } //! [CategoryModel delegate text] @@ -52,15 +57,4 @@ Item { height: 1 color: "#46a2da" } - //! [CategoryModel delegate arrow] - ToolButton { - id: arrow - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: 15 - visible: model.hasModelChildren - icon.source: Qt.resolvedUrl("../resources/right.png") - onClicked: root.showSubcategories() - } - //! [CategoryModel delegate arrow] } diff --git a/examples/location/places/views/CategoryView.qml b/examples/location/places/views/CategoryView.qml index 7e5fc33a..96b798cb 100644 --- a/examples/location/places/views/CategoryView.qml +++ b/examples/location/places/views/CategoryView.qml @@ -24,7 +24,7 @@ ListView { delegate: CategoryDelegate { width: ListView.view.width onSearchCategory: root.searchCategory(category); - onShowSubcategories: root.showSubcategories(delegeteDataModel.modelIndex(index)) + onShowSubcategories: root.showSubcategories(delegeteDataModel.modelIndex(index)); } } } diff --git a/examples/location/places_map/places_map.qml b/examples/location/places_map/places_map.qml index 80a8f0e0..aaa56473 100644 --- a/examples/location/places_map/places_map.qml +++ b/examples/location/places_map/places_map.qml @@ -50,15 +50,16 @@ Rectangle { //! [PlaceSearchModel] //! [Places MapItemView] - Map { - id: map + MapView { + id: view anchors.fill: parent - plugin: myPlugin; - center: positionSource.lastSearchPosition - zoomLevel: 13 + map.plugin: myPlugin; + map.center: positionSource.lastSearchPosition + map.zoomLevel: 13 MapItemView { model: searchModel + parent: view.map delegate: MapQuickItem { coordinate: place.location.coordinate -- cgit v1.2.1