Commit 02580839 authored by Bernhard Beschow's avatar Bernhard Beschow
Browse files

Introduce FloatItemsLayer, a dedicated layer for rendering screen-positioned, 2D float items

AbstractFloatItems are screen-positioned items that live in a 2D world. However, by overriding LayerInterface::render(), it was possible for float items to render in 3D space.

This patch avoids Marble calling 3D rendering API on AbstractFloatItems. As a result, the items are always rendered on the "FLOAT_ITEM" layer and 3D paintings aren't possible any longer for float items.
parent d2436d38
......@@ -205,10 +205,10 @@ void AbstractFloatItem::toolTipEvent ( QHelpEvent *e )
bool AbstractFloatItem::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos, GeoSceneLayer * layer )
{
Q_UNUSED( renderPos )
Q_UNUSED( layer )
paintEvent( painter, viewport );
Q_UNUSED(painter)
Q_UNUSED(viewport)
Q_UNUSED(renderPos)
Q_UNUSED(layer)
return true;
}
......
......@@ -51,10 +51,10 @@ class MARBLE_EXPORT AbstractFloatItem : public RenderPlugin, public FrameGraphic
const QSizeF &size = QSizeF( 150.0, 50.0 ) );
virtual ~AbstractFloatItem();
virtual QHash<QString,QVariant> settings() const;
virtual void setSettings(const QHash<QString, QVariant> &settings);
QHash<QString,QVariant> settings() const override;
void setSettings(const QHash<QString, QVariant> &settings) override;
virtual RenderType renderType() const;
RenderType renderType() const override;
/**
* @brief current pen for rendering
......@@ -80,12 +80,23 @@ class MARBLE_EXPORT AbstractFloatItem : public RenderPlugin, public FrameGraphic
*/
void setFont( const QFont &font );
bool render( GeoPainter *painter, ViewportParams *viewport,
/**
* @brief Paints the float item on the map.
* @deprecated Do not override this method since it won't be called any longer.
* Override one of FrameGraphicsItem's paint methods instead.
*/
MARBLE_DEPRECATED( bool render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos = QLatin1String("FLOAT_ITEM"),
GeoSceneLayer * layer = 0 );
virtual QString renderPolicy() const;
GeoSceneLayer * layer = 0 ) override );
QString renderPolicy() const override;
virtual QStringList renderPosition() const;
/**
* @brief Returns the rendering position of this float item.
* @deprecated The return value of method is ignored. The float item's rendering position
* will always be "FLOAT_ITEM".
*/
MARBLE_DEPRECATED( QStringList renderPosition() const override );
/**
* @brief Set visibility of the float item
......@@ -149,7 +160,7 @@ class MARBLE_EXPORT AbstractFloatItem : public RenderPlugin, public FrameGraphic
void hide();
protected:
virtual bool eventFilter( QObject *object, QEvent *e );
bool eventFilter(QObject *object, QEvent *e) override;
virtual void contextMenuEvent ( QWidget *w, QContextMenuEvent *e );
virtual void toolTipEvent( QHelpEvent *e );
QMenu* contextMenu();
......
......@@ -20,8 +20,6 @@
#include "AbstractDataPluginItem.h"
#include "AbstractFloatItem.h"
#include "GeoPainter.h"
#include "MarbleModel.h"
#include "PluginManager.h"
#include "RenderPlugin.h"
#include "LayerInterface.h"
#include "RenderState.h"
......@@ -34,39 +32,33 @@ namespace Marble
class Q_DECL_HIDDEN LayerManager::Private
{
public:
Private( const MarbleModel* model, LayerManager *parent );
Private(LayerManager *parent);
~Private();
void updateVisibility( bool visible, const QString &nameId );
void addPlugins();
LayerManager *const q;
QList<RenderPlugin *> m_renderPlugins;
QList<AbstractFloatItem *> m_floatItems;
QList<AbstractDataPlugin *> m_dataPlugins;
QList<LayerInterface *> m_internalLayers;
const MarbleModel* m_model;
bool m_showBackground;
RenderState m_renderState;
bool m_showBackground;
bool m_showRuntimeTrace;
};
LayerManager::Private::Private( const MarbleModel* model, LayerManager *parent )
: q( parent ),
m_renderPlugins(),
m_model( model ),
m_showBackground( true ),
m_showRuntimeTrace( false )
LayerManager::Private::Private(LayerManager *parent) :
q(parent),
m_renderPlugins(),
m_showBackground(true),
m_showRuntimeTrace(false)
{
}
LayerManager::Private::~Private()
{
qDeleteAll( m_renderPlugins );
}
void LayerManager::Private::updateVisibility( bool visible, const QString &nameId )
......@@ -75,12 +67,10 @@ void LayerManager::Private::updateVisibility( bool visible, const QString &nameI
}
LayerManager::LayerManager( const MarbleModel* model, QObject *parent )
: QObject( parent ),
d( new Private( model, this ) )
LayerManager::LayerManager(QObject *parent) :
QObject(parent),
d(new Private(this))
{
d->addPlugins();
connect( model->pluginManager(), SIGNAL(renderPluginsChanged()), this, SLOT(addPlugins()) );
}
LayerManager::~LayerManager()
......@@ -98,14 +88,22 @@ bool LayerManager::showRuntimeTrace() const
return d->m_showRuntimeTrace;
}
QList<RenderPlugin *> LayerManager::renderPlugins() const
void LayerManager::addRenderPlugin(RenderPlugin *renderPlugin)
{
return d->m_renderPlugins;
}
d->m_renderPlugins.append(renderPlugin);
QList<AbstractFloatItem *> LayerManager::floatItems() const
{
return d->m_floatItems;
QObject::connect(renderPlugin, SIGNAL(settingsChanged(QString)),
this, SIGNAL(pluginSettingsChanged()));
QObject::connect(renderPlugin, SIGNAL(repaintNeeded(QRegion)),
this, SIGNAL(repaintNeeded(QRegion)));
QObject::connect(renderPlugin, SIGNAL(visibilityChanged(bool,QString)),
this, SLOT(updateVisibility(bool,QString)));
// get data plugins
AbstractDataPlugin *const dataPlugin = qobject_cast<AbstractDataPlugin *>(renderPlugin);
if(dataPlugin) {
d->m_dataPlugins.append(dataPlugin);
}
}
QList<AbstractDataPlugin *> LayerManager::dataPlugins() const
......@@ -201,46 +199,6 @@ void LayerManager::renderLayers( GeoPainter *painter, ViewportParams *viewport )
}
}
void LayerManager::Private::addPlugins()
{
foreach ( const auto *factory, m_model->pluginManager()->renderPlugins() ) {
bool alreadyCreated = false;
foreach( const auto* existing, m_renderPlugins ) {
if ( existing->nameId() == factory->nameId() ) {
alreadyCreated = true;
break;
}
}
if ( alreadyCreated ) {
continue;
}
RenderPlugin *const renderPlugin = factory->newInstance( m_model );
Q_ASSERT( renderPlugin && "Plugin returned null when requesting a new instance." );
m_renderPlugins.append( renderPlugin );
QObject::connect( renderPlugin, SIGNAL(settingsChanged(QString)),
q, SIGNAL(pluginSettingsChanged()) );
QObject::connect( renderPlugin, SIGNAL(repaintNeeded(QRegion)),
q, SIGNAL(repaintNeeded(QRegion)) );
QObject::connect( renderPlugin, SIGNAL(visibilityChanged(bool,QString)),
q, SLOT(updateVisibility(bool,QString)) );
// get float items ...
AbstractFloatItem * const floatItem =
qobject_cast<AbstractFloatItem *>( renderPlugin );
if ( floatItem )
m_floatItems.append( floatItem );
// ... and data plugins
AbstractDataPlugin * const dataPlugin =
qobject_cast<AbstractDataPlugin *>( renderPlugin );
if( dataPlugin )
m_dataPlugins.append( dataPlugin );
}
}
void LayerManager::setShowBackground( bool show )
{
d->m_showBackground = show;
......
......@@ -30,9 +30,7 @@ class AbstractDataPluginItem;
class GeoPainter;
class ViewportParams;
class RenderPlugin;
class AbstractFloatItem;
class AbstractDataPlugin;
class MarbleModel;
class LayerInterface;
/**
......@@ -45,7 +43,7 @@ class LayerManager : public QObject
Q_OBJECT
public:
explicit LayerManager( const MarbleModel *model, QObject *parent = nullptr);
explicit LayerManager(QObject *parent = nullptr);
~LayerManager();
void renderLayers( GeoPainter *painter, ViewportParams *viewport );
......@@ -54,16 +52,8 @@ class LayerManager : public QObject
bool showRuntimeTrace() const;
/**
* @brief Returns a list of all RenderPlugins on the layer, this includes float items
* @return the list of RenderPlugins
*/
QList<RenderPlugin *> renderPlugins() const;
/**
* @brief Returns a list of all FloatItems on the layer
* @return the list of the floatItems
*/
QList<AbstractFloatItem *> floatItems() const;
void addRenderPlugin(RenderPlugin *renderPlugin);
/**
* @brief Returns a list of all DataPlugins on the layer
* @return the list of DataPlugins
......@@ -117,8 +107,6 @@ class LayerManager : public QObject
private:
Q_PRIVATE_SLOT( d, void updateVisibility( bool, const QString & ) )
Q_PRIVATE_SLOT( d, void addPlugins() )
private:
Q_DISABLE_COPY( LayerManager )
......
......@@ -24,6 +24,7 @@
#include <QRegion>
// Marble
#include "layers/FloatItemsLayer.h"
#include "layers/FogLayer.h"
#include "layers/FpsLayer.h"
#include "layers/GeometryLayer.h"
......@@ -58,6 +59,7 @@
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "PluginManager.h"
#include "RenderPlugin.h"
#include "StyleBuilder.h"
#include "SunLocator.h"
......@@ -121,6 +123,8 @@ public:
void updateTileLevel();
void addPlugins();
MarbleMap *const q;
// The model we are showing.
......@@ -134,10 +138,13 @@ public:
bool m_showDebugPolygons;
StyleBuilder m_styleBuilder;
QList<RenderPlugin *> m_renderPlugins;
LayerManager m_layerManager;
MarbleSplashLayer m_marbleSplashLayer;
MarbleMap::CustomPaintLayer m_customPaintLayer;
GeometryLayer m_geometryLayer;
FloatItemsLayer m_floatItemsLayer;
FogLayer m_fogLayer;
GroundLayer m_groundLayer;
TextureLayer m_textureLayer;
......@@ -156,15 +163,17 @@ MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) :
m_showFrameRate( false ),
m_showDebugPolygons( false ),
m_styleBuilder(),
m_layerManager( model, parent ),
m_layerManager( parent ),
m_customPaintLayer( parent ),
m_geometryLayer(model->treeModel(), &m_styleBuilder),
m_floatItemsLayer(parent),
m_textureLayer( model->downloadManager(), model->pluginManager(), model->sunLocator(), model->groundOverlayModel() ),
m_placemarkLayer( model->placemarkModel(), model->placemarkSelectionModel(), model->clock(), &m_styleBuilder ),
m_vectorTileLayer( model->downloadManager(), model->pluginManager(), model->treeModel() ),
m_isLockedToSubSolarPoint( false ),
m_isSubSolarPointIconVisible( false )
{
m_layerManager.addLayer(&m_floatItemsLayer);
m_layerManager.addLayer( &m_fogLayer );
m_layerManager.addLayer( &m_groundLayer );
m_layerManager.addLayer( &m_geometryLayer );
......@@ -192,7 +201,7 @@ MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) :
QObject::connect( &m_geometryLayer, SIGNAL(repaintNeeded()),
parent, SIGNAL(repaintNeeded()));
/**
/*
* Slot handleHighlight finds all placemarks
* that contain the clicked point.
* The placemarks under the clicked position may
......@@ -204,6 +213,15 @@ MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) :
QObject::connect( parent, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
&m_geometryLayer, SLOT(handleHighlight(qreal,qreal,GeoDataCoordinates::Unit)) );
QObject::connect(&m_floatItemsLayer, SIGNAL(repaintNeeded(QRegion)),
parent, SIGNAL(repaintNeeded(QRegion)));
QObject::connect(&m_floatItemsLayer, SIGNAL(renderPluginInitialized(RenderPlugin*)),
parent, SIGNAL(renderPluginInitialized(RenderPlugin*)));
QObject::connect(&m_floatItemsLayer, SIGNAL(visibilityChanged(QString,bool)),
parent, SLOT(setPropertyValue(QString,bool)));
QObject::connect(&m_floatItemsLayer, SIGNAL(pluginSettingsChanged()),
parent, SIGNAL(pluginSettingsChanged()));
QObject::connect( &m_textureLayer, SIGNAL(tileLevelChanged(int)),
parent, SLOT(updateTileLevel()) );
QObject::connect( &m_vectorTileLayer, SIGNAL(tileLevelChanged(int)),
......@@ -213,6 +231,10 @@ MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) :
QObject::connect( parent, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
parent, SIGNAL(repaintNeeded()) );
addPlugins();
QObject::connect(model->pluginManager(), SIGNAL(renderPluginsChanged()),
parent, SLOT(addPlugins()));
}
void MarbleMapPrivate::updateProperty( const QString &name, bool show )
......@@ -241,7 +263,7 @@ void MarbleMapPrivate::updateProperty( const QString &name, bool show )
m_textureLayer.setShowRelief( show );
}
foreach( RenderPlugin *renderPlugin, m_layerManager.renderPlugins() ) {
foreach(RenderPlugin *renderPlugin, m_renderPlugins) {
if ( name == renderPlugin->nameId() ) {
if ( renderPlugin->visible() == show ) {
break;
......@@ -254,6 +276,34 @@ void MarbleMapPrivate::updateProperty( const QString &name, bool show )
}
}
void MarbleMapPrivate::addPlugins()
{
foreach (const RenderPlugin *factory, m_model->pluginManager()->renderPlugins()) {
bool alreadyCreated = false;
foreach(const RenderPlugin *existing, m_renderPlugins) {
if (existing->nameId() == factory->nameId()) {
alreadyCreated = true;
break;
}
}
if (alreadyCreated) {
continue;
}
RenderPlugin *const renderPlugin = factory->newInstance(m_model);
Q_ASSERT(renderPlugin && "Plugin must not return null when requesting a new instance.");
m_renderPlugins << renderPlugin;
if (AbstractFloatItem *const floatItem = qobject_cast<AbstractFloatItem *>(renderPlugin)) {
m_floatItemsLayer.addFloatItem(floatItem);
}
else {
m_layerManager.addRenderPlugin(renderPlugin);
}
}
}
// ----------------------------------------------------------------
......@@ -275,10 +325,12 @@ MarbleMap::~MarbleMap()
d->m_layerManager.removeLayer( &d->m_customPaintLayer );
d->m_layerManager.removeLayer( &d->m_geometryLayer );
d->m_layerManager.removeLayer(&d->m_floatItemsLayer);
d->m_layerManager.removeLayer( &d->m_fogLayer );
d->m_layerManager.removeLayer( &d->m_placemarkLayer );
d->m_layerManager.removeLayer( &d->m_textureLayer );
d->m_layerManager.removeLayer( &d->m_groundLayer );
qDeleteAll(d->m_renderPlugins);
delete d;
delete model; // delete the model after private data
......@@ -990,7 +1042,7 @@ void MarbleMapPrivate::updateMapTheme()
m_styleBuilder.setDefaultLabelColor(m_model->mapTheme()->map()->labelColor());
m_placemarkLayer.requestStyleReset();
foreach( RenderPlugin *renderPlugin, m_layerManager.renderPlugins() ) {
foreach (RenderPlugin *renderPlugin, m_renderPlugins) {
bool propertyAvailable = false;
m_model->mapTheme()->settings()->propertyAvailable( renderPlugin->nameId(), propertyAvailable );
bool propertyValue = false;
......@@ -1257,12 +1309,12 @@ void MarbleMap::setDefaultFont( const QFont& font )
QList<RenderPlugin *> MarbleMap::renderPlugins() const
{
return d->m_layerManager.renderPlugins();
return d->m_renderPlugins;
}
QList<AbstractFloatItem *> MarbleMap::floatItems() const
{
return d->m_layerManager.floatItems();
return d->m_floatItemsLayer.floatItems();
}
AbstractFloatItem * MarbleMap::floatItem( const QString &nameId ) const
......
......@@ -737,6 +737,7 @@ class MARBLE_EXPORT MarbleMap : public QObject
Q_PRIVATE_SLOT( d, void updateProperty( const QString &, bool ) )
Q_PRIVATE_SLOT( d, void setDocument(QString) )
Q_PRIVATE_SLOT( d, void updateTileLevel() )
Q_PRIVATE_SLOT(d, void addPlugins())
private:
Q_DISABLE_COPY( MarbleMap )
......
......@@ -11,6 +11,7 @@ set( layers_HDRS
)
set( layers_SRCS
layers/FloatItemsLayer.cpp
layers/FogLayer.cpp
layers/FpsLayer.cpp
layers/GeometryLayer.cpp
......
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012-2016 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "FloatItemsLayer.h"
#include "AbstractFloatItem.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
namespace Marble
{
FloatItemsLayer::FloatItemsLayer(QObject *parent) :
QObject(parent),
m_floatItems()
{
}
QStringList FloatItemsLayer::renderPosition() const
{
return QStringList() << "FLOAT_ITEM";
}
bool FloatItemsLayer::render(GeoPainter *painter,
ViewportParams *viewport,
const QString &renderPos,
GeoSceneLayer *layer)
{
Q_UNUSED(renderPos)
Q_UNUSED(layer)
foreach (AbstractFloatItem *item, m_floatItems) {
if (!item->enabled()) {
continue;
}
if (!item->isInitialized()) {
item->initialize();
emit renderPluginInitialized(item);
}
if (item->visible()) {
item->paintEvent(painter, viewport);
}
}
return true;
}
void FloatItemsLayer::addFloatItem(AbstractFloatItem *floatItem)
{
Q_ASSERT(floatItem && "must not add a null float item to FloatItemsLayer");
connect(floatItem, SIGNAL(settingsChanged(QString)),
this, SIGNAL(pluginSettingsChanged()));
connect(floatItem, SIGNAL(repaintNeeded(QRegion)),
this, SIGNAL(repaintNeeded(QRegion)));
connect(floatItem, SIGNAL(visibilityChanged(bool,QString)),
this, SLOT(updateVisibility(bool,QString)));
m_floatItems.append( floatItem );
}
QList<AbstractFloatItem *> FloatItemsLayer::floatItems() const
{
return m_floatItems;
}
void FloatItemsLayer::updateVisibility(bool visible, const QString &nameId)
{
emit visibilityChanged(nameId, visible);
}
}
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012-2016 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_FLOATITEMSLAYER_H
#define MARBLE_FLOATITEMSLAYER_H
#include <QObject>
#include "LayerInterface.h"
#include <QList>
#include <QRegion>
namespace Marble
{
class AbstractFloatItem;
class RenderPlugin;
/**
* @brief Layer for handling the rendering of screen-positioned, 2D float items.
*/
class FloatItemsLayer : public QObject, public LayerInterface
{
Q_OBJECT
public:
explicit FloatItemsLayer(QObject *parent = 0);
QStringList renderPosition() const override;
bool render(GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos = "NONE", GeoSceneLayer *layer = 0) override;
void addFloatItem(AbstractFloatItem *floatItem);
/**
* @brief Returns a list of all FloatItems of the layer
* @return the list of the floatItems
*/
QList<AbstractFloatItem *> floatItems() const;
Q_SIGNALS:
/**
* @brief Signal that a render item has been initialized
*/
void renderPluginInitialized(RenderPlugin *renderPlugin);
/**
* This signal is emitted when the repaint of the view was requested by a plugin.
* If available with the @p dirtyRegion which is the region the view will change in.
* If dirtyRegion.isEmpty() returns true, the whole viewport has to be repainted.
*/
void repaintNeeded(const QRegion &dirtyRegion = QRegion());
void visibilityChanged(const QString &nameId, bool visible);
void pluginSettingsChanged();
private Q_SLOTS:
void updateVisibility(bool visible, const QString &nameId);
private:
QList<AbstractFloatItem *> m_floatItems;
};
}
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment