QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgstiledscenerendererpropertieswidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstiledscenerendererpropertieswidget.cpp
3 ---------------------
4 begin : August 2023
5 copyright : (C) 2023 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
16
17#include "qgis.h"
18#include "qgsapplication.h"
19#include "qgslogger.h"
20#include "qgsproject.h"
21#include "qgsprojectutils.h"
23#include "qgstiledscenelayer.h"
29
30#include <QString>
31
32#include "moc_qgstiledscenerendererpropertieswidget.cpp"
33
34using namespace Qt::StringLiterals;
35
36static bool initTiledSceneRenderer( const QString &name, QgsTiledSceneRendererWidgetFunc f, const QString &iconName = QString() )
37{
39 if ( !rendererAbstractMetadata )
40 return false;
41 QgsTiledSceneRendererMetadata *rendererMetadata = dynamic_cast<QgsTiledSceneRendererMetadata *>( rendererAbstractMetadata );
42 if ( !rendererMetadata )
43 return false;
44
45 rendererMetadata->setWidgetFunction( f );
46
47 if ( !iconName.isEmpty() )
48 {
49 rendererMetadata->setIcon( QgsApplication::getThemeIcon( iconName ) );
50 }
51
52 QgsDebugMsgLevel( "Set for " + name, 2 );
53 return true;
54}
55
56void QgsTiledSceneRendererPropertiesWidget::initRendererWidgetFunctions()
57{
58 static bool sInitialized = false;
59 if ( sInitialized )
60 return;
61
62 initTiledSceneRenderer( u"texture"_s, QgsTiledSceneTextureRendererWidget::create, u"styleicons/tiledscenetexture.svg"_s );
63 initTiledSceneRenderer( u"wireframe"_s, QgsTiledSceneWireframeRendererWidget::create, u"styleicons/tiledscenewireframe.svg"_s );
64
65 sInitialized = true;
66}
67
69 : QgsMapLayerConfigWidget( layer, nullptr, parent )
70 , mLayer( layer )
71 , mStyle( style )
72{
73 setupUi( this );
74
75 layout()->setContentsMargins( 0, 0, 0, 0 );
76
77 // initialize registry's widget functions
78 initRendererWidgetFunctions();
79
81 const QStringList renderers = reg->renderersList();
82 for ( const QString &name : renderers )
83 {
85 cboRenderers->addItem( m->icon(), m->visibleName(), name );
86 }
87
88 cboRenderers->setCurrentIndex( -1 ); // set no current renderer
89
90 connect( cboRenderers, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsTiledSceneRendererPropertiesWidget::rendererChanged );
91
92 connect( mBlendModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsTiledSceneRendererPropertiesWidget::emitWidgetChanged );
93 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsTiledSceneRendererPropertiesWidget::emitWidgetChanged );
94
95 mMaxErrorUnitWidget->setUnits(
97 );
98 mMaxErrorSpinBox->setClearValue( 3 );
99
100 connect( mMaxErrorSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsTiledSceneRendererPropertiesWidget::emitWidgetChanged );
101 connect( mMaxErrorUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTiledSceneRendererPropertiesWidget::emitWidgetChanged );
102
103 syncToLayer( layer );
104}
105
107{
108 mMapCanvas = context.mapCanvas();
109 mMessageBar = context.messageBar();
110 if ( mActiveWidget )
111 {
112 mActiveWidget->setContext( context );
113 }
114}
115
117{
118 mLayer = qobject_cast<QgsTiledSceneLayer *>( layer );
119
120 mBlockChangedSignal = true;
121 mOpacityWidget->setOpacity( mLayer->opacity() );
122 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mLayer ) );
123 mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
124
125 if ( mLayer->renderer() )
126 {
127 // set current renderer from layer
128 const QString rendererName = mLayer->renderer()->type();
129
130 const int rendererIdx = cboRenderers->findData( rendererName );
131 cboRenderers->setCurrentIndex( rendererIdx );
132
133 // no renderer found... this mustn't happen
134 Q_ASSERT( rendererIdx != -1 && "there must be a renderer!" );
135
136 mMaxErrorSpinBox->setValue( mLayer->renderer()->maximumScreenError() );
137 mMaxErrorUnitWidget->setUnit( mLayer->renderer()->maximumScreenErrorUnit() );
138 }
139
140 mBlockChangedSignal = false;
141}
142
144{
145 if ( mActiveWidget )
146 mActiveWidget->setDockMode( dockMode );
148}
149
151{
152 mLayer->setOpacity( mOpacityWidget->opacity() );
153 mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
154
155 if ( mActiveWidget )
156 mLayer->setRenderer( mActiveWidget->renderer() );
157 else if ( !cboRenderers->currentData().toString().isEmpty() )
158 {
159 QDomElement elem;
160 if ( QgsTiledSceneRendererAbstractMetadata *metadata = QgsApplication::tiledSceneRendererRegistry()->rendererMetadata( cboRenderers->currentData().toString() ) )
161 {
162 mLayer->setRenderer( metadata->createRenderer( elem, QgsReadWriteContext() ) );
163 }
164 }
165
166 mLayer->renderer()->setMaximumScreenError( mMaxErrorSpinBox->value() );
167 mLayer->renderer()->setMaximumScreenErrorUnit( mMaxErrorUnitWidget->unit() );
168}
169
170void QgsTiledSceneRendererPropertiesWidget::rendererChanged()
171{
172 if ( cboRenderers->currentIndex() == -1 )
173 {
174 QgsDebugError( u"No current item -- this should never happen!"_s );
175 return;
176 }
177
178 const QString rendererName = cboRenderers->currentData().toString();
179
180 //Retrieve the previous renderer: from the old active widget if possible, otherwise from the layer
181 std::unique_ptr<QgsTiledSceneRenderer> oldRenderer;
182 std::unique_ptr<QgsTiledSceneRenderer> newRenderer;
183 if ( mActiveWidget )
184 newRenderer.reset( mActiveWidget->renderer() );
185
186 if ( newRenderer )
187 {
188 oldRenderer = std::move( newRenderer );
189 }
190 else
191 {
192 oldRenderer.reset( mLayer->renderer()->clone() );
193 }
194
195 // get rid of old active widget (if any)
196 if ( mActiveWidget )
197 {
198 stackedWidget->removeWidget( mActiveWidget );
199
200 delete mActiveWidget;
201 mActiveWidget = nullptr;
202 }
203
204 QgsTiledSceneRendererWidget *widget = nullptr;
205 QgsTiledSceneRendererAbstractMetadata *rendererMetadata = QgsApplication::tiledSceneRendererRegistry()->rendererMetadata( rendererName );
206 if ( rendererMetadata )
207 widget = rendererMetadata->createRendererWidget( mLayer, mStyle, oldRenderer.get() );
208 oldRenderer.reset();
209
210 if ( widget )
211 {
212 // instantiate the widget and set as active
213 mActiveWidget = widget;
214 stackedWidget->addWidget( mActiveWidget );
215 stackedWidget->setCurrentWidget( mActiveWidget );
216
217 if ( mMapCanvas || mMessageBar )
218 {
219 QgsSymbolWidgetContext context;
220 context.setMapCanvas( mMapCanvas );
221 context.setMessageBar( mMessageBar );
222 mActiveWidget->setContext( context );
223 }
224
227 widget->setDockMode( dockMode() );
228 }
229 else
230 {
231 // set default "no edit widget available" page
232 stackedWidget->setCurrentWidget( pageNoWidget );
233 }
234 emitWidgetChanged();
235}
236
237void QgsTiledSceneRendererPropertiesWidget::emitWidgetChanged()
238{
239 if ( !mBlockChangedSignal )
240 emit widgetChanged();
241}
@ Millimeters
Millimeters.
Definition qgis.h:5341
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5345
@ MapUnits
Map units.
Definition qgis.h:5342
@ Pixels
Pixels.
Definition qgis.h:5343
@ Inches
Inches.
Definition qgis.h:5346
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5348
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsTiledSceneRendererRegistry * tiledSceneRendererRegistry()
Returns the application's tiled scene renderer registry, used for managing tiled scene layer 2D rende...
QgsMapLayerConfigWidget(QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent=nullptr)
A panel widget that can be shown in the map style dock.
Base class for all map layer types.
Definition qgsmaplayer.h:83
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1....
void showPanel(QgsPanelWidget *panel)
Emit when you require a panel to be show in the interface.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
bool dockMode() const
Returns the dock mode state.
void widgetChanged()
Emitted when the widget state changes.
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
static bool layerIsContainedInGroupLayer(QgsProject *project, QgsMapLayer *layer)
Returns true if the specified layer is a child layer from any QgsGroupLayer in the given project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
A container for the context for various read/write operations on objects.
A database of saved style entities, including symbols, color ramps, text formats and others.
Definition qgsstyle.h:89
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
Represents a map layer supporting display of tiled scene objects.
Stores metadata about one tiled scene renderer class.
void setIcon(const QIcon &icon)
Sets an icon representing the renderer.
virtual QgsTiledSceneRendererWidget * createRendererWidget(QgsTiledSceneLayer *layer, QgsStyle *style, QgsTiledSceneRenderer *oldRenderer)
Returns new instance of settings widget for the renderer.
Convenience metadata class that uses static functions to create tiled scene renderer and its widget.
void setWidgetFunction(QgsTiledSceneRendererWidgetFunc f)
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the widget is shown, e.g., the associated map canvas and expression context...
QgsTiledSceneRendererPropertiesWidget(QgsTiledSceneLayer *layer, QgsStyle *style, QWidget *parent=nullptr)
Constructor for QgsTiledSceneRendererPropertiesWidget, associated with the specified layer and style ...
void setDockMode(bool dockMode) final
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
void syncToLayer(QgsMapLayer *layer) final
Reset to original (vector layer) values.
Registry of 2D renderers for tiled scenes.
QgsTiledSceneRendererAbstractMetadata * rendererMetadata(const QString &rendererName)
Returns the metadata for a specified renderer.
QStringList renderersList() const
Returns a list of available renderers.
void changed()
Emitted when the selected unit is changed, or the definition of the map unit scale is changed.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63
#define QgsDebugError(str)
Definition qgslogger.h:59
QgsTiledSceneRendererWidget *(* QgsTiledSceneRendererWidgetFunc)(QgsTiledSceneLayer *, QgsStyle *, QgsTiledSceneRenderer *)