diff --git a/src/apps/marble-maps/AboutDialog.qml b/src/apps/marble-maps/AboutDialog.qml --- a/src/apps/marble-maps/AboutDialog.qml +++ b/src/apps/marble-maps/AboutDialog.qml @@ -13,144 +13,137 @@ import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 -import org.kde.marble 0.20 - -Item { - id: root - height: Screen.pixelDensity * 2 + Math.max(marbleText.height, devText.height) - - SystemPalette { - id: palette - colorGroup: SystemPalette.Active - } +import org.kde.kirigami 2.0 as Kirigami - Rectangle { - anchors.fill: parent - color: palette.base - } +import org.kde.marble 0.20 - SwipeView { - id: tabView - currentIndex: pageIndicator.currentIndex +Kirigami.Page { + Item { + id: root anchors.fill: parent + height: Screen.pixelDensity * 2 + Math.max(marbleText.height, devText.height) - Item { - id: marbleItem - Text { - id: marbleText - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: marbleLogo.left - anchors.margins: Screen.pixelDensity * 1 - anchors.leftMargin: Screen.pixelDensity * 2 - - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: qsTr("

Marble Maps

Find your way! Marble Maps brings the highly detailed OpenStreetMap to your mobile devices. It features a crisp, beautiful map with an intuitive user interface. It's open source, entirely based on free data and open standards and respects your privacy.

") - onLinkActivated: Qt.openUrlExternally(link) - } - - Image { - id: marbleLogo - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Screen.pixelDensity * 2 - height: 0.8 * marbleText.height - - fillMode: Image.PreserveAspectFit - source: "qrc:/konqi/globe.png" - } + SystemPalette { + id: palette + colorGroup: SystemPalette.Active } - Item { - id: supportItem - Text { - id: groupText - anchors.left: parent.left - anchors.right: groupKonqi.left - anchors.bottom: parent.bottom - anchors.margins: Screen.pixelDensity * 1 - anchors.leftMargin: Screen.pixelDensity * 2 - - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: qsTr("

Support

Do you have a question? Want to file a suggestion for improvement? Please use the Marble forum to get in touch with fellow Marble users and developers. Further support channels are listed at marble.kde.org. We are looking forward to your feedback!

") - onLinkActivated: Qt.openUrlExternally(link) - } - - Image { - id: groupKonqi - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.bottomMargin: Screen.pixelDensity * 3 - anchors.rightMargin: Screen.pixelDensity * 2 - height: 0.8 * groupText.height - fillMode: Image.PreserveAspectFit - source: "qrc:/konqi/group.png" + SwipeView { + id: tabView + currentIndex: pageIndicator.currentIndex + anchors.fill: parent + spacing: 100 + + Item { + id: marbleItem + Text { + id: marbleText + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Screen.pixelDensity * 1 + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + text: qsTr("

Marble Maps

Find your way! Marble Maps brings the highly detailed OpenStreetMap to your mobile devices. It features a crisp, beautiful map with an intuitive user interface. It's open source, entirely based on free data and open standards and respects your privacy.

") + onLinkActivated: Qt.openUrlExternally(link) + } + + Image { + id: marbleLogo + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: Screen.pixelDensity + height: marbleText.height + + fillMode: Image.PreserveAspectFit + source: "qrc:/konqi/globe.png" + } } - } - Item { - id: devItem - Text { - id: devText - anchors.left: parent.left - anchors.right: devKonqi.left - anchors.bottom: parent.bottom - anchors.margins: Screen.pixelDensity * 1 - anchors.leftMargin: Screen.pixelDensity * 2 - - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: qsTr("

Development Team

The main developers of this app are Dennis Nienhüser, Torsten Rahn, Sanjiban Bairagya, Friedrich W. H. Kossebau, Gábor Péterffy and Mikhail Ivchenko. They are part of more than 200 developers who already contributed to the Marble project. Contact us via marble-devel@kde.org.

") - onLinkActivated: Qt.openUrlExternally(link) + Item { + id: supportItem + Text { + id: groupText + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Screen.pixelDensity * 1 + + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + text: qsTr("

Support

Do you have a question? Want to file a suggestion for improvement? Please use the Marble forum to get in touch with fellow Marble users and developers. Further support channels are listed at marble.kde.org. We are looking forward to your feedback!

") + onLinkActivated: Qt.openUrlExternally(link) + } + + Image { + id: groupKonqi + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: Screen.pixelDensity * 3 + anchors.rightMargin: Screen.pixelDensity * 2 + height: groupText.height + + fillMode: Image.PreserveAspectFit + source: "qrc:/konqi/group.png" + } } - - Image { - id: devKonqi - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.bottomMargin: Screen.pixelDensity * 3 - anchors.rightMargin: Screen.pixelDensity * 2 - height: 0.8 * devText.height - - fillMode: Image.PreserveAspectFit - source: "qrc:/konqi/app-dev.png" + Item { + id: devItem + Text { + id: devText + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Screen.pixelDensity * 1 + + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + text: qsTr("

Development Team

The main developers of this app are Dennis Nienhüser, Torsten Rahn, Sanjiban Bairagya, Friedrich W. H. Kossebau, Gábor Péterffy and Mikhail Ivchenko. They are part of more than 200 developers who already contributed to the Marble project.
Contact us via marble-devel@kde.org.

") + onLinkActivated: Qt.openUrlExternally(link) + } + + Image { + id: devKonqi + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: Screen.pixelDensity * 3 + anchors.rightMargin: Screen.pixelDensity * 2 + height: devText.height + + fillMode: Image.PreserveAspectFit + source: "qrc:/konqi/app-dev.png" + } } - } - Item { - id: attributionItem - Text { - id: attributionText - anchors.left: parent.left - anchors.right: devQtKonqi.left - anchors.bottom: parent.bottom - anchors.margins: Screen.pixelDensity * 1 - anchors.leftMargin: Screen.pixelDensity * 2 - - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - width: parent.width - text: qsTr("

Attribution

The map is based on data from the OpenStreetMap project, available under the Open Database License. Additionally public domain data from the Natural Earth project is used. The map style is influenced by and uses icons from OpenStreetMap Carto (CC0 Public Domain).

") - onLinkActivated: Qt.openUrlExternally(link) - } - - Image { - id: devQtKonqi - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.bottomMargin: Screen.pixelDensity * 3 - anchors.rightMargin: Screen.pixelDensity * 2 - height: 0.8 * attributionText.height - - fillMode: Image.PreserveAspectFit - source: "qrc:/konqi/dev-qt.png" + Item { + id: attributionItem + Text { + id: attributionText + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Screen.pixelDensity * 1 + anchors.leftMargin: Screen.pixelDensity * 2 + + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + width: parent.width + text: qsTr("

Attribution

The map is based on data from the OpenStreetMap project, available under the Open Database License. Additionally public domain data from the Natural Earth project is used. The map style is influenced by and uses icons from OpenStreetMap Carto (CC0 Public Domain).

") + onLinkActivated: Qt.openUrlExternally(link) + } + + Image { + id: devQtKonqi + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: Screen.pixelDensity * 3 + anchors.rightMargin: Screen.pixelDensity * 2 + height: attributionText.height + + fillMode: Image.PreserveAspectFit + source: "qrc:/konqi/dev-qt.png" + } } } - } - PageIndicator { - id: pageIndicator - interactive: true - count: tabView.count - currentIndex: tabView.currentIndex + PageIndicator { + id: pageIndicator + interactive: true + count: tabView.count + currentIndex: tabView.currentIndex - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + } } } diff --git a/src/apps/marble-maps/BookmarkManager.qml b/src/apps/marble-maps/BookmarkManager.qml --- a/src/apps/marble-maps/BookmarkManager.qml +++ b/src/apps/marble-maps/BookmarkManager.qml @@ -21,7 +21,235 @@ import org.kde.marble 0.20 Kirigami.Page { + id: bookmarkPage + title: "Bookmarks" -} + property variant map + signal backTriggered() + + Flickable { + id: root + anchors.fill: parent + property int currentIndex: 0 + + SystemPalette { + id: palette + colorGroup: SystemPalette.Active + } + + Text { + id: title + text: "

Bookmarks

" + } + + ColumnLayout { + anchors { + top: title.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + margins: Screen.pixelDensity + } + + ListView { + id: listView + anchors.fill: parent + interactive: false + width: parent.width + + model: DelegateModel { + id: visualModel + model: bookmarks.model + + delegate: + MouseArea { + id: delegateRoot + propagateComposedEvents: true + property int visualIndex: DelegateModel.itemsIndex + width: listView.width + height: 100 + drag.target: icon + drag.axis: Drag.YAxis + + SwipeDelegate { + id: delegate + text: model.display + width: parent.width + height: Screen.pixelDensity * 2 + Math.max(bookmarkText.height, imageButton.height) + + contentItem: Rectangle { + id: icon + width: parent.width + height: Screen.pixelDensity + Math.max(bookmarkText.height, imageButton.height) + + anchors { + horizontalCenter: parent.horizontalCenter; + verticalCenter: parent.verticalCenter + } + + Drag.active: delegateRoot.drag.active + Drag.source: delegateRoot + Drag.hotSpot.x: 100 + Drag.hotSpot.y: 100 + + color: "transparent" + + Text{ + id: bookmarkText + rightPadding: delegate.spacing + anchors { + left: imageButton.right + } + leftPadding: 10 + text: delegate.text + font: delegate.font + color: palette.text + elide: Text.ElideRight + visible: delegate.text + horizontalAlignment: Text.AlignLeft + anchors.verticalCenter: parent.verticalCenter + } + + ImageButton { + id: imageButton + backgroundColor: "transparent" + imageSource: "qrc:///material/place.svg" + width: Screen.pixelDensity * 6 + height: width + touchArea.propagateComposedEvents: true + + image.sourceSize.height: height + image.sourceSize.width: width + anchors { + left: parent.left + verticalCenter: parent.verticalCenter + } + image.smooth: true + onClicked: { + + } + } + + ColorOverlay{ + id: colorOverlay + anchors.fill: imageButton + source: imageButton.image + color: model.color === null ? "#0E95C2" : "#FF009D" + } + } + background: Rectangle { + width: parent.width + height: parent.height + opacity: enabled ? 1 : 0.3 + color: delegate.down ? "#dddedf" : "transparent" + } + + swipe.behind: Rectangle { + width: parent.width + height: parent.height + clip: true + color: SwipeDelegate.pressed ? "#555" : "transparent" + + Label { + font.family: "Fontello" + text: delegate.swipe.complete ? "\ue805" // icon-cw-circled + : "\ue801" // icon-cancel-circled-1 + anchors.fill: parent + horizontalAlignment: Qt.AlignRight + verticalAlignment: Qt.AlignVCenter + + opacity: 2 * -delegate.swipe.position + color: Material.Red + Behavior on color { ColorAnimation { } } + } + + Rectangle{ + width: parent.width + color: "#333333" + height: parent.height + z: 200 + Text { + font.pointSize: 10 + text: qsTr("Removed") + color: "white" + + padding: 20 + anchors.fill: parent + horizontalAlignment: Qt.AlignRight + verticalAlignment: Qt.AlignVCenter + + opacity: delegate.swipe.complete ? 1 : 0 + Behavior on opacity { + NumberAnimation {} + } + } + } + + SwipeDelegate.onClicked: delegate.swipe.close() + SwipeDelegate.onPressedChanged: undoTimer.stop() + } + + + Timer { + id: undoTimer + interval: 1600 + onTriggered: { + var currentBookmark = bookmarks.placemark(index) + bookmarks.removeBookmark(currentBookmark.longitude, currentBookmark.latitude) + } + } + + swipe.onCompleted: undoTimer.start() + + states: [ + State { + when: icon.Drag.active + ParentChange { + target: icon + parent: root + } + + AnchorChanges { + target: icon; + anchors.horizontalCenter: undefined; + anchors.verticalCenter: undefined + } + } + ] + } + + DropArea { + anchors.fill: parent + onEntered: visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex) + } + } + } + + remove: Transition { + SequentialAnimation { + PauseAnimation { duration: 125 } + NumberAnimation { property: "height"; to: 0; easing.type: Easing.InOutQuad } + } + } + + displaced: Transition { + SequentialAnimation { + PauseAnimation { duration: 125 } + NumberAnimation { property: "y"; easing.type: Easing.InOutQuad } + } + } + } + } + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + } + + Bookmarks { + id: bookmarks + } + + onMapChanged: bookmarks.map = map +} diff --git a/src/apps/marble-maps/CMakeLists.txt b/src/apps/marble-maps/CMakeLists.txt --- a/src/apps/marble-maps/CMakeLists.txt +++ b/src/apps/marble-maps/CMakeLists.txt @@ -59,6 +59,7 @@ set(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/package") set(QT_ANDROID_APP_PACKAGE_NAME "org.kde.marble.maps") set(QT_ANDROID_APP_NAME "Marble Maps") + set(QT_ANDROID_APP_EXTRA_PLUGINS "${ABSOLUTE_INSTALL_PATH}//share,${ABSOLUTE_INSTALL_PATH}//lib/qml") configure_file(package/deploy-marble-maps.json.in ${CMAKE_CURRENT_BINARY_DIR}/deploy-marble-maps.json @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/deploy-marble-maps.json DESTINATION "${CMAKE_INSTALL_PREFIX}/share") install(TARGETS ${TARGET} LIBRARY DESTINATION libs/${ANDROID_ABI}) diff --git a/src/apps/marble-maps/FlatButton.qml b/src/apps/marble-maps/FlatButton.qml --- a/src/apps/marble-maps/FlatButton.qml +++ b/src/apps/marble-maps/FlatButton.qml @@ -25,9 +25,10 @@ style: ButtonStyle { background: Rectangle { anchors.fill: parent - color: root.pressed ? palette.highlight : palette.base + color: "transparent" Image { id: icon + smooth: true anchors.fill: parent source: root.imageSource } diff --git a/src/apps/marble-maps/ImageButton.qml b/src/apps/marble-maps/ImageButton.qml --- a/src/apps/marble-maps/ImageButton.qml +++ b/src/apps/marble-maps/ImageButton.qml @@ -21,6 +21,9 @@ height: image.height + 10 property alias imageSource: image.source + property alias image: image + property alias backgroundColor: background.color + property alias touchArea: touchArea signal clicked() SystemPalette{ diff --git a/src/apps/marble-maps/MainScreen.qml b/src/apps/marble-maps/MainScreen.qml --- a/src/apps/marble-maps/MainScreen.qml +++ b/src/apps/marble-maps/MainScreen.qml @@ -9,23 +9,25 @@ // Copyright 2015 Dennis Nienhüser // Copyright 2015 Mikhail Ivchenko // +import QtQuick 2.7 +import QtQuick.Dialogs 1.2 +import QtQuick.Controls 2.2 +import QtQuick.Window 2.1 +import QtQuick.Layouts 1.3 +import QtQuick.Controls.Material 2.0 - -import QtQuick 2.3 -import QtQuick.Controls 2.0 -import QtQuick.Window 2.2 +import org.kde.kirigami 2.0 as Kirigami import org.kde.marble 0.20 -ApplicationWindow { +Kirigami.ApplicationWindow { id: app - title: qsTr("Marble Maps") + width: 500 + height: 800 visible: true - width: 600 - height: 400 - - color: "#f9f9f9" // Keep the background white while no dialog is loaded + Material.theme: Material.Light + Material.accent: Material.Teal property alias state: stateTracker.state @@ -49,454 +51,668 @@ if (!selectedPlacemark) { app.state = "none" } - } - - SystemPalette{ - id: palette - colorGroup: SystemPalette.Active + else { + bookmarkButton.bookmark = bookmarks.isBookmark(selectedPlacemark.longitude, selectedPlacemark.latitude) + } } Settings { id: settings } - Item { - id: mapItem - anchors { - top: parent.top - topMargin: mapOffset - left: parent.left - right: parent.right + property bool aboutToQuit: false + onClosing: { + if (app.aboutToQuit === true) { + close.accepted = true // we will quit + return + } else if (sidePanel.drawerOpen) { + sidePanel.close() + } else if (pageStack.depth > 1) { + pageStack.pop() + } else if (navigationManager.visible) { + navigationManager.visible = false + } else if (app.state !== "none") { + app.state = "none" } + else if(search.searchResultsVisible.visible === true && !sidePanel.drawerOpen){ + search.searchResultsVisible = false + } + else { + if(search.searchResultsVisible === true){ + search.searchResultsVisible = false + } + app.aboutToQuit = true + quitHelper.visible = true + } + close.accepted = false + } - height: !dialogExpanded - ? parent.height - : parent.height + animatedMargin - - PinchArea { - anchors.fill: parent - enabled: true + globalDrawer: Kirigami.GlobalDrawer { + id: sidePanel + title: "Settings" - onPinchStarted: marbleMaps.handlePinchStarted(pinch.center) - onPinchFinished: marbleMaps.handlePinchFinished(pinch.center) - onPinchUpdated: marbleMaps.handlePinchUpdated(pinch.center, pinch.scale); + handleVisible: false + property alias showAccessibility: accessibilityAction.checked - MarbleMaps { - id: marbleMaps + Settings { + id: sidePanelSettings + property bool showUpdateInfo: Number(value("MarbleMaps", "updateInfoVersion", "0")) < 1 + Component.onDestruction: { + sidePanelSettings.setValue("MarbleMaps", "showAccessibility", accessibilityAction.checked ? "true" : "false") + } + } - property string currentPositionProvider: "QtPositioning" - property bool wlanOnly: false - property bool smallZoom : radius < 2 * Math.max(app.width, app.height) + actions: [ + Kirigami.Action { + id: publicTransportAction + text: qsTr("Public Transport") + checkable: true + checked: marbleMaps.showPublicTransport + iconName: "qrc:///material/directions-bus.svg" + visible: true + onTriggered: { + sidePanel.close() + marbleMaps.showPublicTransport = checked + publicTransportDialog.open() + } + }, + Kirigami.Action { + id: outdoorActivitiesAction + checkable: true + checked: marbleMaps.showOutdoorActivities + text: qsTr("Outdoor Activities") + visible: true + iconName: "qrc:///material/directions-run.svg" + onTriggered: { + sidePanel.close() + marbleMaps.showOutdoorActivities = checked + } + }, + Kirigami.Action { + id: accessibilityAction + checkable: true + checked: settings.value("MarbleMaps", "showAccessibility", "false") === "true" + text: qsTr("Accessibility") + visible: true + iconName: "qrc:///material/wheelchair.svg" + onTriggered: { + sidePanelSettings.value("MarbleMaps", "showAccessibility", "false") === "true" - anchors.fill: parent + } + }, + Kirigami.Action{ enabled: false}, + Kirigami.Action { + text: "About" + iconName: "qrc:///marble.svg" visible: true + onTriggered: { + app.state = "about" + sidePanel.close() + source = "" + app.pageStack.push("qrc:///AboutDialog.qml") + } + }, + Kirigami.Action { + text: "Bookmarks" + iconName: "qrc:///material/star.svg" + onTriggered: { + app.state = "bookmarks" + sidePanel.close() + app.pageStack.push("qrc:///BookmarkManager.qml") + } + }, + Kirigami.Action { + text: "Layer Options" + iconName: "qrc:///settings.png" + onTriggered: { + app.state = "options" + sidePanel.close() + app.pageStack.push("qrc:///Options.qml") + } + }, + Kirigami.Action { + text: "Routing" + iconName: "qrc:///material/directions.svg" + onTriggered: { + app.state = "route" + } + } + ] - // Theme settings. - projection: smallZoom ? MarbleItem.Spherical : MarbleItem.Mercator - mapThemeId: settings.value("MarbleMaps", "mapThemeId", "earth/vectorosm/vectorosm.dgml") - - // Visibility of layers/plugins. - showFrameRate: false - showAtmosphere: smallZoom - showCompass: false - showClouds: false - showCrosshairs: false - showGrid: smallZoom - showOverviewMap: false - showOtherPlaces: false - showScaleBar: false - showBackground: smallZoom - showPublicTransport: settings.value("MarbleMaps", "showPublicTransport", "false") === "true" - positionProvider: suspended ? "" : currentPositionProvider - keepScreenOn: !suspended && navigationManager.guidanceModeEnabled - showPositionMarker: false - animationViewContext: dialogAnimation.running - - placemarkDelegate: Image { - id: balloon - property int xPos: 0 - property int yPos: 0 - property real animationOffset: 0 - property var placemark: null - x: xPos - 0.5 * width - y: yPos - height - 30 * Screen.pixelDensity * animationOffset - opacity: 1.0 - animationOffset + Binding { + target: pageStack.currentItem + property: "map" + value: marbleMaps + when: app.state === "bookmarks" + } + } - Connections { - target: app - onSelectedPlacemarkChanged: balloonAnimation.restart() - } + pageStack.initialPage: page - NumberAnimation { - id: balloonAnimation - target: balloon - property: "animationOffset" - from: 1 - to: 0 - duration: 1000 - easing.type: Easing.OutBounce - } + Kirigami.Page { + id: page + padding: 0 + topPadding: 0 + leftPadding: 0 + rightPadding: 0 + bottomPadding: 0 + title: "Marble Maps" + Item { + id: mapItem + width: parent.width + height: dialogLoader.height === 0 ? parent.height - bottomMenu.height : parent.height - dialogLoader.height - bottomMenu.height - width: Screen.pixelDensity*6 - height: width - source: "qrc:///ic_place.png" - onPlacemarkChanged: { - app.selectedPlacemark = placemark - if (placemark) { - app.state = "place" - } else { - app.state = "none" - } - } - } + PinchArea { + id: pinchArea + anchors.fill: parent + enabled: true - onPositionAvailableChanged: { - updateIndicator(); - } - onPositionVisibleChanged: { - updateIndicator(); - } - onVisibleLatLonAltBoxChanged: { - !panningDetectionTimer.restart(); - updateIndicator(); - } - onCurrentPositionChanged: { - updateIndicator(); - } + onPinchStarted: marbleMaps.handlePinchStarted(pinch.center) + onPinchFinished: marbleMaps.handlePinchFinished(pinch.center) + onPinchUpdated: marbleMaps.handlePinchUpdated(pinch.center, pinch.scale); - onZoomChanged: { - zoomDetectionTimer.restart() - } + MarbleMaps { + id: marbleMaps - Component.onCompleted: { - setPluginSetting("coordinate-grid", "gridColor", "#999999"); - setPluginSetting("coordinate-grid", "tropicsColor", "#888888"); - setPluginSetting("coordinate-grid", "equatorColor", "#777777"); - setPluginSetting("coordinate-grid", "primaryLabels", "false"); - setPluginSetting("coordinate-grid", "secondaryLabels", "false"); - marbleMaps.loadSettings() - } - Component.onDestruction: marbleMaps.writeSettings() + property string currentPositionProvider: "QtPositioning" + property bool wlanOnly: false + property bool smallZoom : radius < 2 * Math.max(app.width, app.height) + + anchors.fill: parent + + visible: true + + // Theme settings. + projection: smallZoom ? MarbleItem.Spherical : MarbleItem.Mercator + mapThemeId: settings.value("MarbleMaps", "mapThemeId", "earth/vectorosm/vectorosm.dgml") + + // Visibility of layers/plugins. + showFrameRate: false + showAtmosphere: smallZoom + showCompass: false + showClouds: false + showCrosshairs: false + showGrid: smallZoom + showOverviewMap: false + showOtherPlaces: false + showScaleBar: false + showBackground: smallZoom + showPublicTransport: settings.value("MarbleMaps", "showPublicTransport", "false") === "true" + positionProvider: suspended ? "" : currentPositionProvider + keepScreenOn: !suspended && navigationManager.guidanceModeEnabled + showPositionMarker: false + + placemarkDelegate: Image { + id: balloon + property int xPos: 0 + property int yPos: 0 + property real animationOffset: 0 + property var placemark: null + x: xPos - 0.5 * width + y: yPos - height - 30 * Screen.pixelDensity * animationOffset + opacity: 1.0 - animationOffset + + Connections { + target: app + onSelectedPlacemarkChanged: balloonAnimation.restart() + } - Connections { - target: Qt.application - onStateChanged: { - if (Qt.application.state === Qt.ApplicationInactive || Qt.application.state === Qt.ApplicationSuspended) { - marbleMaps.writeSettings() + NumberAnimation { + id: balloonAnimation + target: balloon + property: "animationOffset" + from: 1 + to: 0 + duration: 1000 + easing.type: Easing.OutBounce + } + + width: Screen.pixelDensity*6 + height: width + source: "qrc:///ic_place.png" + onPlacemarkChanged: { + app.selectedPlacemark = placemark + if (placemark) { + app.state = "place" + } else { + app.state = "none" + } } } - } - function updateIndicator() { - if ( !positionVisible && positionAvailable ) { - zoomToPositionButton.updateIndicator(); + onPositionAvailableChanged: { + updateIndicator(); + } + onPositionVisibleChanged: { + updateIndicator(); + } + onVisibleLatLonAltBoxChanged: { + !panningDetectionTimer.restart(); + updateIndicator(); + } + onCurrentPositionChanged: { + updateIndicator(); } - } - RoutingManager { - id: routingManager - anchors.fill: parent - marbleItem: marbleMaps - visible: hasRoute - - function addToRoute() { - ensureRouteHasDeparture() - routingManager.addViaByPlacemarkAtIndex(routingManager.waypointCount(), selectedPlacemark) - routingManager.clearSearchResultPlacemarks() - selectedPlacemark = null - app.state = "route" + onZoomChanged: { + zoomDetectionTimer.restart() + } + + Component.onCompleted: { + setPluginSetting("coordinate-grid", "gridColor", "#999999"); + setPluginSetting("coordinate-grid", "tropicsColor", "#888888"); + setPluginSetting("coordinate-grid", "equatorColor", "#777777"); + setPluginSetting("coordinate-grid", "primaryLabels", "false"); + setPluginSetting("coordinate-grid", "secondaryLabels", "false"); + marbleMaps.loadSettings() } - function ensureRouteHasDeparture() { - if (routingManager.routeRequestModel.count === 0) { - if (marbleMaps.positionAvailable) { - routingManager.addViaByPlacemark(marbleMaps.currentPosition) + Component.onDestruction: marbleMaps.writeSettings() + + Connections { + target: Qt.application + onStateChanged: { + if (Qt.application.state === Qt.ApplicationInactive || Qt.application.state === Qt.ApplicationSuspended) { + marbleMaps.writeSettings() } } } + function updateIndicator() { + if ( !positionVisible && positionAvailable ) { + zoomToPositionButton.updateIndicator(); + } + } - } + RoutingManager { + id: routingManager + anchors.fill: parent + marbleItem: marbleMaps + visible: hasRoute + + /* + * I need a way to bind the profileSelector that now resides in the bottomMenu to the one in the routingManager. + * However logging this value shows that it doesn't get set so I'm unsure how to proceed. + * routingProfile : profileSelector.selectedProfile + */ + + function addToRoute() { + ensureRouteHasDeparture() + routingManager.addViaByPlacemarkAtIndex(routingManager.waypointCount(), selectedPlacemark) + routingManager.clearSearchResultPlacemarks() + selectedPlacemark = null + app.state = "route" + } + function ensureRouteHasDeparture() { + if (routingManager.routeRequestModel.count === 0) { + if (marbleMaps.positionAvailable) { + routingManager.addViaByPlacemark(marbleMaps.currentPosition) + } + } + } + } - Timer { - id: zoomDetectionTimer - interval: 1000 - } - Timer { - id: panningDetectionTimer - interval: 1000 - } + Timer { + id: zoomDetectionTimer + interval: 1000 + } + Timer { + id: panningDetectionTimer + interval: 1000 + } - PositionMarker { - id: positionMarker - x: navigationManager.snappedPositionMarkerScreenPosition.x - positionMarker.width / 2 - y: navigationManager.snappedPositionMarkerScreenPosition.y - positionMarker.height / 2 - angle: marbleMaps.angle - visible: marbleMaps.positionAvailable && marbleMaps.positionVisible - radius: navigationManager.screenAccuracy / 2 - showAccuracy: navigationManager.deviated - allowRadiusAnimation: !zoomDetectionTimer.running - allowPositionAnimation: !panningDetectionTimer.running - speed: marbleMaps.speed + PositionMarker { + id: positionMarker + x: navigationManager.snappedPositionMarkerScreenPosition.x - positionMarker.width / 2 + y: navigationManager.snappedPositionMarkerScreenPosition.y - positionMarker.height / 2 + angle: marbleMaps.angle + visible: marbleMaps.positionAvailable && marbleMaps.positionVisible + radius: navigationManager.screenAccuracy / 2 + showAccuracy: navigationManager.deviated + allowRadiusAnimation: !zoomDetectionTimer.running + allowPositionAnimation: !panningDetectionTimer.running + speed: marbleMaps.speed + + MouseArea { + anchors.fill: parent + onPressed: app.state = "position" + } + } MouseArea { anchors.fill: parent - onPressed: app.state = "position" + propagateComposedEvents: true + onPressed: { + marbleMaps.focus = true; + mouse.accepted = false; + } } } - MouseArea { - anchors.fill: parent - propagateComposedEvents: true - onPressed: { - marbleMaps.focus = true; - mouse.accepted = false; - } + NavigationManager { + id: navigationManager + width: parent.width + height: parent.height + visible: false + marbleItem: marbleMaps + hasRoute: routingManager.hasRoute } - - } - NavigationManager { - id: navigationManager - width: parent.width - height: parent.height - visible: false - marbleItem: marbleMaps - hasRoute: routingManager.hasRoute - } - } + BoxedText { + id: distanceIndicator + color: Kirigami.Theme.highlightColor + textColor: Kirigami.Theme.highlightedTextColor + text: qsTr("%1 km").arg(zoomToPositionButton.distance < 10 ? zoomToPositionButton.distance.toFixed(1) : zoomToPositionButton.distance.toFixed(0)) + anchors { + bottom: zoomToPositionButton.top + horizontalCenter: zoomToPositionButton.horizontalCenter + } - BoxedText { - id: distanceIndicator - text: qsTr("%1 km").arg(zoomToPositionButton.distance < 10 ? zoomToPositionButton.distance.toFixed(1) : zoomToPositionButton.distance.toFixed(0)) - anchors { - bottom: zoomToPositionButton.top - horizontalCenter: zoomToPositionButton.horizontalCenter + visible: marbleMaps.positionAvailable && !marbleMaps.positionVisible } - visible: marbleMaps.positionAvailable && !marbleMaps.positionVisible - } + PositionButton { + id: zoomToPositionButton + anchors { + right: parent.right + rightMargin: Screen.pixelDensity * 1 + bottom: mapItem.bottom + bottomMargin: 10 + } - PositionButton { - id: zoomToPositionButton - anchors { - right: parent.right - rightMargin: Screen.pixelDensity * 1 - bottom: routeEditorButton.top - bottomMargin: 10 - } + enabled: marbleMaps.positionAvailable - enabled: marbleMaps.positionAvailable + iconSource: marbleMaps.positionAvailable ? "qrc:///gps_fixed.png" : "qrc:///gps_not_fixed.png" - iconSource: marbleMaps.positionAvailable ? "qrc:///gps_fixed.png" : "qrc:///gps_not_fixed.png" + onClicked: marbleMaps.centerOnCurrentPosition() - onClicked: marbleMaps.centerOnCurrentPosition() + property real distance: 0 - property real distance: 0 + function updateIndicator() { + var point = marbleMaps.mapFromItem(zoomToPositionButton, diameter * 0.5, diameter * 0.5); + distance = 0.001 * marbleMaps.distanceFromPointToCurrentLocation(point); + angle = marbleMaps.angleFromPointToCurrentLocation(point); + } - function updateIndicator() { - var point = marbleMaps.mapFromItem(zoomToPositionButton, diameter * 0.5, diameter * 0.5); - distance = 0.001 * marbleMaps.distanceFromPointToCurrentLocation(point); - angle = marbleMaps.angleFromPointToCurrentLocation(point); + showDirection: marbleMaps.positionAvailable && !marbleMaps.positionVisible } - showDirection: marbleMaps.positionAvailable && !marbleMaps.positionVisible } - CircularButton { - id: routeEditorButton - - property string currentProfileIcon: "qrc:///material/directions-car.svg" + Row { + id: bottomMenu + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: dialogLoader.top + width: parent.width + height: bottomMenu.visible ? routeEditorButton.height + Screen.pixelDensity * 2 : 0 + anchors.topMargin: app.animatedMargin + visible: app.state === "place" || app.state === "route" + + onVisibleChanged: bottomMenuAnimation.start() + + NumberAnimation { + id: bottomMenuAnimation + target: bottomMenu + property: "y" + from: app.height - bottomMenu.height + to: 0 + duration: 500 + easing.type: Easing.InExpo + } - anchors { - bottom: parent.bottom - bottomMargin: Screen.pixelDensity * 4 - mapOffset - horizontalCenter: zoomToPositionButton.horizontalCenter + Item { + id: bottomMenuBackground + anchors.fill: parent + Rectangle { + color: Material.accent + anchors.fill : parent + } } - enabled: app.state !== "route" || routingManager.hasRoute + Row { + anchors.centerIn: parent + spacing: Kirigami.Units.gridUnit * 2 - onClicked: { - if (app.state === "route") { - app.state = "none" - navigationManager.visible = true - } else if (app.state === "place") { - app.state = "route" - routingManager.addToRoute() - } else { - app.state = "route" - navigationManager.visible = false + FlatButton { + id: routeEditorButton + property string currentProfileIcon: "qrc:///material/directions-car.svg" + height: Screen.pixelDensity * 6 + width: height + enabled: app.state !== "route" || routingManager.hasRoute + imageSource: "qrc:///material/directions.svg" + + onClicked: { + if (app.state === "route") { + app.state = "none" + navigationManager.visible = true + } else if (app.state === "place") { + app.state = "route" + routingManager.addToRoute() + } else { + app.state = "route" + navigationManager.visible = false + } + } + states: [ + State { + name: "" + PropertyChanges { target: routeEditorButton; imageSource: "qrc:///material/directions.svg"; } + }, + State { + name: "routingAction" + when: app.state === "route" + PropertyChanges { target: routeEditorButton; imageSource: "qrc:///material/navigation.svg"; } + }, + State { + name: "placeAction" + when: app.state === "place" + PropertyChanges { target: routeEditorButton; imageSource: "qrc:///material/directions.svg" } + } + ] } - } - iconSource: "qrc:///material/directions.svg"; - states: [ - State { - name: "" - PropertyChanges { target: routeEditorButton; iconSource: "qrc:///material/directions.svg"; } - }, - State { - name: "routingAction" - when: app.state === "route" - PropertyChanges { target: routeEditorButton; iconSource: "qrc:///material/navigation.svg"; } - }, - State { - name: "placeAction" - when: app.state === "place" - PropertyChanges { target: routeEditorButton; iconSource: currentProfileIcon } + FlatButton { + id: bookmarkButton + anchors.verticalCenter: parent.verticalCenter + height: Screen.pixelDensity * 6 + width: height + property bool bookmark: bookmarks.isBookmark(app.selectedPlacemark.longitude, app.selectedPlacemark.latitude) + enabled: app.state === "place" + visible: app.state === "place" + imageSource: bookmark ? "qrc:/material/star.svg" : "qrc:/material/star_border.svg" + onClicked: { + if (bookmarkButton.bookmark) { + bookmarks.removeBookmark(app.selectedPlacemark.longitude, app.selectedPlacemark.latitude) + } else { + bookmarks.addBookmark(app.selectedPlacemark, "Default") + } + bookmarkButton.bookmark = !bookmarkButton.bookmark + } } - ] + + ProfileSelectorMenu { + id: profileSelector + visible: app.state === "route" + } + } + } + + BorderImage { + anchors.top: mapItem.bottom + anchors.bottom: dialogLoader.bottom + anchors.right: parent.right + anchors.left: parent.left + anchors.margins: -14 + border { top: 14; left: 14; right: 14; bottom: 14 } + source: "qrc:///border_shadow.png" } - } - Search { - id: search - anchors.fill: parent - marbleQuickItem: marbleMaps - visible: !navigationManager.visible + Search { + id: search + anchors.fill: parent + marbleQuickItem: marbleMaps + visible: !navigationManager.visible - onItemSelected: { - if (routingManager) { - routingManager.addSearchResultAsPlacemark(suggestedPlacemark); + onItemSelected: { + if (routingManager) { + routingManager.addSearchResultAsPlacemark(suggestedPlacemark); + } + app.selectedPlacemark = suggestedPlacemark; + app.state = "place" } - app.selectedPlacemark = suggestedPlacemark; - app.state = "place" + onMenuButtonClicked: sidePanel.open() } - onMenuButtonClicked: drawer.open() - } - Loader { - id: dialogLoader + Loader { + id: dialogLoader + focus: true - focus: true + width: childrenRect.width + height : childrenRect.height - anchors { - left: parent.left - right: parent.right - top: parent.bottom - topMargin: app.animatedMargin - } + anchors { + left: parent.left + right: parent.right + top: parent.bottom + bottom: bottomMenu.top + topMargin: app.animatedMargin + bottomMargin: Kirigami.Units.gridUnits * 10 + } + + NumberAnimation { + id: loaderAnimation + target: dialogLoader.item + property: "y" + from: dialogLoader.height === 0 ? app.height : app.height - dialogLoader.item.height + to: 0 + duration: 500 + easing.type: Easing.InExpo + } + onLoaded: { + app.state != "none" ? loaderAnimation.running = true : loaderAnimation.running = false + if (app.state === "place") { + dialogLoader.item.map = marbleMaps + dialogLoader.item.placemark = app.selectedPlacemark + dialogLoader.item.showOsmTags = app.showOsmTags + dialogLoader.item.showAccessibility = sidePanel.showAccessibility + } else if (app.state === "route") { + item.routingManager = routingManager + item.routingProfile = routingManager.routingProfile + item.currentIndex = Qt.binding(function() { return app.currentWaypointIndex }) + } else if (app.state == "position") { + dialogLoader.item.map = marbleMaps + dialogLoader.item.navigationManager = navigationManager + } else if (app.state == "none"){ + dialogLoader.height = 0 + } - onLoaded: { - if (app.state === "place") { - dialogLoader.item.map = marbleMaps - dialogLoader.item.placemark = app.selectedPlacemark - dialogLoader.item.showOsmTags = app.showOsmTags - dialogLoader.item.showAccessibility = drawer.showAccessibility - } else if (app.state === "route") { - item.routingManager = routingManager - item.routingProfile = routingManager.routingProfile - item.currentIndex = Qt.binding(function() { return app.currentWaypointIndex }) - } else if (app.state == "position") { - dialogLoader.item.map = marbleMaps - dialogLoader.item.navigationManager = navigationManager - } + } + + Connections { + target: dialogLoader.item + onCurrentProfileIconChanged: routeEditorButton.currentProfileIcon = dialogLoader.item.currentProfileIcon + ignoreUnknownSignals: true + } } - Connections { - target: dialogLoader.item - onCurrentProfileIconChanged: routeEditorButton.currentProfileIcon = dialogLoader.item.currentProfileIcon - ignoreUnknownSignals: true + Rectangle { + width: parent.width + color: Kirigami.Theme.textColor + opacity: 0.4 + height: 1 + anchors.bottom: dialogLoader.top + } - } - BorderImage { - visible: app.state != "none" - anchors.fill: dialogLoader - anchors.margins: -14 - border { top: 14; left: 14; right: 14; bottom: 14 } - source: "qrc:///border_shadow.png" - } + Item { + id: stateTracker + state: "none" + + states: [ + State { + name: "none" + PropertyChanges { target: dialogLoader; source: "" } - SidePanel { - id: drawer - width: 0.67 * app.width - height: app.height - marbleMaps: marbleMaps + }, + State { + name: "position" + PropertyChanges { target: dialogLoader; source: "CurrentPosition.qml" } + }, + State { + name: "route" + PropertyChanges { target: dialogLoader; source: "RouteEditor.qml" } + }, + State { + name: "place" + PropertyChanges { target: dialogLoader; source: "PlacemarkDialog.qml" } + }, + State { + name: "about" + PropertyChanges { target: dialogLoader; source: "" } + PropertyChanges { + target: pageStack + interactive: true + } + }, + State { + name: "settings" + PropertyChanges { target: dialogLoader; source: "SettingsDialog.qml" } + }, + State { + name: "developer" + PropertyChanges { target: dialogLoader; source: "DeveloperDialog.qml" } + }, + State { + name: "bookmarks" + PropertyChanges { target: dialogLoader; source: "" } + PropertyChanges { + target: pageStack + interactive: false + } + }, + State { + name: "options" + PropertyChanges { target: dialogLoader; source: "" } + PropertyChanges { + target: pageStack + interactive: true + } + } - onAboutActionTriggered: { - app.state = "about" - dialogLoader.focus = true + ] } - } - BoxedText { - id: quitHelper - visible: false - text: qsTr("Press again to close.") - anchors.bottom: parent.bottom - anchors.bottomMargin: Screen.pixelDensity * 5 - anchors.horizontalCenter: parent.horizontalCenter - onVisibleChanged: { - if (visible) { - quitTimer.restart() + BoxedText { + id: quitHelper + visible: false + text: qsTr("Press again to close.") + anchors.bottom: parent.bottom + anchors.bottomMargin: Screen.pixelDensity * 5 + anchors.horizontalCenter: parent.horizontalCenter + onVisibleChanged: { + if (visible) { + quitTimer.restart() + } } - } - Timer { - id: quitTimer - interval: 3000; - running: false; - repeat: false - onTriggered: { - app.aboutToQuit = false - quitHelper.visible = false + Timer { + id: quitTimer + interval: 3000; + running: false; + repeat: false + onTriggered: { + app.aboutToQuit = false + quitHelper.visible = false + } } } - } - property bool aboutToQuit: false + Bookmarks { + id: bookmarks + map: marbleMaps - onClosing: { - if (app.aboutToQuit === true) { - close.accepted = true // we will quit - return - } else if (navigationManager.visible) { - navigationManager.visible = false - } else if (app.state !== "none") { - app.state = "none" - } else { - app.aboutToQuit = true - quitHelper.visible = true } - close.accepted = false - } - - Item { - id: stateTracker - - state: "none" - - states: [ - State { - name: "none" - PropertyChanges { target: dialogLoader; source: "" } - }, - State { - name: "position" - PropertyChanges { target: dialogLoader; source: "CurrentPosition.qml" } - }, - State { - name: "route" - PropertyChanges { target: dialogLoader; source: "RouteEditor.qml" } - }, - State { - name: "place" - PropertyChanges { target: dialogLoader; source: "PlacemarkDialog.qml" } - }, - State { - name: "about" - PropertyChanges { target: dialogLoader; source: "AboutDialog.qml" } - }, - State { - name: "settings" - PropertyChanges { target: dialogLoader; source: "SettingsDialog.qml" } - }, - State { - name: "developer" - PropertyChanges { target: dialogLoader; source: "DeveloperDialog.qml" } - } - ] } } diff --git a/src/apps/marble-maps/MarbleMaps.qrc b/src/apps/marble-maps/MarbleMaps.qrc --- a/src/apps/marble-maps/MarbleMaps.qrc +++ b/src/apps/marble-maps/MarbleMaps.qrc @@ -30,6 +30,8 @@ SidePanel.qml PublicTransport.qml OutdoorActivities.qml + BookmarkManager.qml + DragDropGridType.qml drawer.svg ../../../data/android/drawable-xxxhdpi/search.png ../../../data/android/drawable-xxxhdpi/ic_menu_black_48dp.png @@ -55,6 +57,7 @@ ../../../data/android/drawable-xxxhdpi/ic_place_via.png ../../../data/android/drawable-xxxhdpi/ic_add_black_48dp.png ../../../data/android/drawable-xxxhdpi/ic_settings_black_48dp.png + icons/marble-lineart-simplified-logo.svg material-icons/ic_local_gas_station_48px.svg material-icons/ic_open_in_browser_48px.svg material-icons/ic_volume_off_48px.svg @@ -81,6 +84,8 @@ material-icons/ic_star_24px.svg material-icons/ic_star_border_24px.svg material-icons/ic_label_48px.svg + material-icons/ic_drag_handle_black_48dp.png + material-icons/ic_phone_black_48px.svg konqi/konqi-app-dev.png konqi/konqi-dev-qt.png konqi/konqi-group.png @@ -88,6 +93,8 @@ konqi/konqi-books.png RouteProfileRadioButton.qml MarbleScrollBar.qml - material-icons/ic_phone_black_48px.svg + roboto/Roboto-Medium.ttf + qtquickcontrols2.conf + Options.qml diff --git a/src/apps/marble-maps/Options.qml b/src/apps/marble-maps/Options.qml --- a/src/apps/marble-maps/Options.qml +++ b/src/apps/marble-maps/Options.qml @@ -17,5 +17,70 @@ import org.kde.marble 0.20 Kirigami.Page { + id: optionsPage + padding: 0 + topPadding: 0 + leftPadding: 0 + rightPadding: 0 + bottomPadding: 0 + signal backTriggered() + + Item{ + id: root + anchors { + fill: parent + margins: Kirigami.Units.gridUnit + } + + Column { + anchors.fill: parent + spacing: 5 + + Label { + text: qsTr("

Layer Options

") + } + + Label { + text: qsTr("

Public Transport Layers

") + } + + Item{ + implicitHeight: publicTransportLoader.height + Kirigami.Units.gridUnit * 4 + width: parent.width + + Loader { + anchors.fill: parent + id: publicTransportLoader + source: "PublicTransport.qml" + + onLoaded: { + item.implicitWidth = parent.width + item.marbleMaps = marbleMaps + } + } + } + + Label { + topPadding: Kirigami.Units.gridUnit + text: qsTr("

Outdoor Activities Layers

") + } + + Item{ + implicitHeight: outdoorActivitiesLoader.height + Kirigami.Units.gridUnit * 6 + width: parent.width + + Loader { + anchors.fill: parent + id: outdoorActivitiesLoader + source: "OutdoorActivities.qml" + + onLoaded: { + item.implicitWidth = parent.width + item.marbleMaps = marbleMaps + } + } + } + } + } } diff --git a/src/apps/marble-maps/OutdoorActivities.qml b/src/apps/marble-maps/OutdoorActivities.qml --- a/src/apps/marble-maps/OutdoorActivities.qml +++ b/src/apps/marble-maps/OutdoorActivities.qml @@ -61,7 +61,7 @@ model: transportModel clip: true - spacing: Screen.pixelDensity * 2 + spacing: Screen.pixelDensity delegate: Row { CheckBox { @@ -71,7 +71,7 @@ checked: root.marbleMaps.isRelationTypeVisible(key) contentItem: Row { - spacing: Screen.pixelDensity * 1 + spacing: Screen.pixelDensity Item { height: parent.height diff --git a/src/apps/marble-maps/PlacemarkDialog.qml b/src/apps/marble-maps/PlacemarkDialog.qml --- a/src/apps/marble-maps/PlacemarkDialog.qml +++ b/src/apps/marble-maps/PlacemarkDialog.qml @@ -8,11 +8,12 @@ // Copyright 2015 Dennis Nienhüser // -import QtQuick 2.3 +import QtQuick 2.7 import QtQuick.Window 2.2 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 -import QtQuick.Dialogs 1.2 + +import org.kde.kirigami 2.0 as Kirigami import org.kde.marble 0.20 @@ -196,14 +197,23 @@ } } - Dialog { + Kirigami.OverlaySheet { id: routesDialog - title: qsTr("Routes") - RoutesItem { - id: routesItem - implicitWidth: parent.width - model: placemark === null ? undefined : placemark.routeRelationModel - onHighlightChanged: map.highlightRouteRelation(oid, enabled) + ColumnLayout { + property int implicitWidth: Units.gridUnit * 30 + id: columnLayout + Label{ + Layout.fillWidth: true + text: qsTr("

Routes

") + + } + RoutesItem { + id: routesItem + Layout.fillWidth: true + model: placemark === null ? undefined : placemark.routeRelationModel + onHighlightChanged: map.highlightRouteRelation(oid, enabled) + } + } } } diff --git a/src/apps/marble-maps/RouteProfileRadioButton.qml b/src/apps/marble-maps/RouteProfileRadioButton.qml --- a/src/apps/marble-maps/RouteProfileRadioButton.qml +++ b/src/apps/marble-maps/RouteProfileRadioButton.qml @@ -24,7 +24,7 @@ style: RadioButtonStyle { indicator: Rectangle { - color: control.checked ? palette.highlight : palette.base + color: control.checked ? palette.highlight : "transparent" width: image.width height: image.height + Screen.pixelDensity * 1 radius: Screen.pixelDensity * 1 diff --git a/src/apps/marble-maps/Search.qml b/src/apps/marble-maps/Search.qml --- a/src/apps/marble-maps/Search.qml +++ b/src/apps/marble-maps/Search.qml @@ -8,7 +8,7 @@ // Copyright 2015 Gábor Péterffy // -import QtQuick 2.3 +import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Window 2.2 @@ -73,10 +73,8 @@ Column { anchors.top: parent.top - anchors.topMargin: background.itemSpacing anchors.left: parent.left anchors.right: parent.right - anchors.margins: background.itemSpacing spacing: background.itemSpacing ListView { @@ -93,6 +91,9 @@ height: background.itemSpacing + Math.max(bookmarkIcon.height, bookmarkText.height) spacing: background.itemSpacing + leftPadding: 10 + rightPadding: 10 + Image { id: bookmarkIcon anchors.verticalCenter: parent.verticalCenter @@ -109,7 +110,7 @@ anchors.leftMargin: Screen.pixelDensity * 2 width: bookmarksView.width - bookmarksView.spacing - bookmarkIcon.width text: display - font.pointSize: 18 + font.pointSize: 14 color: palette.text elide: Text.ElideMiddle @@ -136,20 +137,29 @@ Row { visible: bookmarksView.model.count === 0 width: parent.width + anchors.left: parent.left + anchors.right: parent.right + spacing: Screen.pixelDensity * 2 + anchors.margins: Screen.pixelDensity * 2 Text { anchors.bottom: parent.bottom - width: 0.8 * parent.width - font.pointSize: 18 + leftPadding: 10 + bottomPadding: 3 + width: parent.width - Screen.pixelDensity * 2 - emptyImage.width + font.pointSize: 14 color: paletteDisabled.text text: qsTr("Your bookmarks will appear here.") + wrapMode: Text.WrapAtWordBoundaryOrAnywhere elide: Text.ElideRight } Image { + id: emptyImage anchors.bottom: parent.bottom - width: 0.2 * parent.width + width: Screen.pixelDensity* 10 + fillMode: Image.PreserveAspectFit source: "qrc:/konqi/books.png" } @@ -169,13 +179,11 @@ SearchField { id: searchField - width: parent.width - 2 * anchors.margins <= Screen.pixelDensity * 70 ? - parent.width - 2 * anchors.margins - : Screen.pixelDensity * 50 + width: parent.width anchors { top: parent.top left: parent.left - margins: Screen.pixelDensity * 3 + right: parent.right } completionModel: backend.completionModel onSearchRequested: backend.search(query) diff --git a/src/apps/marble-maps/SearchField.qml b/src/apps/marble-maps/SearchField.qml --- a/src/apps/marble-maps/SearchField.qml +++ b/src/apps/marble-maps/SearchField.qml @@ -74,7 +74,7 @@ anchors.right: parent.right placeholderText: qsTr("Search") - font.pointSize: 18 + font.pointSize: 16 textColor: palette.text inputMethodHints: Qt.ImhNoPredictiveText onAccepted: root.search(text) @@ -137,7 +137,6 @@ visible: !root.busy enabled: field.text !== "" imageSource: "qrc:///search.png" - onClicked: root.search(field.text) } } diff --git a/src/apps/marble-maps/SidePanel.qml b/src/apps/marble-maps/SidePanel.qml --- a/src/apps/marble-maps/SidePanel.qml +++ b/src/apps/marble-maps/SidePanel.qml @@ -12,6 +12,8 @@ import QtQuick.Controls 2.0 import QtQuick.Window 2.2 import QtQuick.Dialogs 1.2 +import org.kde.kirigami 2.0 as Kirigami + import org.kde.marble 0.20 Drawer { @@ -20,6 +22,7 @@ property var marbleMaps property alias showAccessibility: accessibilityAction.checked signal aboutActionTriggered() + signal bookmarkActionTriggered() Settings { id: settings @@ -31,7 +34,7 @@ } } - Column { + Column { id: drawerContent anchors.fill: parent spacing: Screen.pixelDensity * 2 @@ -111,9 +114,20 @@ root.aboutActionTriggered() } } + + + MenuIcon { + text: qsTr("Bookmarks") + anchors.leftMargin: Screen.pixelDensity * 2 + anchors.rightMargin: anchors.leftMargin + onTriggered: { + root.close() + root.bookmarkActionTriggered() + } + } } - Dialog { + Kirigami.Dialog { id: publicTransportDialog title: qsTr("Public Transport") @@ -126,7 +140,7 @@ } } - Dialog { + Kirigami.Dialog { id: outdoorActivitiesDialog title: qsTr("Outdoor Activities") diff --git a/src/apps/marble-maps/main.cpp b/src/apps/marble-maps/main.cpp --- a/src/apps/marble-maps/main.cpp +++ b/src/apps/marble-maps/main.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "declarative/MarbleDeclarativePlugin.h" #include @@ -96,6 +98,8 @@ int main(int argc, char ** argv) { QApplication app(argc, argv); + QFont newFont("Roboto", 15, QFont::Normal, false); + app.setFont(newFont); app.setApplicationName( "Marble Maps" ); app.setOrganizationName( "KDE" ); app.setOrganizationDomain( "kde.org" ); @@ -113,6 +117,9 @@ QQmlApplicationEngine engine; TextToSpeechClient * tts = new TextToSpeechClient(&engine); + engine.addImportPath("qmlmaterial/modules/"); + engine.addImportPath("qmlextras/modules/"); + engine.rootContext()->setContextProperty("textToSpeechClient", tts); engine.load(QUrl("qrc:/MainScreen.qml")); // @todo Ship translations and only fall back to english if no translations for the system locale are installed diff --git a/src/apps/marble-maps/package/deploy-marble-maps.json.in b/src/apps/marble-maps/package/deploy-marble-maps.json.in --- a/src/apps/marble-maps/package/deploy-marble-maps.json.in +++ b/src/apps/marble-maps/package/deploy-marble-maps.json.in @@ -12,5 +12,6 @@ "android-package": "@QT_ANDROID_APP_PACKAGE_NAME@", "android-app-name": "@QT_ANDROID_APP_NAME@", "android-extra-libs": "@QT_ANDROID_APP_EXTRA_LIBS@", + "android-extra-plugins": "@QT_ANDROID_APP_EXTRA_PLUGINS@", "android-package-source-directory": "@QT_ANDROID_APP_PACKAGE_SOURCE_ROOT@" } diff --git a/src/lib/marble/declarative/MarbleQuickItem.cpp b/src/lib/marble/declarative/MarbleQuickItem.cpp --- a/src/lib/marble/declarative/MarbleQuickItem.cpp +++ b/src/lib/marble/declarative/MarbleQuickItem.cpp @@ -231,7 +231,7 @@ for (AbstractFloatItem *item: d->m_map.floatItems()) { if (item->nameId() == QLatin1String("license")) { - item->setPosition(QPointF(5.0, -10.0)); + item->setPosition(QPointF(9.0, -10.0)); } else { item->hide(); }