1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

Merge branch 'pt/CC3D_Release' of ssh://git.openpilot.org/OpenPilot into pt/CC3D_Release

This commit is contained in:
PT_Dreamer 2012-07-30 15:25:59 +01:00
commit d8c2bb3292
33 changed files with 2133 additions and 35 deletions

View File

@ -3,21 +3,25 @@
Added the ability to load stylesheets from external file according to operating system:
macos.qss, linux.qss, windows.qss
Files should be placed inside the app folder.
2012-07-27
Several UI changes.
MixerCurveWidget refactoring, now as a simple and advanced view.
2012-07-27
Added “advanced mode” option to general settings. Right now it only shows the hidden apply buttons.
To enable go to tools->options->General and click one of the checkboxes to give focus to the form,
then press F7
2012-07-27
Made the flight mode switch and accessory pots move according to user input on the input wizard.
2012-07-27
Changed the board pictures on the uploader widget
2012-07-27
Add more verbose debug output on the UAVOBJECTS saving code.
Short summary of changes. For a complete list see the git log.
2012-07-20
AeroSimRC simulator plugin is now included into the Windows distribution
(will be installed into .../OpenPilot/misc/AeroSIM-RC directory). Still

View File

@ -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
}
}
}

View File

@ -0,0 +1,120 @@
import Qt 4.7
import "."
import org.OpenPilot 1.0
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
OsgEarth {
id: earthView
anchors.fill: parent
sceneFile: qmlWidget.earthFile
visible: qmlWidget.terrainEnabled
fieldOfView: 90
yaw: AttitudeActual.Yaw
pitch: AttitudeActual.Pitch
roll: AttitudeActual.Roll
latitude: qmlWidget.actualPositionUsed ?
GPSPosition.Latitude/10000000.0 : qmlWidget.latitude
longitude: qmlWidget.actualPositionUsed ?
GPSPosition.Longitude/10000000.0 : qmlWidget.longitude
altitude: qmlWidget.actualPositionUsed ?
GPSPosition.Altitude : qmlWidget.altitude
}
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
}
]
}
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
}
}
}
}

View File

@ -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
}
}

View File

@ -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
}
}
}

View File

@ -0,0 +1,26 @@
<!--
osgEarth Sample - SRTM global elevation
This sample demonstrates the use of a global SRTM TMS data source for world-wide elevation.
The heightfield is draped with the NASA Blue Marble imagery.
-->
<map name="srtm sample" type="globe" version="2">
<image name="pelican nasa blue marble" driver="tms">
<url>http://demo.pelicanmapping.com/rmweb/data/bluemarble-tms/tms.xml</url>
</image>
<heightfield name="pelican srtm" driver="tms">
<url>http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml</url>
</heightfield>
<options>
<lighting>true</lighting>
<terrain>
<vertical_scale>1</vertical_scale>
<loading_policy mode="sequential"/>
</terrain>
</options>
</map>

View File

@ -0,0 +1,26 @@
<!--
osgEarth Sample - SRTM global elevation
This sample demonstrates the use of a global SRTM TMS data source for world-wide elevation.
The heightfield is draped with the NASA Blue Marble imagery.
-->
<map name="srtm sample" type="globe" version="2">
<image name="yahoo aerial" driver="yahoo">
<dataset>satellite</dataset>
</image>
<heightfield name="pelican srtm" driver="tms">
<url>http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml</url>
</heightfield>
<options>
<lighting>false</lighting>
<terrain>
<vertical_scale>2</vertical_scale>
<loading_policy mode="sequential"/>
</terrain>
</options>
</map>

View File

