summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wildemann <metalstrolch@users.noreply.github.com>2017-05-05 05:04:00 +0200
committerPierre GRANDIN <pgrandin@users.noreply.github.com>2017-05-04 20:04:00 -0700
commit585305d57ce8e1c5a3db978086102604f55cb006 (patch)
tree729b8e85769c9122f0a84e241d369373408e744a
parenta5b607303d83e2b46950e2aef63eb5787f3098fb (diff)
downloadnavit-585305d57ce8e1c5a3db978086102604f55cb006.tar.gz
Add Qt5 qml gui skeleton (#236)R7461
* Initial parts of qt5 qml graphics based on graphics/qt5_qml * Qt5 QML gui: working handover The hand over of the QML engine between the graphics and the gui part is working now. The gui can load it's own QML component and embed the navit widget inside other QML code. * Remove unneeded moc include * Fix: Apply coding style * Fix:extern "C" the navit includes in graphics qt5 Seems the navit includes are not fully "c++" aware, so extern "C" them in the c++ parts.
-rwxr-xr-xCMakeLists.txt4
-rw-r--r--navit/graphics/qt5/QNavitQuick.cpp5
-rw-r--r--navit/graphics/qt5/QNavitWidget.cpp5
-rw-r--r--navit/graphics/qt5/event_qt5.cpp5
-rw-r--r--navit/graphics/qt5/graphics_qt5.cpp27
-rw-r--r--navit/graphics/qt5/graphics_qt5.h4
-rw-r--r--navit/graphics/qt5/graphics_qt5.qml17
-rw-r--r--navit/graphics/qt5/graphics_qt5.qrc1
-rw-r--r--navit/graphics/qt5/loader.qml20
-rw-r--r--navit/gui/qt5_qml/CMakeLists.txt7
-rw-r--r--navit/gui/qt5_qml/gui_qt5_qml.cpp254
-rw-r--r--navit/gui/qt5_qml/gui_qt5_qml.qml23
-rw-r--r--navit/gui/qt5_qml/gui_qt5_qml.qrc5
13 files changed, 355 insertions, 22 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e4e5ed7aa..8804c0184 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,6 +96,7 @@ add_module(graphics/egl "Required library not found" FALSE)
add_module(graphics/qt_qpainter "Qt libraries not found" FALSE)
add_module(graphics/qt5 "Qt5 libraries not found" FALSE)
add_module(gui/qml "Qt Declarative not found" FALSE)
+add_module(gui/qt5_qml "Qt5 Declarative not found" FALSE)
add_module(gui/gtk "GTK libs not found" FALSE)
add_module(vehicle/gpsd "gpsd lib not found" FALSE)
add_module(vehicle/gypsy "gypsy lib not found" FALSE)
@@ -339,6 +340,9 @@ if (Qt5Widgets_FOUND OR Qt5Quick_FOUND)
if(USE_QML)
set(Qt5_ADDITIONAL_LIBRARIES ${Qt5_ADDITIONAL_LIBRARIES} ${Qt5Quick_LIBRARIES})
endif()
+ set_with_reason(gui/qt5_qml "Qt5 found" TRUE
+ ${Qt5Quick_LIBRARIES})
+
endif()
set_with_reason(graphics/qt5 "Qt5 found" TRUE
${Qt5_ADDITIONAL_LIBRARIES}
diff --git a/navit/graphics/qt5/QNavitQuick.cpp b/navit/graphics/qt5/QNavitQuick.cpp
index d2664be27..798415f2c 100644
--- a/navit/graphics/qt5/QNavitQuick.cpp
+++ b/navit/graphics/qt5/QNavitQuick.cpp
@@ -18,10 +18,12 @@
*/
#include <glib.h>
-#include "config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+extern"C" {
+#include "config.h"
+
#include "item.h"
#include "point.h"
#include "graphics.h"
@@ -32,6 +34,7 @@
#include "window.h"
#include "callback.h"
#include "keys.h"
+}
#if defined(WINDOWS) || defined(WIN32) || defined (HAVE_API_WIN32_CE)
#include <windows.h>
#endif
diff --git a/navit/graphics/qt5/QNavitWidget.cpp b/navit/graphics/qt5/QNavitWidget.cpp
index d58f835a6..20b1d852f 100644
--- a/navit/graphics/qt5/QNavitWidget.cpp
+++ b/navit/graphics/qt5/QNavitWidget.cpp
@@ -18,10 +18,12 @@
*/
#include <glib.h>
-#include "config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+extern "C" {
+#include "config.h"
+
#include "item.h"
#include "point.h"
#include "graphics.h"
@@ -32,6 +34,7 @@
#include "window.h"
#include "callback.h"
#include "keys.h"
+}
#if defined(WINDOWS) || defined(WIN32) || defined (HAVE_API_WIN32_CE)
#include <windows.h>
#endif
diff --git a/navit/graphics/qt5/event_qt5.cpp b/navit/graphics/qt5/event_qt5.cpp
index 9cea3d921..729e3903b 100644
--- a/navit/graphics/qt5/event_qt5.cpp
+++ b/navit/graphics/qt5/event_qt5.cpp
@@ -20,7 +20,10 @@
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
+
+extern "C" {
#include "config.h"
+
#include "navit/point.h"
#include "navit/item.h"
#include "navit/graphics.h"
@@ -32,6 +35,8 @@
#include "navit/window.h"
#include "navit/keys.h"
#include "navit/navit.h"
+}
+
#if defined(WINDOWS) || defined(WIN32) || defined (HAVE_API_WIN32_CE)
#include <windows.h>
#endif
diff --git a/navit/graphics/qt5/graphics_qt5.cpp b/navit/graphics/qt5/graphics_qt5.cpp
index 37fda3d66..f03ad36e0 100644
--- a/navit/graphics/qt5/graphics_qt5.cpp
+++ b/navit/graphics/qt5/graphics_qt5.cpp
@@ -18,10 +18,12 @@
*/
#include <glib.h>
-#include "config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+extern "C" {
+#include "config.h"
+
#include "item.h"
#include "point.h"
#include "graphics.h"
@@ -31,9 +33,8 @@
#include "debug.h"
#include "window.h"
#include "callback.h"
-#if defined(WINDOWS) || defined(WIN32) || defined (HAVE_API_WIN32_CE)
-#include <windows.h>
-#endif
+}
+
#include "graphics_qt5.h"
#include "event_qt5.h"
#include <QGuiApplication>
@@ -55,6 +56,9 @@
#include <QApplication>
#include "QNavitWidget.h"
#endif
+#if defined(WINDOWS) || defined(WIN32) || defined (HAVE_API_WIN32_CE)
+#include <windows.h>
+#endif
#if USE_QML
GraphicsPriv::GraphicsPriv(struct graphics_priv * gp)
@@ -665,6 +669,10 @@ get_data(struct graphics_priv *this_priv, char const *type)
resize_callback(this_priv, this_priv->pixmap->width(),this_priv->pixmap->height());
return win;
}
+ if (strcmp(type, "engine") == 0) {
+ dbg(lvl_debug, "Hand over QQmlApplicationEngine\n");
+ return(this_priv->engine);
+ }
return NULL;
}
@@ -893,6 +901,7 @@ graphics_qt5_new(struct navit *nav, struct graphics_methods *meth, struct attr *
graphics_priv->y = 0;
graphics_priv->disable = 0;
#if USE_QML
+ graphics_priv->engine = NULL;
graphics_priv->window = NULL;
graphics_priv->GPriv = NULL;
if(use_qml)
@@ -901,15 +910,15 @@ graphics_qt5_new(struct navit *nav, struct graphics_methods *meth, struct attr *
qmlRegisterType<QNavitQuick>("com.navit.graphics_qt5", 1, 0, "QNavitQuick");
/* get our qml application from embedded resources. May be replaced by the
* QtQuick gui component if enabled */
- QQmlApplicationEngine * engine = new QQmlApplicationEngine();
- if(engine != NULL)
+ graphics_priv->engine = new QQmlApplicationEngine();
+ if(graphics_priv->engine != NULL)
{
graphics_priv->GPriv = new GraphicsPriv(graphics_priv);
- QQmlContext *context = engine->rootContext();
+ QQmlContext *context = graphics_priv->engine->rootContext();
context->setContextProperty("graphics_qt5_context", graphics_priv->GPriv);
- engine->load(QUrl("qrc:///graphics_qt5.qml"));
+ graphics_priv->engine->load(QUrl("qrc:///loader.qml"));
/* Get the engine's root window (for resizing) */
- QObject *toplevel = engine->rootObjects().value(0);
+ QObject *toplevel = graphics_priv->engine->rootObjects().value(0);
graphics_priv->window = qobject_cast<QQuickWindow *> (toplevel);
}
}
diff --git a/navit/graphics/qt5/graphics_qt5.h b/navit/graphics/qt5/graphics_qt5.h
index 2e3f7b85e..fad818773 100644
--- a/navit/graphics/qt5/graphics_qt5.h
+++ b/navit/graphics/qt5/graphics_qt5.h
@@ -16,6 +16,7 @@
#include <QPen>
#include <QBrush>
#if USE_QML
+#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QObject>
#endif
@@ -57,7 +58,8 @@ signals:
struct graphics_priv {
#if USE_QML
- GraphicsPriv * GPriv;
+ QQmlApplicationEngine * engine;
+ GraphicsPriv * GPriv;
QQuickWindow * window;
#endif
#if USE_QWIDGET
diff --git a/navit/graphics/qt5/graphics_qt5.qml b/navit/graphics/qt5/graphics_qt5.qml
index a797c8eb9..5f6056b26 100644
--- a/navit/graphics/qt5/graphics_qt5.qml
+++ b/navit/graphics/qt5/graphics_qt5.qml
@@ -2,14 +2,11 @@ import com.navit.graphics_qt5 1.0
import QtQuick 2.2
import QtQuick.Window 2.0
-Window {
- width: 200; height: 200
- QNavitQuick {
- id: navit1
- anchors.fill: parent
- focus: true
- Component.onCompleted: {
- navit1.setGraphicContext(graphics_qt5_context)
- }
- }
+QNavitQuick {
+ id: navit1
+ anchors.fill: parent
+ focus: true
+ Component.onCompleted: {
+ navit1.setGraphicContext(graphics_qt5_context)
+ }
}
diff --git a/navit/graphics/qt5/graphics_qt5.qrc b/navit/graphics/qt5/graphics_qt5.qrc
index 4c82492ee..6a161f621 100644
--- a/navit/graphics/qt5/graphics_qt5.qrc
+++ b/navit/graphics/qt5/graphics_qt5.qrc
@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
+ <file>loader.qml</file>
<file>graphics_qt5.qml</file>
</qresource>
</RCC>
diff --git a/navit/graphics/qt5/loader.qml b/navit/graphics/qt5/loader.qml
new file mode 100644
index 000000000..6901c2c6f
--- /dev/null
+++ b/navit/graphics/qt5/loader.qml
@@ -0,0 +1,20 @@
+import com.navit.graphics_qt5 1.0
+import QtQuick 2.2
+import QtQuick.Window 2.0
+
+Window {
+ width: 200; height: 200
+
+ Loader {
+ id: navit_loader
+ focus: true
+ source: "graphics_qt5.qml"
+ anchors.fill: parent
+ objectName: "navit_loader"
+ }
+
+ Item {
+ id: root_item
+ anchors.fill: parent
+ }
+}
diff --git a/navit/gui/qt5_qml/CMakeLists.txt b/navit/gui/qt5_qml/CMakeLists.txt
new file mode 100644
index 000000000..a191c9d69
--- /dev/null
+++ b/navit/gui/qt5_qml/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Find includes in corresponding build directories
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+# Instruct CMake to run moc automatically when needed.
+set(CMAKE_AUTOMOC ON)
+
+qt5_add_resources(GUI_QT5_QML_QRC "gui_qt5_qml.qrc")
+module_add_library(gui_qt5_qml gui_qt5_qml.cpp ${GUI_QT5_QML_QRC})
diff --git a/navit/gui/qt5_qml/gui_qt5_qml.cpp b/navit/gui/qt5_qml/gui_qt5_qml.cpp
new file mode 100644
index 000000000..a8689843f
--- /dev/null
+++ b/navit/gui/qt5_qml/gui_qt5_qml.cpp
@@ -0,0 +1,254 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2010 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+// style with: clang-format -style=WebKit -i *
+
+#include <QQmlApplicationEngine>
+#include <glib.h>
+
+extern "C" {
+#include "item.h" /* needs to be first, as attr.h depends on it */
+
+#include "attr.h"
+#include "bookmarks.h"
+#include "callback.h"
+#include "color.h"
+#include "command.h"
+#include "config.h"
+#include "coord.h"
+#include "coord.h"
+#include "country.h"
+#include "debug.h"
+#include "event.h"
+
+#include "point.h" /* needs to be before graphics.h */
+
+#include "graphics.h"
+#include "gui.h"
+#include "keys.h"
+#include "map.h"
+#include "mapset.h"
+#include "navit.h"
+#include "plugin.h"
+#include "route.h"
+#include "search.h"
+#include "track.h"
+#include "transform.h"
+#include "vehicle.h"
+#include "xmlconfig.h"
+
+#include "layout.h"
+}
+
+struct gui_priv {
+ /* navit internal handle */
+ struct navit* nav;
+ /* gui handle */
+ struct gui* gui;
+
+ /* attributes given to us */
+ struct attr attributes;
+
+ /* list of callbacks to navit */
+ struct callback_list* callbacks;
+ /* own callbacks *
+ * TODO: Why do we need them as members? */
+ struct callback* button_cb;
+ struct callback* motion_cb;
+ struct callback* resize_cb;
+ struct callback* keypress_cb;
+ struct callback* window_closed_cb;
+
+ /* current graphics */
+ struct graphics* gra;
+ /* root window */
+ struct window* win;
+ /* navit root widget dimesnions*/
+ int w;
+ int h;
+
+ /* Qt application instance */
+ QQmlApplicationEngine* engine;
+ QObject* loader; /* Loader QML component to load our QML parts to the QML engine */
+
+ /* configuration */
+ int menu_on_map_click;
+};
+
+static void gui_qt5_qml_button(void* data, int pressed, int button, struct point* p)
+{
+ struct gui_priv* gui_priv = (struct gui_priv*)data;
+
+ /* check if navit wants to handle this */
+ if (!navit_handle_button(gui_priv->nav, pressed, button, p, NULL)) {
+ dbg(lvl_debug, "navit has handled button\n");
+ return;
+ }
+ dbg(lvl_debug, "enter %d %d\n", pressed, button);
+
+ /* check if user requested menu */
+ if (button == 1 && gui_priv->menu_on_map_click) {
+ dbg(lvl_debug, "navit wants us to enter menu\n");
+ /*TODO: want to emit a signal somewhere? */
+ }
+}
+
+static void gui_qt5_qml_motion(void* data, struct point* p)
+{
+ struct gui_priv* gui_priv = (struct gui_priv*)data;
+ dbg(lvl_debug, "enter (%d, %d)\n", p->x, p->y);
+ /* forward this to navit */
+ navit_handle_motion(gui_priv->nav, p);
+}
+
+static void gui_qt5_qml_resize(void* data, int w, int h)
+{
+ struct gui_priv* gui_priv = (struct gui_priv*)data;
+ dbg(lvl_debug, "enter\n");
+ /* forward this to navit */
+ navit_handle_resize(gui_priv->nav, w, h);
+}
+
+static int gui_qt5_qml_set_graphics(struct gui_priv* gui_priv, struct graphics* gra)
+{
+ struct transformation* trans;
+ dbg(lvl_debug, "enter\n");
+
+ /* get navit transition */
+ trans = navit_get_trans(gui_priv->nav);
+
+ /* Tell navit to ignore events from graphics. We will hook the ones being supported.*/
+ navit_ignore_graphics_events(gui_priv->nav, 1);
+
+ /* remeber graphics */
+ gui_priv->gra = gra;
+
+ /* hook button callback */
+ gui_priv->button_cb = callback_new_attr_1(callback_cast(gui_qt5_qml_button), attr_button, gui_priv);
+ graphics_add_callback(gra, gui_priv->button_cb);
+
+ /* hook motion callback */
+ gui_priv->motion_cb = callback_new_attr_1(callback_cast(gui_qt5_qml_motion), attr_motion, gui_priv);
+ graphics_add_callback(gra, gui_priv->motion_cb);
+
+ /* hook resize callback. Will be called imediately!*/
+ gui_priv->resize_cb = callback_new_attr_1(callback_cast(gui_qt5_qml_resize), attr_resize, gui_priv);
+ graphics_add_callback(gra, gui_priv->resize_cb);
+
+ /* get main navit window */
+ gui_priv->win = (struct window*)graphics_get_data(gra, "window");
+ if (!gui_priv->win) {
+ dbg(lvl_error, "failed to obtain window from graphics plugin, cannot set graphics\n");
+ return 1;
+ }
+
+ /* expect to have qt5 graphics. So get the qml engine prepared by graphics */
+ gui_priv->engine = (QQmlApplicationEngine*)graphics_get_data(gra, "engine");
+ if (gui_priv->engine == NULL) {
+ dbg(lvl_error, "Graphics doesn't seem to be qt5, or doesn't have QML. Cannot set graphics\n");
+ return 1;
+ }
+
+ /* find the loader component */
+ gui_priv->loader = gui_priv->engine->rootObjects().value(0)->findChild<QObject*>("navit_loader");
+ if (gui_priv->loader != NULL) {
+ dbg(lvl_debug, "navit_loader found\n");
+ /* load our root window into the loader component */
+ gui_priv->loader->setProperty("source", "qrc:///gui_qt5_qml.qml");
+ }
+
+ transform_get_size(trans, &gui_priv->w, &gui_priv->h);
+ dbg(lvl_debug, "navit provided geometry: (%d, %d)\n", gui_priv->w, gui_priv->h);
+
+ /* Was resize callback already issued? */
+ // if (navit_get_ready(gui_priv->nav) & 2)
+ // gui_internal_setup(this);
+
+ /* allow navit to draw */
+ navit_draw(gui_priv->nav);
+ return 0;
+}
+
+static int
+gui_qt5_qml_get_attr(struct gui_priv* gui_priv, enum attr_type type, struct attr* attr)
+{
+ dbg(lvl_debug, "enter\n");
+ return 1;
+}
+
+static int
+gui_qt5_qml_set_attr(struct gui_priv* gui_priv, struct attr* attr)
+{
+ dbg(lvl_debug, "enter\n");
+ return 1;
+}
+
+struct gui_methods gui_qt5_qml_methods = {
+ NULL,
+ NULL,
+ gui_qt5_qml_set_graphics,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ gui_qt5_qml_get_attr,
+ NULL,
+ gui_qt5_qml_set_attr,
+};
+
+static struct gui_priv* gui_qt5_qml_new(struct navit* nav, struct gui_methods* meth, struct attr** attrs, struct gui* gui)
+{
+ struct gui_priv* gui_priv;
+ struct attr* attr;
+
+ dbg(lvl_debug, "enter\n");
+
+ /* tell navit our methods */
+ *meth = gui_qt5_qml_methods;
+
+ /* allocate gui private structure */
+ gui_priv = g_new0(struct gui_priv, 1);
+
+ /* default config */
+ gui_priv->menu_on_map_click = 1;
+
+ /* read config */
+ if ((attr = attr_search(attrs, NULL, attr_menu_on_map_click)))
+ gui_priv->menu_on_map_click = attr->u.num;
+
+ /* remember navit internal handle */
+ gui_priv->nav = nav;
+ /* remember our gui handle */
+ gui_priv->gui = gui;
+
+ /* remember the attributes given to us */
+ gui_priv->attributes.type = attr_gui;
+ gui_priv->attributes.u.gui = gui;
+
+ /* create new callbacks */
+ gui_priv->callbacks = callback_list_new();
+
+ /* return self */
+ return gui_priv;
+}
+
+void plugin_init(void)
+{
+ Q_INIT_RESOURCE(gui_qt5_qml);
+ plugin_register_category_gui("qt5_qml", gui_qt5_qml_new);
+}
diff --git a/navit/gui/qt5_qml/gui_qt5_qml.qml b/navit/gui/qt5_qml/gui_qt5_qml.qml
new file mode 100644
index 000000000..679013319
--- /dev/null
+++ b/navit/gui/qt5_qml/gui_qt5_qml.qml
@@ -0,0 +1,23 @@
+import com.navit.graphics_qt5 1.0
+import QtQuick 2.2
+import QtQuick.Window 2.0
+
+Rectangle {
+ width: 200
+ height: 100
+ color: "red"
+
+ Text {
+ anchors.centerIn: parent
+ text: "Hello, World!"
+ }
+ QNavitQuick {
+ id: navit1
+ width: 300
+ height: 300
+ focus: true
+ Component.onCompleted: {
+ navit1.setGraphicContext(graphics_qt5_context)
+ }
+ }
+}
diff --git a/navit/gui/qt5_qml/gui_qt5_qml.qrc b/navit/gui/qt5_qml/gui_qt5_qml.qrc
new file mode 100644
index 000000000..51fa8af88
--- /dev/null
+++ b/navit/gui/qt5_qml/gui_qt5_qml.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>gui_qt5_qml.qml</file>
+ </qresource>
+</RCC>