From 884ef19631d4fed0fceebea28608df7515cf37d7 Mon Sep 17 00:00:00 2001 From: Philippe Renon Date: Fri, 17 Jul 2015 22:42:20 +0200 Subject: [PATCH] LP-29 osgearth integration : new quickwidgetproxy to easily switch between QQuickView and QQuickWidget --- ground/openpilotgcs/copydata.pro | 2 + .../src/libs/utils/quickwidgetproxy.cpp | 160 ++++++++++++++++++ .../src/libs/utils/quickwidgetproxy.h | 58 +++++++ ground/openpilotgcs/src/libs/utils/utils.pro | 2 + 4 files changed, 222 insertions(+) create mode 100644 ground/openpilotgcs/src/libs/utils/quickwidgetproxy.cpp create mode 100644 ground/openpilotgcs/src/libs/utils/quickwidgetproxy.h diff --git a/ground/openpilotgcs/copydata.pro b/ground/openpilotgcs/copydata.pro index eaf91ee08..e51d0d967 100644 --- a/ground/openpilotgcs/copydata.pro +++ b/ground/openpilotgcs/copydata.pro @@ -23,6 +23,7 @@ equals(copyqt, 1) { libQt5Multimedia.so.5 \ libQt5MultimediaWidgets.so.5 \ libQt5Quick.so.5 \ + libQt5QuickWidgets.so.5 \ libQt5Qml.so.5 \ libQt5DBus.so.5 \ libQt5QuickParticles.so.5 \ @@ -70,6 +71,7 @@ equals(copyqt, 1) { Qt5Multimedia$${DS}.dll \ Qt5MultimediaWidgets$${DS}.dll \ Qt5Quick$${DS}.dll \ + Qt5QuickWidgets$${DS}.dll \ Qt5Qml$${DS}.dll \ icuin53.dll \ icudt53.dll \ diff --git a/ground/openpilotgcs/src/libs/utils/quickwidgetproxy.cpp b/ground/openpilotgcs/src/libs/utils/quickwidgetproxy.cpp new file mode 100644 index 000000000..fbe01d19f --- /dev/null +++ b/ground/openpilotgcs/src/libs/utils/quickwidgetproxy.cpp @@ -0,0 +1,160 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 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 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "quickwidgetproxy.h" + +#include +#include +#include + +/* + * Note: QQuickWidget is an alternative to using QQuickView and QWidget::createWindowContainer(). + * The restrictions on stacking order do not apply, making QQuickWidget the more flexible alternative, + * behaving more like an ordinary widget. This comes at the expense of performance. + * Unlike QQuickWindow and QQuickView, QQuickWidget involves rendering into OpenGL framebuffer objects. + * This will naturally carry a minor performance hit. + * + * Note: Using QQuickWidget disables the threaded render loop on all platforms. + * This means that some of the benefits of threaded rendering, for example Animator classes + * and vsync driven animations, will not be available. + * + * Note: Avoid calling winId() on a QQuickWidget. This function triggers the creation of a native window, + * resulting in reduced performance and possibly rendering glitches. + * The entire purpose of QQuickWidget is to render Quick scenes without a separate native window, + * hence making it a native widget should always be avoided. + */ +QuickWidgetProxy::QuickWidgetProxy(QWidget *parent) : QObject(parent) +{ + m_widget = true; + + m_quickWidget = NULL; + + m_container = NULL; + m_quickView = NULL; + + if (m_widget) { + m_quickWidget = new QQuickWidget(parent); + m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + + void (QuickWidgetProxy::*f)(QQuickWidget::Status) = &QuickWidgetProxy::onStatusChanged; + connect(m_quickWidget, &QQuickWidget::statusChanged, this, f); + connect(m_quickWidget, &QQuickWidget::sceneGraphError, this, &QuickWidgetProxy::onSceneGraphError); + } else { + m_quickView = new QQuickView(); + m_quickView->setResizeMode(QQuickView::SizeRootObjectToView); + m_container = QWidget::createWindowContainer(m_quickView, parent); + m_container->setMinimumSize(64, 64); + m_container->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + void (QuickWidgetProxy::*f)(QQuickView::Status) = &QuickWidgetProxy::onStatusChanged; + connect(m_quickView, &QQuickView::statusChanged, this, f); + connect(m_quickView, &QQuickView::sceneGraphError, this, &QuickWidgetProxy::onSceneGraphError); + } +} + +QuickWidgetProxy::~QuickWidgetProxy() +{ + if (m_quickWidget) { + delete m_quickWidget; + } + if (m_quickView) { + delete m_quickView; + delete m_container; + } +} + +QWidget *QuickWidgetProxy::widget() +{ + if (m_widget) { + return m_quickWidget; + } else { + return m_container; + } +} + +QQmlEngine *QuickWidgetProxy::engine() const +{ + if (m_widget) { + return m_quickWidget->engine(); + } else { + return m_quickView->engine(); + } +} + +void QuickWidgetProxy::setSource(const QUrl &url) +{ + if (m_widget) { + m_quickWidget->setSource(url); + } else { + m_quickView->setSource(url); + } +} + +QList QuickWidgetProxy::errors() const +{ + if (m_widget) { + return m_quickWidget->errors(); + } else { + return m_quickView->errors(); + } +} + +void QuickWidgetProxy::onStatusChanged(QQuickWidget::Status status) +{ + switch (status) { + case QQuickWidget::Null: + qDebug() << "QuickWidgetProxy - status Null"; + break; + case QQuickWidget::Ready: + qDebug() << "QuickWidgetProxy - status Ready"; + break; + case QQuickWidget::Loading: + qDebug() << "QuickWidgetProxy - status Loading"; + break; + case QQuickWidget::Error: + qDebug() << "QuickWidgetProxy - status Error"; + foreach(const QQmlError &error, errors()) { + qWarning() << error.description(); + } + break; + } +} + +void QuickWidgetProxy::onStatusChanged(QQuickView::Status status) +{ + switch (status) { + case QQuickView::Null: + qDebug() << "QuickWidgetProxy - status Null"; + break; + case QQuickView::Ready: + qDebug() << "QuickWidgetProxy - status Ready"; + break; + case QQuickView::Loading: + qDebug() << "QuickWidgetProxy - status Loading"; + break; + case QQuickView::Error: + qDebug() << "QuickWidgetProxy - status Error"; + foreach(const QQmlError &error, errors()) { + qWarning() << error.description(); + } + break; + } +} + +void QuickWidgetProxy::onSceneGraphError(QQuickWindow::SceneGraphError error, const QString &message) +{ + qWarning() << QString("Scenegraph error %1: %2").arg(error).arg(message); +} diff --git a/ground/openpilotgcs/src/libs/utils/quickwidgetproxy.h b/ground/openpilotgcs/src/libs/utils/quickwidgetproxy.h new file mode 100644 index 000000000..cafa17074 --- /dev/null +++ b/ground/openpilotgcs/src/libs/utils/quickwidgetproxy.h @@ -0,0 +1,58 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 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 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef QUICKWIDGETPROXY_H_ +#define QUICKWIDGETPROXY_H_ + +#include "utils_global.h" + +#include +#include +#include + +class QQmlEngine; + +/* + * Very crude proxy that allows to switch between QQuickView and QQuickWindow are runtime + */ +class QTCREATOR_UTILS_EXPORT QuickWidgetProxy : public QObject { + Q_OBJECT + +public: + QuickWidgetProxy(QWidget *parent = 0); + virtual ~QuickWidgetProxy(); + + QWidget *widget(); + + void setSource(const QUrl &url); + QQmlEngine *engine() const; + QList errors() const; + +public slots: + void onStatusChanged(QQuickWidget::Status status); + void onStatusChanged(QQuickView::Status status); + void onSceneGraphError(QQuickWindow::SceneGraphError error, const QString &message); + +private: + bool m_widget; + + QQuickWidget *m_quickWidget; + + QWidget *m_container; + QQuickView *m_quickView; +}; + +#endif /* QUICKWIDGETPROXY_H_ */ diff --git a/ground/openpilotgcs/src/libs/utils/utils.pro b/ground/openpilotgcs/src/libs/utils/utils.pro index 5747b6858..43431571a 100644 --- a/ground/openpilotgcs/src/libs/utils/utils.pro +++ b/ground/openpilotgcs/src/libs/utils/utils.pro @@ -51,6 +51,7 @@ SOURCES += \ homelocationutil.cpp \ mytabbedstackwidget.cpp \ mytabwidget.cpp \ + quickwidgetproxy.cpp \ cachedsvgitem.cpp \ svgimageprovider.cpp \ hostosinfo.cpp \ @@ -114,6 +115,7 @@ HEADERS += \ homelocationutil.h \ mytabbedstackwidget.h \ mytabwidget.h \ + quickwidgetproxy.h \ cachedsvgitem.h \ svgimageprovider.h \ hostosinfo.h \