@ -31,6 +31,7 @@
#include <QUrl>
SvgImageProvider::SvgImageProvider(const QString &basePath):
QObject(),
QDeclarativeImageProvider(QDeclarativeImageProvider::Image),
m_basePath(basePath)
{
@ -41,6 +42,30 @@ SvgImageProvider::~SvgImageProvider()
qDeleteAll(m_renderers);
}
QSvgRenderer *SvgImageProvider::loadRenderer(const QString &svgFile)
{
QSvgRenderer *renderer = m_renderers.value(svgFile);
if (!renderer) {
renderer = new QSvgRenderer(svgFile);
QString fn = QUrl::fromLocalFile(m_basePath).resolved(svgFile).toLocalFile();
//convert path to be relative to base
if (!renderer->isValid())
renderer->load(fn);
if (!renderer->isValid()) {
qWarning() << "Failed to load svg file:" << svgFile << fn;
delete renderer;
return 0;
}
m_renderers.insert(svgFile, renderer);
}
return renderer;
}
/**
requestedSize is realted to the whole svg file, not to specific element
*/
@ -58,23 +83,9 @@ QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSiz
if (size)
*size = QSize();
QSvgRenderer *renderer = m_renderers.value(svgFile);
if (!renderer) {
renderer = new QSvgRenderer(svgFile);
QString fn = QUrl::fromLocalFile(m_basePath).resolved(svgFile).toLocalFile();
//convert path to be relative to base
if (!renderer->isValid())
renderer->load(fn);
if (!renderer->isValid()) {
qWarning() << "Failed to load svg file:" << svgFile << fn;
return QImage();
}
m_renderers.insert(svgFile, renderer);
}
QSvgRenderer *renderer = loadRenderer(svgFile);
if (!renderer)
return QImage();
qreal xScale = 1.0;
qreal yScale = 1.0;
@ -128,3 +139,32 @@ QPixmap SvgImageProvider::requestPixmap(const QString &id, QSize *size, const QS
{
return QPixmap::fromImage(requestImage(id, size, requestedSize));
}
/*!
\fn SvgImageProvider::scaledElementBounds(const QString &svgFile, const QString &element)
Returns the bound of \a element in logical coordinates,
scalled to the default size of svg document (so the bounds of whole doc would be (0,0,1,1) ).
*/
QRectF SvgImageProvider::scaledElementBounds(const QString &svgFile, const QString &elementName)
{
QSvgRenderer *renderer = loadRenderer(svgFile);
if (!renderer)
return QRectF();
if (!renderer->elementExists(elementName)) {
qWarning() << "invalid element:" << elementName << "of" << svgFile;
return QRectF();
}
QRectF elementBounds = renderer->boundsOnElement(elementName);
QMatrix matrix = renderer->matrixForElement(elementName);
elementBounds = matrix.mapRect(elementBounds);
QSize docSize = renderer->defaultSize();
return QRectF(elementBounds.x()/docSize.width(),
elementBounds.y()/docSize.height(),
elementBounds.width()/docSize.width(),
elementBounds.height()/docSize.height());
}

View File

@ -28,19 +28,25 @@
#ifndef SVGIMAGEPROVIDER_H_
#define SVGIMAGEPROVIDER_H_
#include <QObject>
#include <QtDeclarative/qdeclarativeimageprovider.h>
#include <QSvgRenderer>
#include <QMap>
class SvgImageProvider : public QDeclarativeImageProvider
class SvgImageProvider : public QObject, public QDeclarativeImageProvider
{
Q_OBJECT
public:
SvgImageProvider(const QString &basePath);
~SvgImageProvider();
QSvgRenderer *loadRenderer(const QString &svgFile);
QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize);
QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize);
Q_INVOKABLE QRectF scaledElementBounds(const QString &svgFile, const QString &elementName);
private:
QMap<QString, QSvgRenderer*> m_renderers;
QString m_basePath;

View File

