From 3f8b69399028c4e403fe989abf081b5e9561780a Mon Sep 17 00:00:00 2001 From: Natalia Shubina Date: Wed, 27 Jul 2011 12:47:45 +1000 Subject: qml_mapviewer: route info, new icons, scale Change-Id: I011dc0cec7592a281b4673bcc16b5aa1c3784236 Reviewed-on: http://codereview.qt.nokia.com/2235 Reviewed-by: Qt Sanity Bot Reviewed-by: Juha Vuolle --- examples/declarative/mapviewer/MapComponent.qml | 538 +++++++++++++++++---- examples/declarative/mapviewer/mapviewer.qml | 27 -- examples/declarative/mapviewer/mapviewer.qrc | 4 + examples/declarative/mapviewer/resources/catch.png | Bin 0 -> 1374 bytes .../declarative/mapviewer/resources/marker.png | Bin 1712 -> 2354 bytes .../mapviewer/resources/marker_hovered.png | Bin 1684 -> 2358 bytes .../mapviewer/resources/marker_selected.png | Bin 1696 -> 2356 bytes examples/declarative/mapviewer/resources/node.png | Bin 0 -> 433 bytes .../mapviewer/resources/node_selected.png | Bin 0 -> 439 bytes .../mapviewer/resources/option_button_selected.png | Bin 469 -> 417 bytes examples/declarative/mapviewer/resources/scale.png | Bin 0 -> 258 bytes 11 files changed, 440 insertions(+), 129 deletions(-) create mode 100755 examples/declarative/mapviewer/resources/catch.png create mode 100755 examples/declarative/mapviewer/resources/node.png create mode 100755 examples/declarative/mapviewer/resources/node_selected.png create mode 100755 examples/declarative/mapviewer/resources/scale.png diff --git a/examples/declarative/mapviewer/MapComponent.qml b/examples/declarative/mapviewer/MapComponent.qml index 81e28730..41c95e54 100644 --- a/examples/declarative/mapviewer/MapComponent.qml +++ b/examples/declarative/mapviewer/MapComponent.qml @@ -52,8 +52,7 @@ Map { property int longPressDuration: 1000 property list markers - property int numberOfMarkers: 0 //actual length of markers array - property int counter: 0 // counter for total amount of markers. Resets to 0 when numberOfMarkers = 0 + property int counter: 0 // counter for total amount of markers. Resets to 0 when number of markers = 0 property Marker currentMarker property RouteQuery routeQuery: RouteQuery {} @@ -62,7 +61,7 @@ Map { query: routeQuery onStatusChanged:{ if (status == RouteModel.Ready){ - if (count == 1) showRouteInfo() + if (count == 1) { routeInfoModel.update();} } else if (status == RouteModel.Error){ map.routeError() @@ -79,13 +78,14 @@ Map { if (count == 1) map.center = get(0).coordinate } } + property int lastX : -1 + property int lastY : -1 signal mousePressed() // replace with // signal mousePressed(MouseEvent mouse) // when QTBUG-14550 is fixed signal sliderUpdated() signal coordinatesCaptured(double latitude, double longitude) - signal showRouteInfo() signal geocodeFinished() signal showGeocodeInfo() signal moveMarker() @@ -95,30 +95,57 @@ Map { markers = [] } - onNumberOfMarkersChanged: { - if (numberOfMarkers == 0) counter = 0 - } - Component { id: routeDelegate - MapRoute { - route: path - color: routeMouseArea.containsMouse ? "lime" :"red" - MapMouseArea { - id: routeMouseArea - hoverEnabled: true - onPressed : {routeTimer.start(); map.state = ""} - onReleased : { if (routeTimer.running) routeTimer.stop() }//SHORT PRESS - onPositionChanged: { if (routeTimer.running) routeTimer.stop()} - - Timer { - id: routeTimer - interval: longPressDuration; running: false; repeat: false - onTriggered: { //LONG PRESS - map.showRouteInfo() + MapGroup { + MapRoute { + route: path + color: routeMouseArea.containsMouse ? "lime" :"red" + MapMouseArea { + id: routeMouseArea + + hoverEnabled: true + onPressed : { + routeTimer.start(); + map.state = "" + map.lastX = mouse.x + map.lastY = mouse.y + } + onReleased : { + if (routeTimer.running){ //SHORT PRESS + routeTimer.stop() + map.lastX = -1 + map.lastY = -1 + } + } + onPositionChanged: { + if (routeTimer.running) routeTimer.stop() + if (map.state == "") { + map.lastX = mouse.x + map.lastY = mouse.y + } + } + Timer { + id: routeTimer + interval: longPressDuration; running: false; repeat: false + onTriggered: { //LONG PRESS + map.state = "RoutePopupMenu" + } } } } + MapImage { + source: routeMouseArea.containsMouse ? "resources/node_selected.png" : "resources/node.png" + coordinate:path.path[0] + offset.x: -5 + offset.y: -5 + } + MapImage { + source: routeMouseArea.containsMouse ? "resources/node_selected.png" : "resources/node.png" + coordinate:path.path[path.path.length-1] + offset.x: -5 + offset.y: -5 + } } } @@ -131,24 +158,117 @@ Map { MapMouseArea { id: circleMouseArea hoverEnabled: true - onPressed : { circleTimer.start(); map.state = ""} - onReleased : { if (circleTimer.running) circleTimer.stop() }//SHORT PRESS + onPressed : { + circleTimer.start() + map.state = "" + map.lastX = mouse.x + map.lastY = mouse.y + } + onReleased : { + if (circleTimer.running) {//SHORT PRESS + circleTimer.stop(); + map.lastX = -1 + map.lastY = -1 + } + } onPositionChanged: { if (circleTimer.running) circleTimer.stop() - if (mouse.button == Qt.LeftButton) radius = center.distanceTo(mouse.coordinate) + if ((mouse.button == Qt.LeftButton) && (map.state == "")) radius = center.distanceTo(mouse.coordinate) + if (map.state == "") { + map.lastX = mouse.x + map.lastY = mouse.y + } } - Timer { id: circleTimer interval: longPressDuration; running: false; repeat: false onTriggered: { //LONG PRESS - map.showGeocodeInfo() + map.state = "PointPopupMenu" } } } } } + Component { + id: routeInfoDelegate + Row { + spacing: 10 + Text { + id: indexText + text: index + 1 + color: "white" + font.bold: true + font.pixelSize: 12 + } + Text { + text: instruction + color: "white" + height: indexText.height*3 + wrapMode: Text.Wrap + width: textArea.width - indexText.width - distanceText.width - spacing*4 + } + Text { + id: distanceText + text: distance + color: "white" + font.bold: true + font.pixelSize: 12 + } + } + } + + Component{ + id: routeInfoHeader + Item { + width: textArea.width + height: travelTime.height + line.anchors.topMargin + line.height + Text { + id: travelTime + text: routeInfoModel.travelTime + color: "white" + font.bold: true + font.pixelSize: 14 + anchors.left: parent.left + } + Text { + id: distance + text: routeInfoModel.distance + color: "white" + font.bold: true + font.pixelSize: 14 + anchors.right: parent.right + } + Rectangle { + id: line + color: "white" + width: parent.width + height: 2 + anchors.left: parent.left + anchors.topMargin: 1 + anchors.top: distance.bottom + } + } + } + + + ListModel{ + id: routeInfoModel + property string travelTime + property string distance + + function update() { + clear() + if (routeModel.count > 0){ + for (var i=0; i< routeModel.get(0).segments.length; i++){ + append({"instruction": routeModel.get(0).segments[i].maneuver.instructionText, "distance": formatDistance(routeModel.get(0).segments[i].maneuver.distanceToNextInstruction)}) + } + } + travelTime = routeModel.count == 0 ? "" : formatTime(routeModel.get(0).travelTime) + distance = routeModel.count == 0 ? "" : formatDistance(routeModel.get(0).distance) + } + } + MapObjectView { model: routeModel delegate: routeDelegate @@ -170,6 +290,65 @@ Map { longitude : 153.088 } + Item { + id: infoTab + parent: scale.parent + z: map.z + height: parent.height - 180 + width: parent.width + x: -5 - infoRect.width + y: 60 + visible: (routeInfoModel.count > 0) + Image { + id: catchImage + source: "resources/catch.png" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + MouseArea { + anchors.fill: parent + onClicked: { + if (infoTab.x == -5) infoTab.x -= infoRect.width + else infoTab.x = -5 + map.state = "" + } + } + } + + Behavior on x { + PropertyAnimation { properties: "x"; duration: 300; easing.type: Easing.InOutQuad } + } + + Rectangle { + id: infoRect + width: parent.width - catchImage.sourceSize.width + height: parent.height + color: "grey" + opacity: 0.75 + radius: 5 + MouseArea { + anchors.fill: parent + hoverEnabled: true + } + Item { + id: textArea + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.top: parent.top + anchors.topMargin: 10 + width: parent.width -15 + height: parent.height - 20 + ListView { + id: routeInfoView + model: routeInfoModel + delegate: routeInfoDelegate + header: routeInfoHeader + anchors.fill: parent + clip: true + } + } + } + } + Common.Slider { id: zoomSlider; parent: map.parent //todo: remove the line @@ -190,6 +369,40 @@ Map { } } + Item {//scale + id: scale + parent: zoomSlider.parent + z: map.z + opacity: 0.6 + visible: map.zoomLevel == 0 ? false : true + anchors { + bottom: zoomSlider.top; + bottomMargin: 8; + leftMargin: 20 + left: zoomSlider.left + } + Image { + id: scaleImage + source: "resources/scale.png" + anchors.bottom: parent.bottom + anchors.left: parent.left + } + Text { + id: scaleText + color: "black" + horizontalAlignment: Text.AlignHCenter + width: scaleImage.sourceSize.width + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.bottomMargin: 3 + Component.onCompleted: {text = calculateScale()} + } + } + + onCenterChanged:{ + scaleText.text = calculateScale() + } + Common.Menu { id: markerMenu orientation: ListView.Vertical @@ -240,11 +453,11 @@ Map { addMarker() break; } - case 1: { + case 1: {//show coordinates map.coordinatesCaptured(mouseArea.lastCoordinate.latitude, mouseArea.lastCoordinate.longitude) break; } - case 2: { + case 2: { //delete all Markers map.deleteAllMarkers() break; } @@ -253,51 +466,187 @@ Map { } } + Common.Menu { + id: routeMenu + orientation: ListView.Vertical + z: map.z +2 + opacity: 0 + + itemHeight: 30; + itemWidth: 150 + x: 0 + y: 0 + + onClicked: { + switch (button) { + case 0: {//delete route + routeModel.clear() + routeInfoModel.update() + break; + } + } + map.state = "" + } + Component.onCompleted: { + setModel(["Delete"]) + } + } + + Common.Menu { + id: pointMenu + orientation: ListView.Vertical + z: map.z +2 + opacity: 0 + + itemHeight: 30; + itemWidth: 150 + x: 0 + y: 0 + + onClicked: { + switch (button) { + case 0: {//point info + map.showGeocodeInfo() + break; + } + case 1: {//delete point + geocodeModel.clear() + break; + } + } + map.state = "" + } + Component.onCompleted: { + setModel(["Info", "Delete"]) + } + } + + onZoomLevelChanged:{ + zoomSlider.value = map.zoomLevel + scaleText.text = map.calculateScale() + } + + MapMouseArea { + id: mouseArea + property Coordinate lastCoordinate: Coordinate { latitude : 0; longitude : 0} + + onPressed : { + mapTimer.start() + map.state = "" + map.lastX = mouse.x + map.lastY = mouse.y + lastCoordinate = mouse.coordinate + map.mousePressed() + } + onReleased : { + if (mapTimer.running) {//SHORT PRESS + mapTimer.stop() + map.lastX = -1 + map.lastY = -1 + } + } + onPositionChanged: { + if (mapTimer.running) mapTimer.stop() + if ((mouse.button == Qt.LeftButton) & (map.state == "")) { + if ((map.lastX != -1) && (map.lastY != -1)) { + var dx = mouse.x - map.lastX + var dy = mouse.y - map.lastY + map.pan(-dx, -dy) + } + map.lastX = mouse.x + map.lastY = mouse.y + } + } + onDoubleClicked: { + map.center = mouse.coordinate + if (mouse.button == Qt.LeftButton){ + map.zoomLevel += 1 + } else if (mouse.button == Qt.RightButton){ + map.zoomLevel -= 1 + } + lastX = -1 + lastY = -1 + } + Timer { + id: mapTimer + interval: longPressDuration; running: false; repeat: false + onTriggered: { //LONG PRESS + if (map.markers.length != 0) popupMenu.setModel(["Set Marker","Coordinates","Delete all markers"]) + else popupMenu.setModel(["Set Marker","Coordinates"]) + + map.state = "PopupMenu" + } + } + } + + Keys.onPressed: { + if ((event.key == Qt.Key_Plus) || (event.key == Qt.Key_VolumeUp)) { + map.zoomLevel += 1 + } else if ((event.key == Qt.Key_Minus) || (event.key == Qt.Key_VolumeDown)){ + map.zoomLevel -= 1 + } + } + + function calculateScale(){ + var coord1, coord2, dist, text + if (map.zoomLevel == 0) { text=""} + else{ + coord1 = map.toCoordinate(Qt.point(0,scale.y)) + coord2 = map.toCoordinate(Qt.point(0+scaleImage.sourceSize.width,scale.y)) + dist = Math.round(coord1.distanceTo(coord2)) + text = formatDistance(dist) + } + return text + } + function deleteAllMarkers(){ - for (var i = 0; i 2){ - if (currentMarker == markers[numberOfMarkers-2]) array = ["Delete", "Move to", "Coordinates", "Route to next point"] + if (currentMarker == markers[count-1]) array = ["Delete", "Move to", "Coordinates"] + else if (count > 2){ + if (currentMarker == markers[count-2]) array = ["Delete", "Move to", "Coordinates", "Route to next point"] else array = ["Delete", "Move to", "Coordinates", "Route to next points"] } else array = ["Delete", "Move to", "Coordinates", "Route to next point"] @@ -309,7 +658,8 @@ Map { function calculateRoute(marker){ routeQuery.clearWaypoints(); var startPointFound = false - for (var i = 0; i< numberOfMarkers; i++){ + var count = map.markers.length + for (var i = 0; i< count; i++){ if (startPointFound != true){ if (markers[i] == marker){ startPointFound = true @@ -323,70 +673,42 @@ Map { routeModel.update(); } - onZoomLevelChanged:{ - zoomSlider.value = map.zoomLevel + function roundNumber(number, digits) { + var multiple = Math.pow(10, digits); + return Math.round(number * multiple) / multiple; } - MapMouseArea { - id: mouseArea - property int lastX : -1 - property int lastY : -1 - property Coordinate lastCoordinate: Coordinate { latitude : 0; longitude : 0} - - onPressed : { - mapTimer.start() - map.state = "" - lastX = mouse.x - lastY = mouse.y - lastCoordinate = mouse.coordinate - map.mousePressed() - } - onReleased : { - if (mapTimer.running) { mapTimer.stop() //SHORT PRESS - lastX = -1 - lastY = -1 - } - } - onPositionChanged: { - if (mapTimer.running) mapTimer.stop() - if ((mouse.button == Qt.LeftButton) & (map.state == "")) { - if ((lastX != -1) && (lastY != -1)) { - var dx = mouse.x - lastX - var dy = mouse.y - lastY - map.pan(-dx, -dy) - } - lastX = mouse.x - lastY = mouse.y - } - } - onDoubleClicked: { - map.center = mouse.coordinate - if (mouse.button == Qt.LeftButton){ - map.zoomLevel += 1 - } else if (mouse.button == Qt.RightButton){ - map.zoomLevel -= 1 - } - lastX = -1 - lastY = -1 - } - Timer { - id: mapTimer - interval: longPressDuration; running: false; repeat: false - onTriggered: { //LONG PRESS - if (numberOfMarkers != 0) popupMenu.setModel(["Set Marker","Capture","Delete all markers"]) - else popupMenu.setModel(["Set Marker","Capture"]) - - map.state = "PopupMenu" - } - } + function formatTime(sec){ + var value = sec + var seconds = value % 60 + value /= 60 + value = (value > 1) ? Math.round(value) : 0 + var minutes = value % 60 + value /= 60 + value = (value > 1) ? Math.round(value) : 0 + var hours = value + if (hours > 0) value = hours + "h:"+ minutes + "m" + else value = minutes + "min" + return value } - Keys.onPressed: { - if ((event.key == Qt.Key_Plus) || (event.key == Qt.Key_VolumeUp)) { - map.zoomLevel += 1 - } else if ((event.key == Qt.Key_Minus) || (event.key == Qt.Key_VolumeDown)){ - map.zoomLevel -= 1 - } + function formatDistance(meters) + { + var dist = Math.round(meters) + if (dist > 1000 ){ + if (dist > 10000){ + dist = Math.round(dist / 1000) + } + else{ + dist = Math.round(dist / 100) + dist = dist / 10 + } + dist = dist + " km" + } + else{ + dist = dist + " m" + } + return dist } // states of map @@ -394,14 +716,26 @@ Map { State { name: "PopupMenu" PropertyChanges { target: popupMenu; opacity: 1} - PropertyChanges { target: popupMenu; x: ((mouseArea.lastX + popupMenu.width > map.width) ? map.width - popupMenu.width : mouseArea.lastX)} - PropertyChanges { target: popupMenu; y: ((mouseArea.lastY + popupMenu.height > map.height) ? map.height - popupMenu.height : mouseArea.lastY)} + PropertyChanges { target: popupMenu; x: ((map.lastX + popupMenu.width > map.width) ? map.width - popupMenu.width : map.lastX)} + PropertyChanges { target: popupMenu; y: ((map.lastY + popupMenu.height > map.height) ? map.height - popupMenu.height : map.lastY)} }, State { name: "MarkerPopupMenu" PropertyChanges { target: markerMenu; opacity: 1} PropertyChanges { target: markerMenu; x: ((currentMarker.lastMouseX + markerMenu.width > map.width) ? map.width - markerMenu.width : currentMarker.lastMouseX )} PropertyChanges { target: markerMenu; y: ((currentMarker.lastMouseY + markerMenu.height > map.height) ? map.height - markerMenu.height : currentMarker.lastMouseY)} + }, + State { + name: "RoutePopupMenu" + PropertyChanges { target: routeMenu; opacity: 1} + PropertyChanges { target: routeMenu; x: ((map.lastX + routeMenu.width > map.width) ? map.width - routeMenu.width : map.lastX)} + PropertyChanges { target: routeMenu; y: ((map.lastY + routeMenu.height > map.height) ? map.height - routeMenu.height : map.lastY)} + }, + State { + name: "PointPopupMenu" + PropertyChanges { target: pointMenu; opacity: 1} + PropertyChanges { target: pointMenu; x: ((map.lastX + pointMenu.width > map.width) ? map.width - pointMenu.width : map.lastX)} + PropertyChanges { target: pointMenu; y: ((map.lastY + pointMenu.height > map.height) ? map.height - pointMenu.height : map.lastY)} } ] } diff --git a/examples/declarative/mapviewer/mapviewer.qml b/examples/declarative/mapviewer/mapviewer.qml index 6a76ed8b..75b19632 100644 --- a/examples/declarative/mapviewer/mapviewer.qml +++ b/examples/declarative/mapviewer/mapviewer.qml @@ -505,26 +505,6 @@ Item { page.state = "Message" } - onShowRouteInfo: { - var value = map.routeModel.get(0).travelTime - var seconds = value % 60 - value /= 60 - value = Math.round(value) - var minutes = value % 60 - value /= 60 - value = Math.round(value) - var hours = value - var dist = roundNumber(map.routeModel.get(0).distance,0) - - if (dist>1000) dist = dist/1000 + " km" - else dist = dist + " m" - - messageDialog.title = "Route info" - messageDialog.text = "Travel time: " + hours + "h:"+ minutes + "m
Distance: " + dist; - - page.state = "Message" - } - onGeocodeFinished:{ var street, district, city, county, state, countryCode, country, latitude, longitude, text @@ -578,13 +558,6 @@ Item { return text } - - function roundNumber(number, digits) { - var multiple = Math.pow(10, digits); - var rndedNum = Math.round(number * multiple) / multiple; - return rndedNum; - } - //=====================States of page===================== states: [ State { diff --git a/examples/declarative/mapviewer/mapviewer.qrc b/examples/declarative/mapviewer/mapviewer.qrc index 3f622246..56b16ea1 100644 --- a/examples/declarative/mapviewer/mapviewer.qrc +++ b/examples/declarative/mapviewer/mapviewer.qrc @@ -30,5 +30,9 @@ resources/marker.png resources/marker_selected.png resources/marker_hovered.png + resources/node.png + resources/node_selected.png + resources/catch.png + resources/scale.png diff --git a/examples/declarative/mapviewer/resources/catch.png b/examples/declarative/mapviewer/resources/catch.png new file mode 100755 index 00000000..a07dabed Binary files /dev/null and b/examples/declarative/mapviewer/resources/catch.png differ diff --git a/examples/declarative/mapviewer/resources/marker.png b/examples/declarative/mapviewer/resources/marker.png index e2375e3c..a0d6b2df 100755 Binary files a/examples/declarative/mapviewer/resources/marker.png and b/examples/declarative/mapviewer/resources/marker.png differ diff --git a/examples/declarative/mapviewer/resources/marker_hovered.png b/examples/declarative/mapviewer/resources/marker_hovered.png index a974e721..890b67cc 100755 Binary files a/examples/declarative/mapviewer/resources/marker_hovered.png and b/examples/declarative/mapviewer/resources/marker_hovered.png differ diff --git a/examples/declarative/mapviewer/resources/marker_selected.png b/examples/declarative/mapviewer/resources/marker_selected.png index 5d97a17d..2f850ec4 100755 Binary files a/examples/declarative/mapviewer/resources/marker_selected.png and b/examples/declarative/mapviewer/resources/marker_selected.png differ diff --git a/examples/declarative/mapviewer/resources/node.png b/examples/declarative/mapviewer/resources/node.png new file mode 100755 index 00000000..e51978f2 Binary files /dev/null and b/examples/declarative/mapviewer/resources/node.png differ diff --git a/examples/declarative/mapviewer/resources/node_selected.png b/examples/declarative/mapviewer/resources/node_selected.png new file mode 100755 index 00000000..d46347bf Binary files /dev/null and b/examples/declarative/mapviewer/resources/node_selected.png differ diff --git a/examples/declarative/mapviewer/resources/option_button_selected.png b/examples/declarative/mapviewer/resources/option_button_selected.png index a0c01cf7..4ebb1223 100755 Binary files a/examples/declarative/mapviewer/resources/option_button_selected.png and b/examples/declarative/mapviewer/resources/option_button_selected.png differ diff --git a/examples/declarative/mapviewer/resources/scale.png b/examples/declarative/mapviewer/resources/scale.png new file mode 100755 index 00000000..3ceccc5e Binary files /dev/null and b/examples/declarative/mapviewer/resources/scale.png differ -- cgit v1.2.3