diff --git a/src/map-quick/IndoorMap.qml b/src/map-quick/IndoorMap.qml index 4d653de..edfde5e 100644 --- a/src/map-quick/IndoorMap.qml +++ b/src/map-quick/IndoorMap.qml @@ -1,94 +1,97 @@ /* Copyright (C) 2020 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.12 import QtQuick.Layouts 1.12 import org.kde.kosmindoormap 1.0 import QtQuick.Controls 2.12 as QQC2 /** QML item for displaying a train station or airport map. */ Item { id: mapRoot + /** Access to map loading status and progress. */ property alias mapLoader: map.loader + /** Path to a MapCSS style sheet used for rendering the map. */ + property alias styleSheet: map.styleSheet MapItemImpl { id: map anchors.fill: parent } Flickable { id: flickable boundsBehavior: Flickable.StopAtBounds contentX: map.view.panX contentY: map.view.panY contentWidth: map.view.panWidth contentHeight: map.view.panHeight anchors.fill: parent Rectangle { color: "red"; width: 100; height: 100 } Rectangle { color: "green"; width: 100; height: 100; x: flickable.contentWidth - width; y: flickable.contentHeight - height; } onContentXChanged: { if (moving) { map.view.panTopLeft(flickable.contentX, flickable.contentY); map.update(); } } onContentYChanged: { if (moving) { map.view.panTopLeft(flickable.contentX, flickable.contentY); map.update(); } } QQC2.ScrollBar.vertical: QQC2.ScrollBar {} QQC2.ScrollBar.horizontal: QQC2.ScrollBar {} } Connections { target: map.view onTransformationChanged: { console.log(map.view.panY, flickable.contentY); flickable.contentX = map.view.panX; flickable.contentY = map.view.panY; } } MouseArea { acceptedButtons: Qt.NoButton anchors.fill: parent onWheel: { if (wheel.angleDelta.y > 0) { map.view.zoomIn(Qt.point(wheel.x, wheel.y)); } else { map.view.zoomOut(Qt.point(wheel.x, wheel.y)); } wheel.accepted = true; map.update(); } } PinchArea { anchors.fill: parent } QQC2.BusyIndicator { anchors.centerIn: parent running: map.loader.isLoading } } diff --git a/src/map-quick/mapitem.cpp b/src/map-quick/mapitem.cpp index a9331c1..420862a 100644 --- a/src/map-quick/mapitem.cpp +++ b/src/map-quick/mapitem.cpp @@ -1,77 +1,94 @@ /* Copyright (C) 2020 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapitem.h" #include #include #include using namespace KOSMIndoorMap; MapItem::MapItem(QQuickItem *parent) : QQuickPaintedItem(parent) , m_loader(new MapLoader(this)) , m_view(new View(this)) { connect(m_loader, &MapLoader::done, this, &MapItem::loaderDone); m_view->setScreenSize({100, 100}); // FIXME this breaks view when done too late! m_view->setLevel(0); m_controller.setView(m_view); - - // TODO error handling, make style path a property - MapCSSParser cssParser; - m_style = cssParser.parse(QStringLiteral(":/org.kde.kosmindoormap/assets/css/breeze-light.mapcss")); } MapItem::~MapItem() = default; void MapItem::paint(QPainter *painter) { m_controller.updateScene(m_sg); m_renderer.setPainter(painter); m_renderer.render(m_sg, m_view); } MapLoader* MapItem::loader() const { return m_loader; } View* MapItem::view() const { return m_view; } +QString MapItem::styleSheetName() const +{ + return m_styleSheetName; +} + +void MapItem::setStylesheetName(const QString &styleSheet) +{ + if (m_styleSheetName == styleSheet) { + return; + } + m_styleSheetName = styleSheet; + + MapCSSParser cssParser; + m_style = cssParser.parse(m_styleSheetName); + m_style.compile(m_data.dataSet()); + m_controller.setStyleSheet(&m_style); + + emit styleSheetChanged(); + update(); +} + void MapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry); m_view->setScreenSize(newGeometry.size().toSize()); qDebug() << newGeometry << m_view->zoomLevel(); } void MapItem::loaderDone() { m_data = m_loader->takeData(); m_view->setSceneBoundingBox(m_data.boundingBox()); m_controller.setDataSet(&m_data); m_style.compile(m_data.dataSet()); m_controller.setStyleSheet(&m_style); update(); } diff --git a/src/map-quick/mapitem.h b/src/map-quick/mapitem.h index c5dd5a2..f163fee 100644 --- a/src/map-quick/mapitem.h +++ b/src/map-quick/mapitem.h @@ -1,67 +1,75 @@ /* Copyright (C) 2020 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KOSMINDOORMAP_MAPITEM_H #define KOSMINDOORMAP_MAPITEM_H #include #include #include #include #include #include #include #include namespace KOSMIndoorMap { /** Map renderer for the IndoorMap QML item. * @internal Do not use directly! */ class MapItem : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(KOSMIndoorMap::MapLoader* loader READ loader CONSTANT) Q_PROPERTY(KOSMIndoorMap::View* view READ view CONSTANT) + Q_PROPERTY(QString styleSheet READ styleSheetName WRITE setStylesheetName NOTIFY styleSheetChanged) public: explicit MapItem(QQuickItem *parent = nullptr); ~MapItem(); void paint(QPainter *painter) override; MapLoader* loader() const; View* view() const; + QString styleSheetName() const; + void setStylesheetName(const QString &styleSheet); + +Q_SIGNALS: + void styleSheetChanged(); + protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; private: void loaderDone(); MapLoader *m_loader = nullptr; MapData m_data; SceneGraph m_sg; View *m_view = nullptr; + QString m_styleSheetName; MapCSSStyle m_style; SceneController m_controller; PainterRenderer m_renderer; }; } #endif // KOSMINDOORMAP_MAPITEM_H diff --git a/tests/indoormap.qml b/tests/indoormap.qml index 27f2292..abe9020 100644 --- a/tests/indoormap.qml +++ b/tests/indoormap.qml @@ -1,39 +1,57 @@ /* Copyright (C) 2020 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.12 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.1 as QQC2 import org.kde.kirigami 2.0 as Kirigami import org.kde.kosmindoormap 1.0 Kirigami.ApplicationWindow { title: "OSM Indoor Map QML Test" pageStack.initialPage: Kirigami.Page { title: "Indoor Map View" + actions { + contextualActions: [ + Kirigami.Action { + text: "Light Style" + onTriggered: map.styleSheet = ":/org.kde.kosmindoormap/assets/css/breeze-light.mapcss" + }, + Kirigami.Action { + text: "Dark Style" + onTriggered: map.styleSheet = ":/org.kde.kosmindoormap/assets/css/breeze-dark.mapcss" + }, + Kirigami.Action { + text: "Diagnostic View" + onTriggered: map.styleSheet = ":/org.kde.kosmindoormap/assets/css/diagnostic.mapcss" + } + ] + } + IndoorMap { id: map anchors.fill: parent + styleSheet: ":/org.kde.kosmindoormap/assets/css/breeze-light.mapcss" Component.onCompleted: { map.mapLoader.loadForCoordinate(49.44572, 11.08196); } } } }