@ -5,7 +5,8 @@ QT += gui \
network \
xml \
svg \
opengl
opengl \
declarative
DEFINES += QTCREATOR_UTILS_LIB
@ -51,7 +52,9 @@ SOURCES += reloadpromptutils.cpp \
mytabbedstackwidget.cpp \
mytabwidget.cpp \
mylistwidget.cpp \
cachedsvgitem.cpp
cachedsvgitem.cpp \
svgimageprovider.cpp
SOURCES += xmlconfig.cpp
win32 {
@ -106,7 +109,10 @@ HEADERS += utils_global.h \
mytabbedstackwidget.h \
mytabwidget.h \
mylistwidget.h \
cachedsvgitem.h
cachedsvgitem.h \
svgimageprovider.h
HEADERS += xmlconfig.h
FORMS += filewizardpage.ui \

View File

@ -1680,6 +1680,40 @@
</data>
</smooth>
</PFDGadget>
<PfdQmlGadget>
<NoTerrain>
<configInfo>
<locked>false</locked>
<version>0.0.0</version>
</configInfo>
<data>
<actualPositionUsed>false</actualPositionUsed>
<altitude>2000</altitude>
<cacheOnly>false</cacheOnly>
<earthFile>%%DATAPATH%%pfd/pfd/default/readymap.earth</earthFile>
<latitude>46.671478</latitude>
<longitude>10.158932</longitude>
<qmlFile>%%DATAPATH%%pfd/pfd/default/Pfd.qml</qmlFile>
<terrainEnabled>false</terrainEnabled>
</data>
</NoTerrain>
<Terrain>
<configInfo>
<locked>false</locked>
<version>0.0.0</version>
</configInfo>
<data>
<actualPositionUsed>false</actualPositionUsed>
<altitude>2000</altitude>
<cacheOnly>false</cacheOnly>
<earthFile>%%DATAPATH%%pfd/pfd/default/readymap.earth</earthFile>
<latitude>46.671478</latitude>
<longitude>10.158932</longitude>
<qmlFile>%%DATAPATH%%pfd/pfd/default/Pfd.qml</qmlFile>
<terrainEnabled>true</terrainEnabled>
</data>
</Terrain>
</PfdQmlGadget>
<QmlViewGadget>
<default>
<configInfo>

View File

@ -0,0 +1,12 @@
<plugin name="PfdQml" version="1.0.0" compatVersion="1.0.0">
<vendor>The OpenPilot Project</vendor>
<copyright>(C) 2010 Edouard Lafargue</copyright>
<copyright>(C) 2012 Dmytro Poplavskiy</copyright>
<license>The GNU Public License (GPL) Version 3</license>
<description>QML based PFD widget</description>
<url>http://www.openpilot.org</url>
<dependencyList>
<dependency name="Core" version="1.0.0"/>
<dependency name="UAVObjects" version="1.0.0"/>
</dependencyList>
</plugin>

View File

@ -0,0 +1,327 @@
/*
* 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 <QtCore/qfileinfo.h>
#include <QtDeclarative/qdeclarative.h>
#include <QtDeclarative/qdeclarativeview.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtGui/qpainter.h>
#include <QtGui/qvector3d.h>
#include <QtOpenGL/qglframebufferobject.h>
#include <osg/MatrixTransform>
#include <osg/AutoTransform>
#include <osg/Camera>
#include <osg/TexMat>
#include <osg/TextureRectangle>
#include <osg/Texture2D>
#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ObjectPlacer>
#include <osgEarth/Map>
#include <QtCore/qtimer.h>
#include "utils/pathutils.h"
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<QGLWidget*>(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<QDeclarativeView*>(scene()->views().first());
if (view) {
QUrl baseUrl = view->engine()->baseUrl();
sceneFile = baseUrl.resolved(sceneFile).toLocalFile();
}
}
m_model = osgDB::readNodeFile(sceneFile.toStdString());
//setup caching
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(m_model.get());
if (mapNode) {
osgEarth::TMSCacheOptions cacheOptions;
//cacheOptions.cacheOnly() = true;
QString cacheDir = Utils::PathUtils().GetStoragePath()+QLatin1String("osgEarth_cache");
cacheOptions.setPath(cacheDir.toStdString());
osgEarth::Cache *cache= new osgEarth::TMSCache(cacheOptions);
mapNode->getMap()->setCache(cache);
} else {
qWarning() << Q_FUNC_INFO << sceneFile << " doesn't look like an osgEarth file";
}
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();
}

View File

@ -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 <osgViewer/Viewer>
#include <QtDeclarative/QDeclarativeItem>
#include <osgQt/GraphicsWindowQt>
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<osgViewer::Viewer> m_viewer;
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> m_gw;
osg::ref_ptr<osg::Node> m_model;
QWeakPointer<QGLWidget> 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

View File

@ -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

View File

@ -0,0 +1 @@
include(../../plugins/uavobjects/uavobjects.pri)

View File

@ -0,0 +1,57 @@
/*
* 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<PfdQmlGadgetConfiguration*>(config);
m_widget->setQmlFile(m->qmlFile());
m_widget->setEarthFile(m->earthFile());
m_widget->setTerrainEnabled(m->terrainEnabled());
m_widget->setActualPositionUsed(m->actualPositionUsed());
m_widget->setLatitude(m->latitude());
m_widget->setLongitude(m->longitude());
m_widget->setAltitude(m->altitude());
//setting OSGEARTH_CACHE_ONLY seems to work the most reliably
//between osgEarth versions I tried
if (m->cacheOnly()) {
qputenv("OSGEARTH_CACHE_ONLY", "true");
} else {
//how portable it is?
unsetenv("OSGEARTH_CACHE_ONLY");
}
}

View File

@ -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 <coreplugin/iuavgadget.h>
#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_

View File

@ -0,0 +1,87 @@
/*
* 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),
m_actualPositionUsed(false),
m_latitude(0),
m_longitude(0),
m_altitude(0),
m_cacheOnly(false)
{
//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();
m_actualPositionUsed = qSettings->value("actualPositionUsed").toBool();
m_latitude = qSettings->value("latitude").toDouble();
m_longitude = qSettings->value("longitude").toDouble();
m_altitude = qSettings->value("altitude").toDouble();
m_cacheOnly = qSettings->value("cacheOnly").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;
m->m_actualPositionUsed = m_actualPositionUsed;
m->m_latitude = m_latitude;
m->m_longitude = m_longitude;
m->m_altitude = m_altitude;
m->m_cacheOnly = m_cacheOnly;
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);
qSettings->setValue("actualPositionUsed", m_actualPositionUsed);
qSettings->setValue("latitude", m_latitude);
qSettings->setValue("longitude", m_longitude);
qSettings->setValue("altitude", m_altitude);
qSettings->setValue("cacheOnly", m_cacheOnly);
}

View File

@ -0,0 +1,62 @@
/*
* 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 <coreplugin/iuavgadgetconfiguration.h>
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; }
void setActualPositionUsed(bool flag) { m_actualPositionUsed = flag; }
void setLatitude(double value) { m_latitude = value; }
void setLongitude(double value) { m_longitude = value; }
void setAltitude(double value) { m_altitude = value; }
void setCacheOnly(bool flag) { m_cacheOnly = flag; }
QString qmlFile() const { return m_qmlFile; }
QString earthFile() const { return m_earthFile; }
bool terrainEnabled() const { return m_terrainEnabled; }
bool actualPositionUsed() const { return m_actualPositionUsed; }
double latitude() const { return m_latitude; }
double longitude() const { return m_longitude; }
double altitude() const { return m_altitude; }
bool cacheOnly() const { return m_cacheOnly; }
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;
bool m_actualPositionUsed;
double m_latitude;
double m_longitude;
double m_altitude;
bool m_cacheOnly;
};
#endif // PfdQmlGADGETCONFIGURATION_H

View File

@ -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 <coreplugin/iuavgadget.h>
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<PfdQmlGadgetConfiguration*>(config));
}

View File

@ -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 <coreplugin/iuavgadgetfactory.h>
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_

View File

@ -0,0 +1,89 @@
/*
* 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 <QFileDialog>
#include <QtAlgorithms>
#include <QStringList>
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(parent);
//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());
options_page->useActualLocation->setChecked(m_config->actualPositionUsed());
options_page->usePredefinedLocation->setChecked(!m_config->actualPositionUsed());
options_page->latitude->setText(QString::number(m_config->latitude()));
options_page->longitude->setText(QString::number(m_config->longitude()));
options_page->altitude->setText(QString::number(m_config->altitude()));
options_page->useOnlyCache->setChecked(m_config->cacheOnly());
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());
m_config->setActualPositionUsed(options_page->useActualLocation->isChecked());
m_config->setLatitude(options_page->latitude->text().toDouble());
m_config->setLongitude(options_page->longitude->text().toDouble());
m_config->setAltitude(options_page->altitude->text().toDouble());
m_config->setCacheOnly(options_page->useOnlyCache->isChecked());
}
void PfdQmlGadgetOptionsPage::finish()
{
}

View File

@ -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 <QStringList>
#include <QDebug>
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

View File

@ -0,0 +1,294 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PfdQmlGadgetOptionsPage</class>
<widget class="QWidget" name="PfdQmlGadgetOptionsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>457</width>
<height>436</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>457</width>
<height>436</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<property name="spacing">
<number>10</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>QML file: </string>
</property>
</widget>
</item>
<item>
<widget class="Utils::PathChooser" name="qmlSourceFile" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="showTerrain">
<property name="title">
<string>Show Terrain:</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,0">
<property name="spacing">
<number>10</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>OsgEarth file:</string>
</property>
</widget>
</item>
<item>
<widget class="Utils::PathChooser" name="earthFile" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QRadioButton" name="useActualLocation">
<property name="text">
<string>Use actual location</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QRadioButton" name="usePredefinedLocation">
<property name="text">
<string>Use pre-defined location:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1" colspan="3">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Latitude:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="latitude"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Longitude:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="longitude"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Altitude:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="altitude"/>
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="useOnlyCache">
<property name="text">
<string>Use only cache data</string>
</property>
</widget>
</item>
<item row="4" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>74</width>
<height>24</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="3">
<widget class="QPushButton" name="preSeedTerrain">
<property name="text">
<string>Pre seed terrain cache</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>121</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header>utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>usePredefinedLocation</sender>
<signal>toggled(bool)</signal>
<receiver>latitude</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>150</x>
<y>138</y>
</hint>
<hint type="destinationlabel">
<x>142</x>
<y>172</y>
</hint>
</hints>
</connection>
<connection>
<sender>usePredefinedLocation</sender>
<signal>toggled(bool)</signal>
<receiver>longitude</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>164</x>
<y>141</y>
</hint>
<hint type="destinationlabel">
<x>164</x>
<y>202</y>
</hint>
</hints>
</connection>
<connection>
<sender>usePredefinedLocation</sender>
<signal>toggled(bool)</signal>
<receiver>altitude</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>190</x>
<y>141</y>
</hint>
<hint type="destinationlabel">
<x>190</x>
<y>237</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,146 @@
/*
* 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 <QDebug>
#include <QSvgRenderer>
#include <QtOpenGL/QGLWidget>
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qdeclarativeengine.h>
PfdQmlGadgetWidget::PfdQmlGadgetWidget(QWidget *parent) :
QDeclarativeView(parent),
m_terrainEnabled(false),
m_actualPositionUsed(false),
m_latitude(46.671478),
m_longitude(10.158932),
m_altitude(2000)
{
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<UAVObjectManager>();
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<OsgEarthItem>("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);
}
}
//Switch between PositionActual UAVObject position
//and pre-defined latitude/longitude/altitude properties
void PfdQmlGadgetWidget::setActualPositionUsed(bool arg)
{
if (m_actualPositionUsed != arg) {
m_actualPositionUsed = arg;
emit actualPositionUsedChanged(arg);
}
}
void PfdQmlGadgetWidget::setLatitude(double arg)
{
//not sure qFuzzyCompare is accurate enough for geo coordinates
if (m_latitude != arg) {
m_latitude = arg;
emit latitudeChanged(arg);
}
}
void PfdQmlGadgetWidget::setLongitude(double arg)
{
if (m_longitude != arg) {
m_longitude = arg;
emit longitudeChanged(arg);
}
}
void PfdQmlGadgetWidget::setAltitude(double arg)
{
if (!qFuzzyCompare(m_altitude,arg)) {
m_altitude = arg;
emit altitudeChanged(arg);
}
}

View File

@ -0,0 +1,79 @@
/*
* 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 <QtDeclarative/qdeclarativeview.h>
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)
Q_PROPERTY(bool actualPositionUsed READ actualPositionUsed WRITE setActualPositionUsed NOTIFY actualPositionUsedChanged)
//pre-defined fallback position
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:
PfdQmlGadgetWidget(QWidget *parent = 0);
~PfdQmlGadgetWidget();
void setQmlFile(QString fn);
QString earthFile() const { return m_earthFile; }
bool terrainEnabled() const { return m_terrainEnabled; }
bool actualPositionUsed() const { return m_actualPositionUsed; }
double latitude() const { return m_latitude; }
double longitude() const { return m_longitude; }
double altitude() const { return m_altitude; }
public slots:
void setEarthFile(QString arg);
void setTerrainEnabled(bool arg);
void setLatitude(double arg);
void setLongitude(double arg);
void setAltitude(double arg);
void setActualPositionUsed(bool arg);
signals:
void earthFileChanged(QString arg);
void terrainEnabledChanged(bool arg);
void actualPositionUsedChanged(bool arg);
void latitudeChanged(double arg);
void longitudeChanged(double arg);
void altitudeChanged(double arg);
private:
QString m_qmlFileName;
QString m_earthFile;
bool m_terrainEnabled;
bool m_actualPositionUsed;
double m_latitude;
double m_longitude;
double m_altitude;
};
#endif /* PFDQMLGADGETWIDGET_H_ */

View File

@ -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 <QDebug>
#include <QtPlugin>
#include <QStringList>
#include <extensionsystem/pluginmanager.h>
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)

