mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-03-21 13:28:58 +01:00
Expose SVG elements geometry to QML side
This allows to reuse the existing svg file like pfd.svg without manually positioning individual svg element.
This commit is contained in:
parent
0c092970ca
commit
6ee34931ac
@ -31,15 +31,11 @@
|
||||
#include "uavobjectmanager.h"
|
||||
#include "uavobject.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 +65,8 @@ QmlViewGadgetWidget::QmlViewGadgetWidget(QWidget *parent) :
|
||||
else
|
||||
qWarning() << "Failed to load object" << objectName;
|
||||
}
|
||||
|
||||
engine()->rootContext()->setContextProperty("qmlWidget", this);
|
||||
}
|
||||
|
||||
QmlViewGadgetWidget::~QmlViewGadgetWidget()
|
||||
@ -80,8 +78,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));
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user