diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ce2049..aaf884c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,17 +1,20 @@ add_subdirectory(graphql) add_subdirectory(osm) add_subdirectory(wikidata) if (NOT CMAKE_CROSSCOMPILING) add_subdirectory(generator) endif() add_subdirectory(lib) if (BISON_FOUND AND FLEX_FOUND) add_subdirectory(map) endif() +if (TARGET KOSMIndoorMap AND TARGET Qt5::Quick) + add_subdirectory(map-quick) +endif() add_subdirectory(qmlplugin) if (TARGET Qt5::Quick) add_subdirectory(quick) endif() if (NOT CROSS_COMPILING) add_subdirectory(tools) endif() diff --git a/src/map-quick/CMakeLists.txt b/src/map-quick/CMakeLists.txt new file mode 100644 index 0000000..eb7706d --- /dev/null +++ b/src/map-quick/CMakeLists.txt @@ -0,0 +1,23 @@ +set(kosmindoormapquickplugin_SRC + kosmindoormapquickplugin.cpp + mapitem.cpp +) +set(kosmindoormapquickplugin_qml + qmldir + IndoorMap.qml +) + +add_library(kosmindoormapquickplugin ${kosmindoormapquickplugin_SRC}) +target_link_libraries(kosmindoormapquickplugin + Qt5::Quick + KOSMIndoorMap +) + +# make examples work without installation +set_property(TARGET kosmindoormapquickplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/kosmindoormap) +foreach(f IN LISTS kosmindoormapquickplugin_qml) + file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/${f} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/kosmindoormap/${f} SYMBOLIC) +endforeach() + +# install(TARGETS kosmindoormapquickplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/kosmindoormap) +# install(FILES ${kosmindoormapquickplugin_qml} ${quick_SRC} DESTINATION ${QML_INSTALL_DIR}/org/kde/kosmindoormap) diff --git a/src/map-quick/IndoorMap.qml b/src/map-quick/IndoorMap.qml new file mode 100644 index 0000000..4d653de --- /dev/null +++ b/src/map-quick/IndoorMap.qml @@ -0,0 +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 . +*/ + +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 + + property alias mapLoader: map.loader + + 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/kosmindoormapquickplugin.cpp b/src/map-quick/kosmindoormapquickplugin.cpp new file mode 100644 index 0000000..2662b4b --- /dev/null +++ b/src/map-quick/kosmindoormapquickplugin.cpp @@ -0,0 +1,27 @@ +/* + 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 "kosmindoormapquickplugin.h" +#include "mapitem.h" + +using namespace KOSMIndoorMap; + +void KOSMIndoorMapQuickPlugin::registerTypes(const char *uri) +{ + Q_UNUSED(uri); + qmlRegisterType("org.kde.kosmindoormap", 1, 0, "MapItemImpl"); +} diff --git a/src/map-quick/kosmindoormapquickplugin.h b/src/map-quick/kosmindoormapquickplugin.h new file mode 100644 index 0000000..0b36f43 --- /dev/null +++ b/src/map-quick/kosmindoormapquickplugin.h @@ -0,0 +1,32 @@ +/* + 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 KOSMINDOORMAPQUICKPLUGIN_H +#define KOSMINDOORMAPQUICKPLUGIN_H + +#include + +/** Qt Quick integration plugin for KOSMIndoorMap. */ +class KOSMIndoorMapQuickPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") +public: + void registerTypes(const char *uri) override; +}; + +#endif // KOSMINDOORMAPQUICKPLUGIN_H diff --git a/src/map-quick/mapitem.cpp b/src/map-quick/mapitem.cpp new file mode 100644 index 0000000..049cd16 --- /dev/null +++ b/src/map-quick/mapitem.cpp @@ -0,0 +1,77 @@ +/* + 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_renderer.setPainter(painter); + m_renderer.render(m_sg, m_view); +} + +MapLoader* MapItem::loader() const +{ + return m_loader; +} + +View* MapItem::view() const +{ + return m_view; +} + +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); + m_controller.updateScene(m_sg); + update(); +} diff --git a/src/map-quick/mapitem.h b/src/map-quick/mapitem.h new file mode 100644 index 0000000..c5dd5a2 --- /dev/null +++ b/src/map-quick/mapitem.h @@ -0,0 +1,67 @@ +/* + 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) +public: + explicit MapItem(QQuickItem *parent = nullptr); + ~MapItem(); + + void paint(QPainter *painter) override; + + MapLoader* loader() const; + View* view() const; + +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; + MapCSSStyle m_style; + SceneController m_controller; + PainterRenderer m_renderer; +}; + +} + +#endif // KOSMINDOORMAP_MAPITEM_H diff --git a/src/map-quick/qmldir b/src/map-quick/qmldir new file mode 100644 index 0000000..8598ca8 --- /dev/null +++ b/src/map-quick/qmldir @@ -0,0 +1,4 @@ +module org.kde.kosmindoormap +plugin kosmindoormapquickplugin +classname KOSMIndoorMapQuickPlugin +IndoorMap 1.0 IndoorMap.qml diff --git a/tests/indoormap.qml b/tests/indoormap.qml new file mode 100644 index 0000000..27f2292 --- /dev/null +++ b/tests/indoormap.qml @@ -0,0 +1,39 @@ +/* + 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" + + IndoorMap { + id: map + anchors.fill: parent + + Component.onCompleted: { + map.mapLoader.loadForCoordinate(49.44572, 11.08196); + } + } + } +}