31#include <QStandardItem>
32#include <QStandardItemModel>
36#include "moc_qgseffectstackpropertieswidget.cpp"
38using namespace Qt::StringLiterals;
42static const int EFFECT_ITEM_TYPE = QStandardItem::UserType + 1;
44class EffectItem :
public QStandardItem
47 EffectItem( QgsPaintEffect *effect, QgsEffectStackPropertiesWidget *propertiesWidget )
51 mWidget = propertiesWidget;
54 void setEffect( QgsPaintEffect *effect )
60 int type()
const override {
return EFFECT_ITEM_TYPE; }
62 QgsPaintEffect *effect()
67 QVariant data(
int role )
const override
69 if ( role == Qt::DisplayRole || role == Qt::EditRole )
73 if ( role == Qt::CheckStateRole )
75 return mEffect->enabled() ? Qt::Checked : Qt::Unchecked;
77 return QStandardItem::data( role );
80 void setData(
const QVariant &value,
int role )
override
82 if ( role == Qt::CheckStateRole )
84 mEffect->setEnabled( value.toBool() );
85 mWidget->updatePreview();
89 QStandardItem::setData( value, role );
94 QgsPaintEffect *mEffect =
nullptr;
95 QgsEffectStackPropertiesWidget *mWidget =
nullptr;
116 this->layout()->setContentsMargins( 0, 0, 0, 0 );
118 mEffectsList->setMaximumHeight(
static_cast<int>(
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 7 ) );
119 mEffectsList->setMinimumHeight( mEffectsList->maximumHeight() );
120 lblPreview->setMaximumWidth( mEffectsList->maximumHeight() );
127 mModel =
new QStandardItemModel();
129 mEffectsList->setModel(
mModel );
131 QItemSelectionModel *selModel = mEffectsList->selectionModel();
146 for (
int i = 0; i <
stack->count(); ++i )
149 if (
stack->effect(
stack->count() - i - 1 )->enabled() )
155 const QModelIndex newIndex = mEffectsList->model()->index( initialRow, 0 );
156 mEffectsList->setCurrentIndex( newIndex );
176 EffectItem *parent =
static_cast<EffectItem *
>(
mModel->invisibleRootItem() );
178 const int count =
stack->count();
179 for (
int i = count - 1; i >= 0; i-- )
181 EffectItem *effectItem =
new EffectItem(
stack->effect( i ),
this );
182 effectItem->setEditable(
false );
183 parent->appendRow( effectItem );
196 const QModelIndex currentIdx = mEffectsList->currentIndex();
197 if ( !currentIdx.isValid() )
200 EffectItem *item =
static_cast<EffectItem *
>(
mModel->itemFromIndex( currentIdx ) );
202 QStandardItem *root =
mModel->invisibleRootItem();
203 const int rowCount = root->rowCount();
204 const int currentRow = item ? item->row() : 0;
206 mUpButton->setEnabled( currentRow > 0 );
207 mDownButton->setEnabled( currentRow < rowCount - 1 );
208 mRemoveButton->setEnabled( rowCount > 1 );
214 QImage previewImage( 100, 100, QImage::Format_ARGB32 );
215 previewImage.fill( Qt::transparent );
216 painter.begin( &previewImage );
217 painter.setRenderHint( QPainter::Antialiasing );
223 QPainter previewPicPainter;
224 previewPicPainter.begin( &previewPic );
225 previewPicPainter.setPen( Qt::red );
226 previewPicPainter.setBrush( QColor( 255, 100, 100, 255 ) );
227 previewPicPainter.drawEllipse( QPoint( 50, 50 ), 20, 20 );
228 previewPicPainter.end();
229 mStack->render( previewPic, context );
233 context.
painter()->translate( 20, 20 );
238 lblPreview->setPixmap( QPixmap::fromImage( previewImage ) );
244 const QModelIndex idx = mEffectsList->currentIndex();
245 if ( !idx.isValid() )
248 EffectItem *item =
static_cast<EffectItem *
>(
mModel->itemFromIndex( idx ) );
269 const int index = stackedWidget->addWidget( widget );
270 stackedWidget->setCurrentIndex( index );
283 mStack->insertEffect( 0, newEffect );
285 EffectItem *newEffectItem =
new EffectItem( newEffect,
this );
286 mModel->invisibleRootItem()->insertRow(
mStack->count() - 1, newEffectItem );
288 mEffectsList->setCurrentIndex(
mModel->indexFromItem( newEffectItem ) );
296 const int row = item->row();
297 QStandardItem *root =
mModel->invisibleRootItem();
299 const int layerIdx = root->rowCount() - row - 1;
302 mModel->invisibleRootItem()->removeRow( row );
304 const int newSelection = std::min( row, root->rowCount() - 1 );
305 const QModelIndex newIdx = root->child( newSelection )->index();
306 mEffectsList->setCurrentIndex( newIdx );
330 const int row = item->row();
332 QStandardItem *root =
mModel->invisibleRootItem();
334 const int layerIdx = root->rowCount() - row - 1;
337 mStack->insertEffect( layerIdx - offset, tmpEffect );
339 QList<QStandardItem *> toMove = root->takeRow( row );
340 root->insertRows( row + offset, toMove );
342 const QModelIndex newIdx = toMove[0]->index();
343 mEffectsList->setCurrentIndex( newIdx );
352 item->setEffect( newEffect );
354 QStandardItem *root =
mModel->invisibleRootItem();
355 const int effectIdx = root->rowCount() - item->row() - 1;
356 mStack->changeEffect( effectIdx, newEffect );
369 :
QgsDialog( parent, f, QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok )
372 setWindowTitle( tr(
"Effect Properties" ) );
375 QDialogButtonBox *
buttonBox = this->findChild<QDialogButtonBox *>( QString(), Qt::FindDirectChildrenOnly );
376 connect(
buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsEffectStackPropertiesDialog::showHelp );
391void QgsEffectStackPropertiesDialog::showHelp()
393 QgsHelp::openHelp( u
"working_with_vector/vector_properties.html#draw-effects"_s );
405 QHBoxLayout *layout =
new QHBoxLayout();
406 layout->setContentsMargins( 0, 0, 0, 0 );
407 layout->setSpacing( 6 );
410 mEnabledCheckBox =
new QCheckBox(
this );
411 mEnabledCheckBox->setText( tr(
"Draw effects" ) );
412 layout->addWidget( mEnabledCheckBox );
414 mButton =
new QToolButton(
this );
416 mButton->setToolTip( tr(
"Customize effects" ) );
417 layout->addWidget( mButton );
419 setFocusPolicy( Qt::StrongFocus );
420 setFocusProxy( mEnabledCheckBox );
422 connect( mButton, &QAbstractButton::clicked,
this, &QgsEffectStackCompactWidget::showDialog );
423 connect( mEnabledCheckBox, &QAbstractButton::toggled,
this, &QgsEffectStackCompactWidget::enableToggled );
434 mEnabledCheckBox->setChecked(
false );
435 mEnabledCheckBox->setEnabled(
false );
436 mButton->setEnabled(
false );
450 mEnabledCheckBox->setChecked( mStack->enabled() );
452 mButton->setEnabled( mStack->enabled() );
462 mPreviewPicture = picture;
465void QgsEffectStackCompactWidget::showDialog()
483 QgsEffectStackPropertiesDialog dlg( clone,
this );
484 dlg.setPreviewPicture( mPreviewPicture );
486 if ( dlg.exec() == QDialog::Accepted )
494void QgsEffectStackCompactWidget::enableToggled(
bool checked )
501 mStack->setEnabled( checked );
502 mButton->setEnabled( checked );
506void QgsEffectStackCompactWidget::updateAcceptWidget(
QgsPanelWidget *panel )
508 QgsEffectStackPropertiesWidget *widget = qobject_cast<QgsEffectStackPropertiesWidget *>( panel );
509 *mStack = *widget->
stack();
514void QgsEffectStackCompactWidget::updateEffectLive()
516 QgsEffectStackPropertiesWidget *widget = qobject_cast<QgsEffectStackPropertiesWidget *>( sender() );
517 *mStack = *widget->
stack();
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
static const double UI_SCALE_FACTOR
UI scaling factor.
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
QDialogButtonBox * buttonBox()
Returns the button box.
QgsDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags, QDialogButtonBox::StandardButtons buttons=QDialogButtonBox::Close, Qt::Orientation orientation=Qt::Horizontal)
Constructor for QgsDialog.
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
A paint effect which draws the source picture with minor or no alterations.
void setPreviewPicture(const QPicture &picture)
Sets the picture to use for effect previews for the dialog.
QgsEffectStackPropertiesWidget * mPropertiesWidget
QgsEffectStackPropertiesDialog(QgsEffectStack *stack, QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
QgsEffectStackPropertiesDialog constructor.
QgsEffectStack * stack()
Returns effect stack attached to the dialog.
A paint effect which consists of a stack of other chained paint effects.
QgsEffectStack * clone() const override
Duplicates an effect by creating a deep copy of the effect.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
QgsPaintEffectAbstractMetadata * effectMetadata(const QString &name) const
Returns the metadata for a specific effect.
Base class for visual effects which can be applied to QPicture drawings.
void setEnabled(bool enabled)
Sets whether the effect is enabled.
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.