Skip to content

Commit 0bbee86

Browse files
committed
3d: Introduce qgs3dsymbolbutton
1 parent bfd66eb commit 0bbee86

File tree

3 files changed

+208
-0
lines changed

3 files changed

+208
-0
lines changed

src/app/3d/qgs3dsymbolbutton.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/***************************************************************************
2+
qgs3dsymbolbutton.cpp
3+
--------------------------------------
4+
Date : January 2026
5+
Copyright : (C) 2026 by Jean Felder
6+
Email : jean dot felder at oslandia 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+
***************************************************************************/
15+
16+
#include "qgs3dsymbolbutton.h"
17+
18+
#include "qgs3dsymbolutils.h"
19+
#include "qgsvectorlayer3drendererwidget.h"
20+
21+
#include "moc_qgs3dsymbolbutton.cpp"
22+
23+
Qgs3DSymbolButton::Qgs3DSymbolButton( QWidget *parent )
24+
: QToolButton( parent )
25+
{
26+
connect( this, &QAbstractButton::clicked, this, &Qgs3DSymbolButton::showSettingsDialog );
27+
}
28+
29+
void Qgs3DSymbolButton::setLayer( QgsVectorLayer *layer )
30+
{
31+
mLayer = layer;
32+
}
33+
34+
void Qgs3DSymbolButton::setDialogTitle( const QString &title )
35+
{
36+
mDialogTitle = title;
37+
}
38+
39+
void Qgs3DSymbolButton::setSymbol( std::unique_ptr<QgsAbstract3DSymbol> symbol )
40+
{
41+
mSymbol = std::move( symbol );
42+
43+
const int fontHeight = static_cast<int>( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
44+
const QSize size = QToolButton::minimumSizeHint();
45+
46+
int symbolBtnHeight;
47+
if ( mSymbol && mSymbol->type() == "point"_L1 )
48+
{
49+
symbolBtnHeight = std::max( size.height(), 3 * fontHeight );
50+
setMaximumWidth( static_cast<int>( 1.5 * symbolBtnHeight ) );
51+
setMinimumWidth( maximumWidth() );
52+
}
53+
else
54+
{
55+
symbolBtnHeight = fontHeight;
56+
setMaximumWidth( 999999 );
57+
}
58+
59+
setMinimumHeight( symbolBtnHeight );
60+
updatePreview();
61+
}
62+
63+
QgsAbstract3DSymbol *Qgs3DSymbolButton::symbol() const
64+
{
65+
return mSymbol.get();
66+
}
67+
68+
void Qgs3DSymbolButton::resizeEvent( QResizeEvent *event )
69+
{
70+
QToolButton::resizeEvent( event );
71+
updatePreview();
72+
}
73+
74+
void Qgs3DSymbolButton::updatePreview()
75+
{
76+
if ( !mSymbol )
77+
{
78+
return;
79+
}
80+
81+
#ifdef Q_OS_WIN
82+
QSize iconSize = QSize( width() - 10, height() - 6 );
83+
#else
84+
QSize iconSize = QSize( width() - 10, height() - 12 );
85+
#endif
86+
87+
const QIcon symbolIcon = Qgs3DSymbolUtils::vectorSymbolPreviewIcon( mSymbol.get(), iconSize, QgsScreenProperties( screen() ), 0 );
88+
setIcon( symbolIcon );
89+
setIconSize( iconSize );
90+
}
91+
92+
void Qgs3DSymbolButton::updateSymbolFromWidget( QgsSingleSymbol3DRendererWidget *widget )
93+
{
94+
setSymbol( std::unique_ptr<QgsAbstract3DSymbol>( widget->symbol()->clone() ) );
95+
emit changed();
96+
}
97+
98+
void Qgs3DSymbolButton::showSettingsDialog()
99+
{
100+
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
101+
if ( panel && panel->dockMode() )
102+
{
103+
QgsSingleSymbol3DRendererWidget *widget = new QgsSingleSymbol3DRendererWidget( mLayer, this );
104+
widget->setPanelTitle( mDialogTitle );
105+
widget->setSymbol( mSymbol.get() );
106+
connect( widget, &QgsPanelWidget::widgetChanged, this, [this, widget] { updateSymbolFromWidget( widget ); } );
107+
panel->openPanel( widget );
108+
}
109+
}

src/app/3d/qgs3dsymbolbutton.h

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/***************************************************************************
2+
qgs3dsymbolbutton.h
3+
--------------------------------------
4+
Date : January 2026
5+
Copyright : (C) 2026 by Jean Felder
6+
Email : jean dot felder at oslandia 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+
***************************************************************************/
15+
16+
#ifndef QGS3DSYMBOLBUTTON_H
17+
#define QGS3DSYMBOLBUTTON_H
18+
19+
#include <memory>
20+
21+
#include "qgsabstract3dsymbol.h"
22+
#include "qgsvectorlayer.h"
23+
24+
#include <QToolButton>
25+
26+
class QgsSingleSymbol3DRendererWidget;
27+
28+
29+
/**
30+
* \class Qgs3DSymbolButton
31+
* \brief A push button widget for selecting and displaying a 3D symbol.
32+
* \since QGIS 4.0
33+
*/
34+
class Qgs3DSymbolButton : public QToolButton
35+
{
36+
Q_OBJECT
37+
38+
public:
39+
/**
40+
* Constructor for Qgs3DSymbolButton
41+
*
42+
* \param parent parent widget
43+
*/
44+
Qgs3DSymbolButton( QWidget *parent );
45+
46+
47+
/**
48+
* Sets the button's symbol.
49+
*
50+
* \param symbol 3D symbol to represent
51+
* \see symbol()
52+
*/
53+
void setSymbol( std::unique_ptr<QgsAbstract3DSymbol> symbol );
54+
55+
/**
56+
* Returns the current symbol defined by the button.
57+
* \see setSymbol()
58+
*/
59+
QgsAbstract3DSymbol *symbol() const;
60+
61+
/**
62+
* Sets a \a layer to associate with the widget. This allows the
63+
* widget to setup layer related settings within the symbol settings dialog.
64+
*
65+
* \param layer layer to associate. Ownership of \a layer is not transferred.
66+
*/
67+
void setLayer( QgsVectorLayer *layer );
68+
69+
/**
70+
* Sets the \a title for the symbol settings dialog window.
71+
*
72+
* \param title dialog title
73+
*/
74+
void setDialogTitle( const QString &title );
75+
76+
signals:
77+
/**
78+
* Emitted when the symbol's settings are changed.
79+
*/
80+
void changed();
81+
82+
protected:
83+
void resizeEvent( QResizeEvent *event ) override;
84+
85+
private slots:
86+
void showSettingsDialog();
87+
void updateSymbolFromWidget( QgsSingleSymbol3DRendererWidget *widget );
88+
89+
private:
90+
void updatePreview();
91+
92+
private:
93+
std::unique_ptr<QgsAbstract3DSymbol> mSymbol = nullptr;
94+
QPointer<QgsVectorLayer> mLayer;
95+
QString mDialogTitle;
96+
};
97+
98+
#endif // QGS3DSYMBOLBUTTON_H

src/app/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ if (WITH_3D)
380380
3d/qgsphongmaterialwidget.cpp
381381
3d/qgsphongtexturedmaterialwidget.cpp
382382
3d/qgsrulebased3drendererwidget.cpp
383+
3d/qgs3dsymbolbutton.cpp
383384
3d/qgssimplelinematerialwidget.cpp
384385
3d/qgssymbol3dwidget.cpp
385386
3d/qgstiledscenelayer3drendererwidget.cpp

0 commit comments

Comments
 (0)