View File

@ -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 <extensionsystem/iplugin.h>
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_ */

View File

@ -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

View File

@ -14,8 +14,8 @@ HEADERS += \
qmlviewgadgetwidget.h \
qmlviewgadgetfactory.h \
qmlviewgadgetconfiguration.h \
qmlviewgadgetoptionspage.h \
svgimageprovider.h
qmlviewgadgetoptionspage.h
SOURCES += \
qmlviewplugin.cpp \
@ -23,8 +23,7 @@ SOURCES += \
qmlviewgadgetfactory.cpp \
qmlviewgadgetwidget.cpp \
qmlviewgadgetconfiguration.cpp \
qmlviewgadgetoptionspage.cpp \
svgimageprovider.cpp
qmlviewgadgetoptionspage.cpp
OTHER_FILES += QMLView.pluginspec

View File

@ -30,16 +30,13 @@
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "utils/svgimageprovider.h"
#include <utils/stylehelper.h>
#include <utils/cachedsvgitem.h>
#include <iostream>
#include <QDebug>
#include <QPainter>
#include <QSvgRenderer>
#include <QtOpenGL/QGLWidget>
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
#include <cmath>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecontext.h>
@ -69,6 +66,8 @@ QmlViewGadgetWidget::QmlViewGadgetWidget(QWidget *parent) :
else
qWarning() << "Failed to load object" << objectName;
}
engine()->rootContext()->setContextProperty("qmlWidget", this);
}
QmlViewGadgetWidget::~QmlViewGadgetWidget()
@ -80,8 +79,12 @@ void QmlViewGadgetWidget::setQmlFile(QString fn)
m_fn = fn;
engine()->removeImageProvider("svg");
engine()->addImageProvider("svg",
new SvgImageProvider(fn));
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));

View File

@ -29,7 +29,6 @@
#define QMLVIEWGADGETWIDGET_H_
#include "qmlviewgadgetconfiguration.h"
#include "svgimageprovider.h"
#include <QtDeclarative/qdeclarativeview.h>