From f95bd8bc1bd43ffc2322535d129346a6b727a52b Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 23 Jul 2012 17:19:24 +1000 Subject: [PATCH] Initial implementation of QML based PFD widget It uses the same pfd.svg file as original PFD widget; depends on osgearth for terrain rendering --- .../pfd/default/AltitudeScale.qml | 83 +++++ .../share/openpilotgcs/pfd/default/Pfd.qml | 120 +++++++ .../pfd/default/PfdIndicators.qml | 70 ++++ .../openpilotgcs/pfd/default/SpeedScale.qml | 91 +++++ .../share/openpilotgcs/pfd/default/srtm.earth | 26 ++ .../openpilotgcs/pfd/default/yahoo_srtm.earth | 26 ++ .../src/plugins/coreplugin/OpenPilotGCS.xml | 24 ++ .../src/plugins/pfdqml/PfdQml.pluginspec | 12 + .../src/plugins/pfdqml/osgearth.cpp | 311 ++++++++++++++++++ .../src/plugins/pfdqml/osgearth.h | 117 +++++++ .../src/plugins/pfdqml/pfdqml.pro | 35 ++ .../plugins/pfdqml/pfdqml_dependencies.pri | 1 + .../src/plugins/pfdqml/pfdqmlgadget.cpp | 44 +++ .../src/plugins/pfdqml/pfdqmlgadget.h | 45 +++ .../pfdqml/pfdqmlgadgetconfiguration.cpp | 67 ++++ .../pfdqml/pfdqmlgadgetconfiguration.h | 48 +++ .../plugins/pfdqml/pfdqmlgadgetfactory.cpp | 49 +++ .../src/plugins/pfdqml/pfdqmlgadgetfactory.h | 41 +++ .../pfdqml/pfdqmlgadgetoptionspage.cpp | 77 +++++ .../plugins/pfdqml/pfdqmlgadgetoptionspage.h | 54 +++ .../plugins/pfdqml/pfdqmlgadgetoptionspage.ui | 135 ++++++++ .../src/plugins/pfdqml/pfdqmlgadgetwidget.cpp | 106 ++++++ .../src/plugins/pfdqml/pfdqmlgadgetwidget.h | 51 +++ .../src/plugins/pfdqml/pfdqmlplugin.cpp | 55 ++++ .../src/plugins/pfdqml/pfdqmlplugin.h | 36 ++ ground/openpilotgcs/src/plugins/plugins.pro | 7 +- 26 files changed, 1730 insertions(+), 1 deletion(-) create mode 100644 ground/openpilotgcs/share/openpilotgcs/pfd/default/AltitudeScale.qml create mode 100644 ground/openpilotgcs/share/openpilotgcs/pfd/default/Pfd.qml create mode 100644 ground/openpilotgcs/share/openpilotgcs/pfd/default/PfdIndicators.qml create mode 100644 ground/openpilotgcs/share/openpilotgcs/pfd/default/SpeedScale.qml create mode 100644 ground/openpilotgcs/share/openpilotgcs/pfd/default/srtm.earth create mode 100644 ground/openpilotgcs/share/openpilotgcs/pfd/default/yahoo_srtm.earth create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/PfdQml.pluginspec create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/osgearth.cpp create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/osgearth.h create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqml.pro create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqml_dependencies.pri create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.cpp create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.h create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.cpp create mode 100644 ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.h diff --git a/ground/openpilotgcs/share/openpilotgcs/pfd/default/AltitudeScale.qml b/ground/openpilotgcs/share/openpilotgcs/pfd/default/AltitudeScale.qml new file mode 100644 index 000000000..6e5b608f7 --- /dev/null +++ b/ground/openpilotgcs/share/openpilotgcs/pfd/default/AltitudeScale.qml @@ -0,0 +1,83 @@ +import Qt 4.7 + +Item { + id: sceneItem + property variant sourceSize + + Image { + id: altitude_bg + source: "image://svg/pfd.svg!altitude-bg" + sourceSize: sceneItem.sourceSize + clip: true + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "altitude-bg") + + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + width: scaledBounds.width * sceneItem.width + height: scaledBounds.height * sceneItem.height + + Image { + id: altitude_scale + + source: "image://svg/pfd.svg!altitude-scale" + sourceSize: sceneItem.sourceSize + + anchors.verticalCenter: parent.verticalCenter + // The altitude scale represents 30 meters, + // move it in 0..5m range + anchors.verticalCenterOffset: -height/30 * (PositionActual.Down-Math.floor(PositionActual.Down/5)*5) + anchors.left: parent.left + + property int topNumber: 15-Math.floor(PositionActual.Down/5)*5 + + // Altitude numbers + Column { + Repeater { + model: 7 + Item { + height: altitude_scale.height / 6 + width: altitude_bg.width + + Text { + text: altitude_scale.topNumber - index*5 + color: "white" + font.pixelSize: parent.height / 4 + font.family: "Arial" + + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.top + } + } + } + } + } + } + + + Image { + id: altitude_window + clip: true + + source: "image://svg/pfd.svg!altitude-window" + sourceSize: sceneItem.sourceSize + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "altitude-window") + + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + width: scaledBounds.width * sceneItem.width + height: scaledBounds.height * sceneItem.height + + Text { + id: altitude_text + text: Math.floor(-PositionActual.Down).toFixed() + color: "white" + font { + family: "Arial" + pixelSize: parent.height * 0.6 + } + anchors.centerIn: parent + } + } +} diff --git a/ground/openpilotgcs/share/openpilotgcs/pfd/default/Pfd.qml b/ground/openpilotgcs/share/openpilotgcs/pfd/default/Pfd.qml new file mode 100644 index 000000000..517aa5b6a --- /dev/null +++ b/ground/openpilotgcs/share/openpilotgcs/pfd/default/Pfd.qml @@ -0,0 +1,120 @@ +import Qt 4.7 +import "." +import org.OpenPilot 1.0 +//import "/home/dima/work/RC/OsgEarthQml-build-desktop-Qt_4_8_1_in_PATH__System__Debug" + +Rectangle { + color: "#666666" + + Image { + id: background + source: "image://svg/pfd.svg!background" + + fillMode: Image.PreserveAspectFit + anchors.fill: parent + + sourceSize.width: width + sourceSize.height: height + + Item { + id: sceneItem + width: parent.paintedWidth + height: parent.paintedHeight + anchors.centerIn: parent + clip: true + + Image { + id: world + source: "image://svg/pfd.svg!world" + sourceSize: background.sourceSize + smooth: true + visible: !qmlWidget.terrainEnabled + + transform: [ + Translate { + id: pitchTranslate + x: (world.parent.width - world.width)/2 + y: (world.parent.height - world.height)/2 + AttitudeActual.Pitch*world.parent.height/94 + }, + Rotation { + angle: -AttitudeActual.Roll + origin.x : world.parent.width/2 + origin.y : world.parent.height/2 + } + ] + } + + OsgEarth { + id: earthView + + anchors.fill: parent + sceneFile: qmlWidget.earthFile + visible: qmlWidget.terrainEnabled + + fieldOfView: 90 + + yaw: AttitudeActual.Yaw + pitch: AttitudeActual.Pitch + roll: AttitudeActual.Roll + + + latitude: -27.935474 + longitude: 153.187147 + altitude: 3000 + //altitude: PositionActual.Down + } + + Image { + id: rollscale + source: "image://svg/pfd.svg!rollscale" + sourceSize: background.sourceSize + smooth: true + + transformOrigin: Item.Center + rotation: -AttitudeActual.Roll + } + + Image { + id: foreground + source: "image://svg/pfd.svg!foreground" + sourceSize: background.sourceSize + anchors.centerIn: parent + } + + Image { + id: compass + source: "image://svg/pfd.svg!compass" + sourceSize: background.sourceSize + clip: true + + y: 12 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: compass_band + source: "image://svg/pfd.svg!compass-band" + sourceSize: background.sourceSize + + anchors.centerIn: parent + //the band is 540 degrees wide + anchors.horizontalCenterOffset: -1*AttitudeActual.Yaw/540*width + } + } + + SpeedScale { + anchors.fill: parent + sourceSize: background.sourceSize + } + + AltitudeScale { + anchors.fill: parent + sourceSize: background.sourceSize + } + + PfdIndicators { + anchors.fill: parent + sourceSize: background.sourceSize + } + } + } +} diff --git a/ground/openpilotgcs/share/openpilotgcs/pfd/default/PfdIndicators.qml b/ground/openpilotgcs/share/openpilotgcs/pfd/default/PfdIndicators.qml new file mode 100644 index 000000000..d520dcf00 --- /dev/null +++ b/ground/openpilotgcs/share/openpilotgcs/pfd/default/PfdIndicators.qml @@ -0,0 +1,70 @@ +import Qt 4.7 + +Item { + id: sceneItem + property variant sourceSize + + //telemetry status arrow + Image { + id: telemetry_status + source: "image://svg/pfd.svg!gcstelemetry-"+statusName + sourceSize: sceneItem.sourceSize + + property string statusName : ["Disconnected","HandshakeReq","HandshakeAck","Connected"][GCSTelemetryStats.Status] + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "gcstelemetry-Disconnected") + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + width: scaledBounds.width * sceneItem.width + height: scaledBounds.height * sceneItem.height + } + + //telemetry rate text + Text { + id: telemetry_rate + text: GCSTelemetryStats.TxDataRate.toFixed()+"/"+GCSTelemetryStats.RxDataRate.toFixed() + color: "white" + font.family: "Arial" + font.pixelSize: telemetry_status.height * 0.75 + + anchors.top: telemetry_status.bottom + anchors.horizontalCenter: telemetry_status.horizontalCenter + } + + Text { + id: gps_text + text: "GPS: " + GPSPosition.Satellites + "\nPDP: " + GPSPosition.PDOP + color: "white" + font.family: "Arial" + font.pixelSize: telemetry_status.height * 0.75 + + visible: GPSPosition.Satellites > 0 + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "gps-txt") + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + } + + Text { + id: battery_text + + text: FlightBatteryState.Voltage.toFixed(2)+" V\n" + + FlightBatteryState.Current.toFixed(2)+" A\n" + + FlightBatteryState.ConsumedEnergy.toFixed()+" mAh" + + + color: "white" + font.family: "Arial" + + //I think it should be pixel size, + //but making it more consistent with C++ version instead + font.pointSize: scaledBounds.height * sceneItem.height + + visible: FlightBatteryState.Voltage > 0 || FlightBatteryState.Current > 0 + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "battery-txt") + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + + } +} diff --git a/ground/openpilotgcs/share/openpilotgcs/pfd/default/SpeedScale.qml b/ground/openpilotgcs/share/openpilotgcs/pfd/default/SpeedScale.qml new file mode 100644 index 000000000..ddc82b571 --- /dev/null +++ b/ground/openpilotgcs/share/openpilotgcs/pfd/default/SpeedScale.qml @@ -0,0 +1,91 @@ +import Qt 4.7 + +Item { + id: sceneItem + property variant sourceSize + property real groundSpeed : 3.6 * Math.sqrt(Math.pow(VelocityActual.North,2)+ + Math.pow(VelocityActual.East,2)) + + Image { + id: speed_bg + source: "image://svg/pfd.svg!speed-bg" + sourceSize: sceneItem.sourceSize + clip: true + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "speed-bg") + + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + width: scaledBounds.width * sceneItem.width + height: scaledBounds.height * sceneItem.height + + Image { + id: speed_scale + + source: "image://svg/pfd.svg!speed-scale" + sourceSize: sceneItem.sourceSize + + anchors.verticalCenter: parent.verticalCenter + // The speed scale represents 30 meters, + // move it in 0..5m range + anchors.verticalCenterOffset: height/30 * (sceneItem.groundSpeed-Math.floor(sceneItem.groundSpeed/5)*5) + anchors.right: parent.right + + property int topNumber: Math.floor(sceneItem.groundSpeed/5)*5+15 + + // speed numbers + Column { + width: speed_bg.width + anchors.right: speed_scale.right + + Repeater { + model: 7 + Item { + height: speed_scale.height / 6 + width: speed_bg.width + + Text { + //don't show negative numbers + text: speed_scale.topNumber - index*5 + color: "white" + visible: speed_scale.topNumber - index*5 >= 0 + + font.pixelSize: parent.height / 4 + font.family: "Arial" + + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.top + } + } + } + } + } + } + + + Image { + id: speed_window + clip: true + + source: "image://svg/pfd.svg!speed-window" + sourceSize: sceneItem.sourceSize + + property variant scaledBounds: svgRenderer.scaledElementBounds("pfd.svg", "speed-window") + + x: scaledBounds.x * sceneItem.width + y: scaledBounds.y * sceneItem.height + width: scaledBounds.width * sceneItem.width + height: scaledBounds.height * sceneItem.height + + Text { + id: speed_text + text: Math.round(sceneItem.groundSpeed).toFixed() + color: "white" + font { + family: "Arial" + pixelSize: parent.height * 0.6 + } + anchors.centerIn: parent + } + } +} diff --git a/ground/openpilotgcs/share/openpilotgcs/pfd/default/srtm.earth b/ground/openpilotgcs/share/openpilotgcs/pfd/default/srtm.earth new file mode 100644 index 000000000..bd17c7eb0 --- /dev/null +++ b/ground/openpilotgcs/share/openpilotgcs/pfd/default/srtm.earth @@ -0,0 +1,26 @@ + + + + + + http://demo.pelicanmapping.com/rmweb/data/bluemarble-tms/tms.xml + + + + http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml + + + + true + + 1 + + + + + diff --git a/ground/openpilotgcs/share/openpilotgcs/pfd/default/yahoo_srtm.earth b/ground/openpilotgcs/share/openpilotgcs/pfd/default/yahoo_srtm.earth new file mode 100644 index 000000000..1033290b5 --- /dev/null +++ b/ground/openpilotgcs/share/openpilotgcs/pfd/default/yahoo_srtm.earth @@ -0,0 +1,26 @@ + + + + + + satellite + + + + http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml + + + + false + + 2 + + + + + diff --git a/ground/openpilotgcs/src/plugins/coreplugin/OpenPilotGCS.xml b/ground/openpilotgcs/src/plugins/coreplugin/OpenPilotGCS.xml index d61dba982..ac8ac26cc 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/OpenPilotGCS.xml +++ b/ground/openpilotgcs/src/plugins/coreplugin/OpenPilotGCS.xml @@ -1691,6 +1691,30 @@ + + + + false + 0.0.0 + + + false + %%DATAPATH%%pfd/default/Pfd.qml + %%DATAPATH%%pfd/default/srtm.earth + + + + + false + 0.0.0 + + + true + %%DATAPATH%%pfd/default/Pfd.qml + %%DATAPATH%%pfd/default/srtm.earth + + + diff --git a/ground/openpilotgcs/src/plugins/pfdqml/PfdQml.pluginspec b/ground/openpilotgcs/src/plugins/pfdqml/PfdQml.pluginspec new file mode 100644 index 000000000..563bacefd --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/PfdQml.pluginspec @@ -0,0 +1,12 @@ + + The OpenPilot Project + (C) 2010 Edouard Lafargue + (C) 2012 Dmytro Poplavskiy + The GNU Public License (GPL) Version 3 + QML based PFD widget + http://www.openpilot.org + + + + + diff --git a/ground/openpilotgcs/src/plugins/pfdqml/osgearth.cpp b/ground/openpilotgcs/src/plugins/pfdqml/osgearth.cpp new file mode 100644 index 000000000..b4e8ac53e --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/osgearth.cpp @@ -0,0 +1,311 @@ +/* + * 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 "osgearth.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +OsgEarthItem::OsgEarthItem(QDeclarativeItem *parent): + QDeclarativeItem(parent), + m_fbo(0), + m_currentSize(640, 480), + m_roll(0.0), + m_pitch(0.0), + m_yaw(0.0), + m_latitude(-28.5), + m_longitude(153.0), + m_altitude(400.0), + m_fieldOfView(90.0), + m_sceneFile(QLatin1String("/usr/share/osgearth/maps/srtm.earth")), + m_cameraDirty(false) +{ + setSize(m_currentSize); + setFlag(ItemHasNoContents, false); +} + +OsgEarthItem::~OsgEarthItem() +{ +} + +void OsgEarthItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_UNUSED(oldGeometry); + Q_UNUSED(newGeometry); + + //Dynamic gyometry changes are not supported yet, + //terrain is rendered to fixed geompetry and scalled for now + + /* + qDebug() << Q_FUNC_INFO << newGeometry; + + int w = qRound(newGeometry.width()); + int h = qRound(newGeometry.height()); + + if (m_currentSize != QSize(w,h) && m_gw.get()) { + m_currentSize = QSize(w,h); + + m_gw->getEventQueue()->windowResize(0,0,w,h); + m_gw->resized(0,0,w,h); + + osg::Camera *camera = m_viewer->getCamera(); + camera->setViewport(new osg::Viewport(0,0,w,h)); + camera->setProjectionMatrixAsPerspective(m_fieldOfView, qreal(w)/h, 1.0f, 10000.0f); + } + */ +} + +void OsgEarthItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *style, QWidget *widget) +{ + Q_UNUSED(painter); + Q_UNUSED(style); + QGLWidget *glWidget = qobject_cast(widget); + + if (!m_glWidget) { + //make a shared gl widget to avoid + //osg rendering to mess with qpainter state + m_glWidget = new QGLWidget(widget, glWidget); + m_glWidget.data()->setAttribute(Qt::WA_PaintOutsidePaintEvent); + } + + if (!m_viewer.get()) + QMetaObject::invokeMethod(this, "initScene", Qt::QueuedConnection); + + if (glWidget && m_fbo) + glWidget->drawTexture(boundingRect(), m_fbo->texture()); +} + +void OsgEarthItem::markCameraDirty() +{ + m_cameraDirty = true; + QMetaObject::invokeMethod(this, "updateFBO", Qt::QueuedConnection); +} + +void OsgEarthItem::updateFBO() +{ + if (!m_cameraDirty || !m_viewer.get() || m_glWidget.isNull()) + return; + + m_cameraDirty = false; + m_glWidget.data()->makeCurrent(); + + if (m_fbo && m_fbo->size() != m_currentSize) { + delete m_fbo; + m_fbo = 0; + } + + if (!m_fbo) { + m_fbo = new QGLFramebufferObject(m_currentSize, QGLFramebufferObject::CombinedDepthStencil); + QPainter p(m_fbo); + p.fillRect(0,0,m_currentSize.width(), m_currentSize.height(), Qt::gray); + } + + //To find a camera view matrix, find placer matrixes for two points + //onr at requested coords and another latitude shifted by 0.01 deg + osgEarth::Util::ObjectPlacer placer(m_viewer->getSceneData()); + + osg::Matrixd positionMatrix; + placer.createPlacerMatrix(m_latitude, m_longitude, m_altitude, positionMatrix); + osg::Matrixd positionMatrix2; + placer.createPlacerMatrix(m_latitude+0.01, m_longitude, m_altitude, positionMatrix2); + + osg::Vec3d eye(0.0f, 0.0f, 0.0f); + osg::Vec3d viewVector(0.0f, 0.0f, 0.0f); + osg::Vec3d upVector(0.0f, 0.0f, 1.0f); + + eye = positionMatrix.preMult(eye); + upVector = positionMatrix.preMult(upVector); + upVector.normalize(); + viewVector = positionMatrix2.preMult(viewVector) - eye; + viewVector.normalize(); + viewVector *= 10.0; + + //TODO: clarify the correct rotation order, + //currently assuming yaw, pitch, roll + osg::Quat q; + q.makeRotate(-m_yaw*M_PI/180.0, upVector); + upVector = q * upVector; + viewVector = q * viewVector; + + osg::Vec3d side = viewVector ^ upVector; + q.makeRotate(m_pitch*M_PI/180.0, side); + upVector = q * upVector; + viewVector = q * viewVector; + + q.makeRotate(m_roll*M_PI/180.0, viewVector); + upVector = q * upVector; + viewVector = q * viewVector; + + osg::Vec3d center = eye + viewVector; + +// qDebug() << "e " << eye.x() << eye.y() << eye.z(); +// qDebug() << "c " << center.x() << center.y() << center.z(); +// qDebug() << "up" << upVector.x() << upVector.y() << upVector.z(); + + m_viewer->getCamera()->setViewMatrixAsLookAt(osg::Vec3d(eye.x(), eye.y(), eye.z()), + osg::Vec3d(center.x(), center.y(), center.z()), + osg::Vec3d(upVector.x(), upVector.y(), upVector.z())); + + { + QPainter fboPainter(m_fbo); + fboPainter.beginNativePainting(); + m_viewer->frame(); + fboPainter.endNativePainting(); + } + m_glWidget.data()->doneCurrent(); + + update(); +} + +void OsgEarthItem::setRoll(qreal arg) +{ + if (!qFuzzyCompare(m_roll, arg)) { + m_roll = arg; + markCameraDirty(); + emit rollChanged(arg); + } +} + +void OsgEarthItem::setPitch(qreal arg) +{ + if (!qFuzzyCompare(m_pitch, arg)) { + m_pitch = arg; + markCameraDirty(); + emit pitchChanged(arg); + } +} + +void OsgEarthItem::setYaw(qreal arg) +{ + if (!qFuzzyCompare(m_yaw, arg)) { + m_yaw = arg; + markCameraDirty(); + emit yawChanged(arg); + } +} + +void OsgEarthItem::setLatitude(double arg) +{ + //not sure qFuzzyCompare is accurate enough for geo coordinates + if (m_latitude != arg) { + m_latitude = arg; + emit latitudeChanged(arg); + } +} + +void OsgEarthItem::setLongitude(double arg) +{ + if (m_longitude != arg) { + m_longitude = arg; + emit longitudeChanged(arg); + } +} + +void OsgEarthItem::setAltitude(double arg) +{ + if (!qFuzzyCompare(m_altitude,arg)) { + m_altitude = arg; + emit altitudeChanged(arg); + } +} + +//! Camera vertical field of view in degrees +void OsgEarthItem::setFieldOfView(qreal arg) +{ + if (!qFuzzyCompare(m_fieldOfView,arg)) { + m_fieldOfView = arg; + emit fieldOfViewChanged(arg); + + if (m_viewer.get()) { + m_viewer->getCamera()->setProjectionMatrixAsPerspective( + m_fieldOfView, + qreal(m_currentSize.width())/m_currentSize.height(), + 1.0f, 10000.0f); + } + + markCameraDirty(); + } +} + +void OsgEarthItem::setSceneFile(QString arg) +{ + if (m_sceneFile != arg) { + m_sceneFile = arg; + emit sceneFileChanged(arg); + } +} + + +void OsgEarthItem::initScene() +{ + if (m_viewer.get()) + return; + + int w = m_currentSize.width(); + int h = m_currentSize.height(); + + QString sceneFile = m_sceneFile; + + //try to resolve the relative scene file name: + if (!QFileInfo(sceneFile).exists()) { + QDeclarativeView *view = qobject_cast(scene()->views().first()); + + if (view) { + QUrl baseUrl = view->engine()->baseUrl(); + sceneFile = baseUrl.resolved(sceneFile).toLocalFile(); + } + } + + m_model = osgDB::readNodeFile(sceneFile.toStdString()); + + m_gw = new osgViewer::GraphicsWindowEmbedded(0,0,w,h); + + m_viewer = new osgViewer::Viewer(); + m_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); + m_viewer->setSceneData(m_model); + m_viewer->getDatabasePager()->setDoPreCompile(true); + + osg::Camera *camera = m_viewer->getCamera(); + camera->setViewport(new osg::Viewport(0,0,w,h)); + camera->setGraphicsContext(m_gw); + camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + // configure the near/far so we don't clip things that are up close + camera->setNearFarRatio(0.00002); + camera->setProjectionMatrixAsPerspective(m_fieldOfView, qreal(w)/h, 1.0f, 10000.0f); + + markCameraDirty(); +} + diff --git a/ground/openpilotgcs/src/plugins/pfdqml/osgearth.h b/ground/openpilotgcs/src/plugins/pfdqml/osgearth.h new file mode 100644 index 000000000..6a1095a07 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/osgearth.h @@ -0,0 +1,117 @@ +/* + * 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 OSGEARTH_H +#define OSGEARTH_H + +#include + +#include +#include + +class QGLFramebufferObject; +class QGLWidget; + +class OsgEarthItem : public QDeclarativeItem +{ + Q_OBJECT + Q_DISABLE_COPY(OsgEarthItem) + + Q_PROPERTY(QString sceneFile READ sceneFile WRITE setSceneFile NOTIFY sceneFileChanged) + Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged) + + Q_PROPERTY(qreal roll READ roll WRITE setRoll NOTIFY rollChanged) + Q_PROPERTY(qreal pitch READ pitch WRITE setPitch NOTIFY pitchChanged) + Q_PROPERTY(qreal yaw READ yaw WRITE setYaw NOTIFY yawChanged) + + Q_PROPERTY(double latitude READ latitude WRITE setLatitude NOTIFY latitudeChanged) + Q_PROPERTY(double longitude READ longitude WRITE setLongitude NOTIFY longitudeChanged) + Q_PROPERTY(double altitude READ altitude WRITE setAltitude NOTIFY altitudeChanged) + +public: + OsgEarthItem(QDeclarativeItem *parent = 0); + ~OsgEarthItem(); + + QString sceneFile() const { return m_sceneFile; } + qreal fieldOfView() const { return m_fieldOfView; } + + qreal roll() const { return m_roll; } + qreal pitch() const { return m_pitch; } + qreal yaw() const { return m_yaw; } + + double latitude() const { return m_latitude; } + double longitude() const { return m_longitude; } + double altitude() const { return m_altitude; } + +protected: + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *style, QWidget *widget); + +public slots: + void setSceneFile(QString arg); + void setFieldOfView(qreal arg); + + void setRoll(qreal arg); + void setPitch(qreal arg); + void setYaw(qreal arg); + + void setLatitude(double arg); + void setLongitude(double arg); + void setAltitude(double arg); + +signals: + void rollChanged(qreal arg); + void pitchChanged(qreal arg); + void yawChanged(qreal arg); + + void latitudeChanged(double arg); + void longitudeChanged(double arg); + void altitudeChanged(double arg); + + void sceneFileChanged(QString arg); + void fieldOfViewChanged(qreal arg); + +private slots: + void markCameraDirty(); + void updateFBO(); + void initScene(); + +private: + osg::ref_ptr m_viewer; + osg::ref_ptr m_gw; + osg::ref_ptr m_model; + QWeakPointer m_glWidget; + QGLFramebufferObject *m_fbo; + QSize m_currentSize; + + qreal m_roll; + qreal m_pitch; + qreal m_yaw; + + double m_latitude; + double m_longitude; + double m_altitude; + + qreal m_fieldOfView; + QString m_sceneFile; + + bool m_cameraDirty; +}; + +QML_DECLARE_TYPE(OsgEarthItem) + +#endif // OSGEARTH_H + diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqml.pro b/ground/openpilotgcs/src/plugins/pfdqml/pfdqml.pro new file mode 100644 index 000000000..7064f8a0c --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqml.pro @@ -0,0 +1,35 @@ +TEMPLATE = lib +TARGET = PfdQml +QT += svg +QT += opengl +QT += declarative + +include(../../openpilotgcsplugin.pri) +include(../../plugins/coreplugin/coreplugin.pri) +include(pfdqml_dependencies.pri) + +LIBS += -losg -losgUtil -losgViewer -losgQt -losgDB -lOpenThreads -losgGA +LIBS += -losgEarth -losgEarthFeatures -losgEarthUtil + +HEADERS += \ + pfdqmlplugin.h \ + pfdqmlgadget.h \ + pfdqmlgadgetwidget.h \ + pfdqmlgadgetfactory.h \ + pfdqmlgadgetconfiguration.h \ + pfdqmlgadgetoptionspage.h \ + osgearth.h + +SOURCES += \ + pfdqmlplugin.cpp \ + pfdqmlgadget.cpp \ + pfdqmlgadgetfactory.cpp \ + pfdqmlgadgetwidget.cpp \ + pfdqmlgadgetconfiguration.cpp \ + pfdqmlgadgetoptionspage.cpp \ + osgearth.cpp + +OTHER_FILES += PfdQml.pluginspec + +FORMS += pfdqmlgadgetoptionspage.ui + diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqml_dependencies.pri b/ground/openpilotgcs/src/plugins/pfdqml/pfdqml_dependencies.pri new file mode 100644 index 000000000..9aae5fbc0 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqml_dependencies.pri @@ -0,0 +1 @@ +include(../../plugins/uavobjects/uavobjects.pri) diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.cpp b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.cpp new file mode 100644 index 000000000..48661a581 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.cpp @@ -0,0 +1,44 @@ +/* + * 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 "pfdqmlgadget.h" +#include "pfdqmlgadgetwidget.h" +#include "pfdqmlgadgetconfiguration.h" + +PfdQmlGadget::PfdQmlGadget(QString classId, PfdQmlGadgetWidget *widget, QWidget *parent) : + IUAVGadget(classId, parent), + m_widget(widget) +{ +} + +PfdQmlGadget::~PfdQmlGadget() +{ + delete m_widget; +} + +/* + This is called when a configuration is loaded, and updates the plugin's settings. + Careful: the plugin is already drawn before the loadConfiguration method is called the + first time, so you have to be careful not to assume all the plugin values are initialized + the first time you use them + */ +void PfdQmlGadget::loadConfiguration(IUAVGadgetConfiguration* config) +{ + PfdQmlGadgetConfiguration *m = qobject_cast(config); + m_widget->setQmlFile(m->qmlFile()); + m_widget->setEarthFile(m->earthFile()); + m_widget->setTerrainEnabled(m->terrainEnabled()); +} diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.h b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.h new file mode 100644 index 000000000..073e1f326 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadget.h @@ -0,0 +1,45 @@ +/* + * 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 PFDQMLGADGET_H_ +#define PFDQMLQMLGADGET_H_ + +#include +#include "pfdqmlgadgetwidget.h" + +class IUAVGadget; +class QWidget; +class QString; +class PfdQmlGadgetWidget; + +using namespace Core; + +class PfdQmlGadget : public Core::IUAVGadget +{ + Q_OBJECT +public: + PfdQmlGadget(QString classId, PfdQmlGadgetWidget *widget, QWidget *parent = 0); + ~PfdQmlGadget(); + + QWidget *widget() { return m_widget; } + void loadConfiguration(IUAVGadgetConfiguration* config); + +private: + PfdQmlGadgetWidget *m_widget; +}; + + +#endif // PFDQMLQMLGADGET_H_ diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp new file mode 100644 index 000000000..56926917e --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.cpp @@ -0,0 +1,67 @@ +/* + * 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 "pfdqmlgadgetconfiguration.h" +#include "utils/pathutils.h" + +/** + * Loads a saved configuration or defaults if non exist. + * + */ +PfdQmlGadgetConfiguration::PfdQmlGadgetConfiguration(QString classId, QSettings *qSettings, QObject *parent) : + IUAVGadgetConfiguration(classId, parent), + m_qmlFile("Unknown"), + m_earthFile("Unknown"), + m_terrainEnabled(true) +{ + //if a saved configuration exists load it + if(qSettings != 0) { + m_qmlFile = qSettings->value("qmlFile").toString(); + m_qmlFile=Utils::PathUtils().InsertDataPath(m_qmlFile); + + m_earthFile = qSettings->value("earthFile").toString(); + m_earthFile=Utils::PathUtils().InsertDataPath(m_earthFile); + + m_terrainEnabled = qSettings->value("terrainEnabled").toBool(); + } +} + +/** + * Clones a configuration. + * + */ +IUAVGadgetConfiguration *PfdQmlGadgetConfiguration::clone() +{ + PfdQmlGadgetConfiguration *m = new PfdQmlGadgetConfiguration(this->classId()); + m->m_qmlFile = m_qmlFile; + m->m_earthFile = m_earthFile; + m->m_terrainEnabled = m_terrainEnabled; + + return m; +} + +/** + * Saves a configuration. + * + */ +void PfdQmlGadgetConfiguration::saveConfig(QSettings* qSettings) const { + QString qmlFile = Utils::PathUtils().RemoveDataPath(m_qmlFile); + qSettings->setValue("qmlFile", qmlFile); + QString earthFile = Utils::PathUtils().RemoveDataPath(m_earthFile); + qSettings->setValue("earthFile", earthFile); + + qSettings->setValue("terrainEnabled", m_terrainEnabled); +} diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h new file mode 100644 index 000000000..c9986173b --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetconfiguration.h @@ -0,0 +1,48 @@ +/* + * 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 PFDQMLGADGETCONFIGURATION_H +#define PFDQMLGADGETCONFIGURATION_H + +#include + +using namespace Core; + +class PfdQmlGadgetConfiguration : public IUAVGadgetConfiguration +{ +Q_OBJECT +public: + explicit PfdQmlGadgetConfiguration(QString classId, QSettings* qSettings = 0, QObject *parent = 0); + + void setQmlFile(const QString &fileName) { m_qmlFile=fileName; } + void setEarthFile(const QString &fileName) { m_earthFile=fileName; } + void setTerrainEnabled(bool flag) { m_terrainEnabled = flag; } + + //get dial configuration functions + QString qmlFile() const { return m_qmlFile; } + QString earthFile() const { return m_earthFile; } + bool terrainEnabled() const { return m_terrainEnabled; } + + void saveConfig(QSettings* settings) const; + IUAVGadgetConfiguration *clone(); + +private: + QString m_qmlFile; // The name of the dial's SVG source file + QString m_earthFile; // The name of osgearth terrain file + bool m_terrainEnabled; +}; + +#endif // PfdQmlGADGETCONFIGURATION_H diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp new file mode 100644 index 000000000..9616c4796 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.cpp @@ -0,0 +1,49 @@ +/* + * 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 "pfdqmlgadgetfactory.h" +#include "pfdqmlgadgetwidget.h" +#include "pfdqmlgadget.h" +#include "pfdqmlgadgetconfiguration.h" +#include "pfdqmlgadgetoptionspage.h" +#include + +PfdQmlGadgetFactory::PfdQmlGadgetFactory(QObject *parent) : + IUAVGadgetFactory(QString("PfdQmlGadget"), + tr("PFD (qml)"), + parent) +{ +} + +PfdQmlGadgetFactory::~PfdQmlGadgetFactory() +{ +} + +Core::IUAVGadget* PfdQmlGadgetFactory::createGadget(QWidget *parent) +{ + PfdQmlGadgetWidget* gadgetWidget = new PfdQmlGadgetWidget(parent); + return new PfdQmlGadget(QString("PfdQmlGadget"), gadgetWidget, parent); +} + +IUAVGadgetConfiguration *PfdQmlGadgetFactory::createConfiguration(QSettings *qSettings) +{ + return new PfdQmlGadgetConfiguration(QString("PfdQmlGadget"), qSettings); +} + +IOptionsPage *PfdQmlGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config) +{ + return new PfdQmlGadgetOptionsPage(qobject_cast(config)); +} + diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h new file mode 100644 index 000000000..950124010 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetfactory.h @@ -0,0 +1,41 @@ +/* + * 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 PFDQMLGADGETFACTORY_H_ +#define PFDQMLGADGETFACTORY_H_ + +#include + +namespace Core { +class IUAVGadget; +class IUAVGadgetFactory; +} + +using namespace Core; + +class PfdQmlGadgetFactory : public IUAVGadgetFactory +{ + Q_OBJECT +public: + PfdQmlGadgetFactory(QObject *parent = 0); + ~PfdQmlGadgetFactory(); + + Core::IUAVGadget *createGadget(QWidget *parent); + IUAVGadgetConfiguration *createConfiguration(QSettings *qSettings); + IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config); +}; + +#endif // PfdQmlGADGETFACTORY_H_ diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp new file mode 100644 index 000000000..01ee89c96 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.cpp @@ -0,0 +1,77 @@ +/* + * 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 "pfdqmlgadgetoptionspage.h" +#include "pfdqmlgadgetconfiguration.h" +#include "ui_pfdqmlgadgetoptionspage.h" +#include "extensionsystem/pluginmanager.h" +#include "uavobjectmanager.h" +#include "uavdataobject.h" + + +#include +#include +#include + +PfdQmlGadgetOptionsPage::PfdQmlGadgetOptionsPage(PfdQmlGadgetConfiguration *config, QObject *parent) : + IOptionsPage(parent), + m_config(config) +{ +} + +//creates options page widget (uses the UI file) +QWidget *PfdQmlGadgetOptionsPage::createPage(QWidget *parent) +{ + + options_page = new Ui::PfdQmlGadgetOptionsPage(); + //main widget + QWidget *optionsPageWidget = new QWidget; + //main layout + options_page->setupUi(optionsPageWidget); + + // Restore the contents from the settings: + options_page->qmlSourceFile->setExpectedKind(Utils::PathChooser::File); + options_page->qmlSourceFile->setPromptDialogFilter(tr("QML file (*.qml)")); + options_page->qmlSourceFile->setPromptDialogTitle(tr("Choose QML file")); + options_page->qmlSourceFile->setPath(m_config->qmlFile()); + + // Restore the contents from the settings: + options_page->earthFile->setExpectedKind(Utils::PathChooser::File); + options_page->earthFile->setPromptDialogFilter(tr("OsgEarth (*.earth)")); + options_page->earthFile->setPromptDialogTitle(tr("Choose OsgEarth terrain file")); + options_page->earthFile->setPath(m_config->earthFile()); + + options_page->showTerrain->setChecked(m_config->terrainEnabled()); + + return optionsPageWidget; +} + +/** + * Called when the user presses apply or OK. + * + * Saves the current values + * + */ +void PfdQmlGadgetOptionsPage::apply() +{ + m_config->setQmlFile(options_page->qmlSourceFile->path()); + m_config->setEarthFile(options_page->earthFile->path()); + m_config->setTerrainEnabled(options_page->showTerrain->isChecked()); +} + +void PfdQmlGadgetOptionsPage::finish() +{ +} diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h new file mode 100644 index 000000000..8797275a6 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.h @@ -0,0 +1,54 @@ +/* + * 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 PFDQMLGADGETOPTIONSPAGE_H +#define PFDQMLGADGETOPTIONSPAGE_H + +#include "coreplugin/dialogs/ioptionspage.h" +#include "QString" +#include +#include + +namespace Core { +class IUAVGadgetConfiguration; +} + +class PfdQmlGadgetConfiguration; + +namespace Ui { + class PfdQmlGadgetOptionsPage; +} + +using namespace Core; + +class PfdQmlGadgetOptionsPage : public IOptionsPage +{ +Q_OBJECT +public: + explicit PfdQmlGadgetOptionsPage(PfdQmlGadgetConfiguration *config, QObject *parent = 0); + + QWidget *createPage(QWidget *parent); + void apply(); + void finish(); + +private: + Ui::PfdQmlGadgetOptionsPage *options_page; + PfdQmlGadgetConfiguration *m_config; + +private slots: +}; + +#endif // PfdQmlGADGETOPTIONSPAGE_H diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui new file mode 100644 index 000000000..dd8d03e4f --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetoptionspage.ui @@ -0,0 +1,135 @@ + + + PfdQmlGadgetOptionsPage + + + + 0 + 0 + 441 + 339 + + + + + 0 + 0 + + + + Form + + + + + + 10 + + + QLayout::SetMaximumSize + + + 10 + + + + + QML file: + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Horizontal + + + + + + + + + true + + + Show terrain + + + true + + + + + + + + + 10 + + + QLayout::SetMaximumSize + + + 10 + + + + + OsgEarth file: + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 40 + + + + + + + + + Utils::PathChooser + QWidget +
utils/pathchooser.h
+ 1 +
+
+ + +
diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp new file mode 100644 index 000000000..ac2d7ada2 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.cpp @@ -0,0 +1,106 @@ +/* + * 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 "pfdqmlgadgetwidget.h" +#include "extensionsystem/pluginmanager.h" +#include "uavobjectmanager.h" +#include "uavobject.h" +#include "utils/svgimageprovider.h" +#include "osgearth.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +PfdQmlGadgetWidget::PfdQmlGadgetWidget(QWidget *parent) : + QDeclarativeView(parent) +{ + setMinimumSize(64,64); + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + setResizeMode(SizeRootObjectToView); + + setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + + QStringList objectsToExport; + objectsToExport << "VelocityActual" << + "PositionActual" << + "AttitudeActual" << + "GPSPosition" << + "GCSTelemetryStats" << + "FlightBatteryState"; + + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectManager *objManager = pm->getObject(); + + foreach (const QString &objectName, objectsToExport) { + UAVObject* object = objManager->getObject(objectName); + if (object) + engine()->rootContext()->setContextProperty(objectName, object); + else + qWarning() << "Failed to load object" << objectName; + } + + //to expose settings values + engine()->rootContext()->setContextProperty("qmlWidget", this); + + qmlRegisterType("org.OpenPilot", 1, 0, "OsgEarth"); +} + +PfdQmlGadgetWidget::~PfdQmlGadgetWidget() +{ +} + +void PfdQmlGadgetWidget::setQmlFile(QString fn) +{ + m_qmlFileName = fn; + + engine()->removeImageProvider("svg"); + SvgImageProvider *svgProvider = new SvgImageProvider(fn); + engine()->addImageProvider("svg", svgProvider); + + //it's necessary to allow qml side to query svg element position + engine()->rootContext()->setContextProperty("svgRenderer", svgProvider); + engine()->setBaseUrl(QUrl::fromLocalFile(fn)); + + qDebug() << Q_FUNC_INFO << fn; + setSource(QUrl::fromLocalFile(fn)); + + foreach(const QDeclarativeError &error, errors()) { + qDebug() << error.description(); + } +} + +void PfdQmlGadgetWidget::setEarthFile(QString arg) +{ + if (m_earthFile != arg) { + m_earthFile = arg; + emit earthFileChanged(arg); + } +} + +void PfdQmlGadgetWidget::setTerrainEnabled(bool arg) +{ + if (m_terrainEnabled != arg) { + m_terrainEnabled = arg; + emit terrainEnabledChanged(arg); + } +} diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h new file mode 100644 index 000000000..6e0f8b35f --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlgadgetwidget.h @@ -0,0 +1,51 @@ +/* + * 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 PFDQMLGADGETWIDGET_H_ +#define PFDQMLGADGETWIDGET_H_ + +#include "pfdqmlgadgetconfiguration.h" +#include + +class PfdQmlGadgetWidget : public QDeclarativeView +{ + Q_OBJECT + Q_PROPERTY(QString earthFile READ earthFile WRITE setEarthFile NOTIFY earthFileChanged) + Q_PROPERTY(bool terrainEnabled READ terrainEnabled WRITE setTerrainEnabled NOTIFY terrainEnabledChanged) + +public: + PfdQmlGadgetWidget(QWidget *parent = 0); + ~PfdQmlGadgetWidget(); + void setQmlFile(QString fn); + + QString earthFile() const { return m_earthFile; } + bool terrainEnabled() const { return m_terrainEnabled; } + +public slots: + void setEarthFile(QString arg); + void setTerrainEnabled(bool arg); + +signals: + void earthFileChanged(QString arg); + void terrainEnabledChanged(bool arg); + +private: + QString m_qmlFileName; + QString m_earthFile; + bool m_terrainEnabled; +}; + +#endif /* PFDQMLGADGETWIDGET_H_ */ diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.cpp b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.cpp new file mode 100644 index 000000000..f7d40a24d --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.cpp @@ -0,0 +1,55 @@ +/* + * 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 "pfdqmlplugin.h" +#include "pfdqmlgadgetfactory.h" +#include +#include +#include +#include + + +PfdQmlPlugin::PfdQmlPlugin() +{ + // Do nothing +} + +PfdQmlPlugin::~PfdQmlPlugin() +{ + // Do nothing +} + +bool PfdQmlPlugin::initialize(const QStringList& args, QString *errMsg) +{ + Q_UNUSED(args); + Q_UNUSED(errMsg); + mf = new PfdQmlGadgetFactory(this); + addAutoReleasedObject(mf); + + return true; +} + +void PfdQmlPlugin::extensionsInitialized() +{ + // Do nothing +} + +void PfdQmlPlugin::shutdown() +{ + // Do nothing +} +Q_EXPORT_PLUGIN(PfdQmlPlugin) + diff --git a/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.h b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.h new file mode 100644 index 000000000..e1ef1a122 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/pfdqml/pfdqmlplugin.h @@ -0,0 +1,36 @@ +/* + * 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 PFDQMLPLUGIN_H_ +#define PFDQMLPLUGIN_H_ + +#include + +class PfdQmlGadgetFactory; + +class PfdQmlPlugin : public ExtensionSystem::IPlugin +{ +public: + PfdQmlPlugin(); + ~PfdQmlPlugin(); + + void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString); + void shutdown(); +private: + PfdQmlGadgetFactory *mf; +}; +#endif /* PFDQMLPLUGIN_H_ */ diff --git a/ground/openpilotgcs/src/plugins/plugins.pro b/ground/openpilotgcs/src/plugins/plugins.pro index 154335e3a..63fd4c297 100644 --- a/ground/openpilotgcs/src/plugins/plugins.pro +++ b/ground/openpilotgcs/src/plugins/plugins.pro @@ -128,12 +128,17 @@ plugin_pfd.depends = plugin_coreplugin plugin_pfd.depends += plugin_uavobjects SUBDIRS += plugin_pfd -# Primary Flight Display (PFD) gadget +# QML viewer gadget plugin_qmlview.subdir = qmlview plugin_qmlview.depends = plugin_coreplugin plugin_qmlview.depends += plugin_uavobjects SUBDIRS += plugin_qmlview +# Primary Flight Display (PFD) gadget, QML version +plugin_pfdqml.subdir = pfdqml +plugin_pfdqml.depends = plugin_coreplugin +plugin_pfdqml.depends += plugin_uavobjects +SUBDIRS += plugin_pfdqml #IP connection plugin plugin_ipconnection.subdir = ipconnection