QGIS API Documentation  3.25.0-Master (dec16ba68b)
qgssymbolbutton.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbolbutton.h
3  -----------------
4  Date : July 2017
5  Copyright : (C) 2017 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  ***************************************************************************/
15 
16 #include "qgssymbolbutton.h"
17 #include "qgspanelwidget.h"
18 #include "qgsexpressioncontext.h"
20 #include "qgsvectorlayer.h"
22 #include "qgsstyle.h"
23 #include "qgscolorwidgets.h"
24 #include "qgscolorschemeregistry.h"
25 #include "qgscolorswatchgrid.h"
26 #include "qgssymbollayerutils.h"
27 #include "qgsapplication.h"
28 #include "qgsguiutils.h"
30 #include "qgsgui.h"
31 #include "qgscolordialog.h"
32 #include "qgsfillsymbol.h"
33 #include "qgslinesymbol.h"
34 #include "qgsmarkersymbol.h"
35 
36 #include <QMenu>
37 #include <QClipboard>
38 #include <QDrag>
39 #include <QBuffer>
40 
41 QgsSymbolButton::QgsSymbolButton( QWidget *parent, const QString &dialogTitle )
42  : QToolButton( parent )
43  , mDialogTitle( dialogTitle.isEmpty() ? tr( "Symbol Settings" ) : dialogTitle )
44 {
45  mSymbol.reset( QgsFillSymbol::createSimple( QVariantMap() ) );
46 
47  setAcceptDrops( true );
48  connect( this, &QAbstractButton::clicked, this, &QgsSymbolButton::showSettingsDialog );
49 
50  //setup dropdown menu
51  mMenu = new QMenu( this );
52  connect( mMenu, &QMenu::aboutToShow, this, &QgsSymbolButton::prepareMenu );
53  setMenu( mMenu );
54  setPopupMode( QToolButton::MenuButtonPopup );
55 
56  //make sure height of button looks good under different platforms
57  const QSize size = QToolButton::minimumSizeHint();
58  const int fontHeight = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
59  mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight ) );
60 }
61 
63 
65 {
66 
67  return mSizeHint;
68 }
69 
71 {
72  return mSizeHint;
73 }
74 
76 {
77  if ( type != mType )
78  {
79  switch ( type )
80  {
82  mSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
83  break;
84 
86  mSymbol.reset( QgsLineSymbol::createSimple( QVariantMap() ) );
87  break;
88 
90  mSymbol.reset( QgsFillSymbol::createSimple( QVariantMap() ) );
91  break;
92 
94  break;
95  }
96  }
97  updatePreview();
98  mType = type;
99 }
100 
101 void QgsSymbolButton::showSettingsDialog()
102 {
103  QgsExpressionContext context;
104  if ( mExpressionContextGenerator )
105  context = mExpressionContextGenerator->createExpressionContext();
106  else
107  {
109  }
110 
111  QgsSymbol *newSymbol = nullptr;
112  if ( mSymbol )
113  {
114  newSymbol = mSymbol->clone();
115  }
116  else
117  {
118  switch ( mType )
119  {
122  break;
125  break;
128  break;
130  break;
131  }
132  }
133 
134  QgsSymbolWidgetContext symbolContext;
135  symbolContext.setExpressionContext( &context );
136  symbolContext.setMapCanvas( mMapCanvas );
137  symbolContext.setMessageBar( mMessageBar );
138 
140  if ( panel && panel->dockMode() )
141  {
142  QgsSymbolSelectorWidget *d = new QgsSymbolSelectorWidget( newSymbol, QgsStyle::defaultStyle(), mLayer, panel );
143  d->setPanelTitle( mDialogTitle );
144  d->setContext( symbolContext );
145  connect( d, &QgsPanelWidget::widgetChanged, this, &QgsSymbolButton::updateSymbolFromWidget );
146  connect( d, &QgsPanelWidget::panelAccepted, this, &QgsSymbolButton::cleanUpSymbolSelector );
147  panel->openPanel( d );
148  }
149  else
150  {
151  QgsSymbolSelectorDialog dialog( newSymbol, QgsStyle::defaultStyle(), mLayer, this );
152  dialog.setWindowTitle( mDialogTitle );
153  dialog.setContext( symbolContext );
154  if ( dialog.exec() )
155  {
156  setSymbol( newSymbol );
157  }
158  else
159  {
160  delete newSymbol;
161  }
162 
163  // reactivate button's window
164  activateWindow();
165  }
166 }
167 
168 void QgsSymbolButton::updateSymbolFromWidget()
169 {
170  if ( QgsSymbolSelectorWidget *w = qobject_cast<QgsSymbolSelectorWidget *>( sender() ) )
171  setSymbol( w->symbol()->clone() );
172 }
173 
174 void QgsSymbolButton::cleanUpSymbolSelector( QgsPanelWidget *container )
175 {
176  QgsSymbolSelectorWidget *w = qobject_cast<QgsSymbolSelectorWidget *>( container );
177  if ( !w )
178  return;
179 
180  delete w->symbol();
181 }
182 
184 {
185  return mMapCanvas;
186 }
187 
189 {
190  mMapCanvas = mapCanvas;
191 }
192 
194 {
195  mMessageBar = bar;
196 }
197 
199 {
200  return mMessageBar;
201 }
202 
204 {
205  return mLayer;
206 }
207 
209 {
210  mLayer = layer;
211 }
212 
214 {
215  mExpressionContextGenerator = generator;
216 }
217 
219 {
220  mSymbol.reset( symbol );
221  updatePreview();
222  emit changed();
223 }
224 
225 void QgsSymbolButton::setColor( const QColor &color )
226 {
227  if ( !mSymbol )
228  return;
229 
230  QColor opaque = color;
231  opaque.setAlphaF( 1.0 );
232 
233  if ( opaque == mSymbol->color() )
234  return;
235 
236  mSymbol->setColor( opaque );
237  updatePreview();
238  emit changed();
239 }
240 
242 {
243  QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::symbolToMimeData( mSymbol.get() ) );
244 }
245 
247 {
248  std::unique_ptr< QgsSymbol > symbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
249  if ( symbol && symbol->type() == mType )
250  setSymbol( symbol.release() );
251 }
252 
254 {
255  QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
256 }
257 
259 {
260  QColor clipColor;
261  bool hasAlpha = false;
262  if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
263  {
264  //paste color
265  setColor( clipColor );
267  }
268 }
269 
270 void QgsSymbolButton::mousePressEvent( QMouseEvent *e )
271 {
272  if ( mPickingColor )
273  {
274  //don't show dialog if in color picker mode
275  e->accept();
276  return;
277  }
278 
279  if ( e->button() == Qt::RightButton )
280  {
281  QToolButton::showMenu();
282  return;
283  }
284  else if ( e->button() == Qt::LeftButton )
285  {
286  mDragStartPosition = e->pos();
287  }
288  QToolButton::mousePressEvent( e );
289 }
290 
291 void QgsSymbolButton::mouseMoveEvent( QMouseEvent *e )
292 {
293  if ( mPickingColor )
294  {
295  updatePreview( QgsGui::sampleColor( e->globalPos() ) );
296  e->accept();
297  return;
298  }
299 
300  //handle dragging colors/symbols from button
301 
302  if ( !( e->buttons() & Qt::LeftButton ) )
303  {
304  //left button not depressed, so not a drag
305  QToolButton::mouseMoveEvent( e );
306  return;
307  }
308 
309  if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
310  {
311  //mouse not moved, so not a drag
312  QToolButton::mouseMoveEvent( e );
313  return;
314  }
315 
316  //user is dragging
317  QDrag *drag = new QDrag( this );
318  drag->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
319  drag->setPixmap( QgsColorWidget::createDragIcon( mSymbol->color() ) );
320  drag->exec( Qt::CopyAction );
321  setDown( false );
322 }
323 
325 {
326  if ( mPickingColor )
327  {
328  //end color picking operation by sampling the color under cursor
329  stopPicking( e->globalPos() );
330  e->accept();
331  return;
332  }
333 
334  QToolButton::mouseReleaseEvent( e );
335 }
336 
337 void QgsSymbolButton::keyPressEvent( QKeyEvent *e )
338 {
339  if ( !mPickingColor )
340  {
341  //if not picking a color, use default tool button behavior
342  QToolButton::keyPressEvent( e );
343  return;
344  }
345 
346  //cancel picking, sampling the color if space was pressed
347  stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
348 }
349 
350 void QgsSymbolButton::dragEnterEvent( QDragEnterEvent *e )
351 {
352  //is dragged data valid color data?
353  QColor mimeColor;
354  bool hasAlpha = false;
355 
356  if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
357  {
358  //if so, we accept the drag, and temporarily change the button's color
359  //to match the dragged color. This gives immediate feedback to the user
360  //that colors can be dropped here
361  e->acceptProposedAction();
362  updatePreview( mimeColor );
363  }
364 }
365 
366 void QgsSymbolButton::dragLeaveEvent( QDragLeaveEvent *e )
367 {
368  Q_UNUSED( e )
369  //reset button color
370  updatePreview();
371 }
372 
373 void QgsSymbolButton::dropEvent( QDropEvent *e )
374 {
375  //is dropped data valid format data?
376  QColor mimeColor;
377  bool hasAlpha = false;
378  if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
379  {
380  //accept drop and set new color
381  e->acceptProposedAction();
382  mimeColor.setAlphaF( 1.0 );
383  mSymbol->setColor( mimeColor );
385  updatePreview();
386  emit changed();
387  }
388  updatePreview();
389 }
390 
391 void QgsSymbolButton::wheelEvent( QWheelEvent *event )
392 {
393  if ( isEnabled() && mSymbol )
394  {
395  bool symbolChanged = false;
396  const double increment = ( ( event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1 ) *
397  event->angleDelta().y() > 0 ? 1 : -1;
398  switch ( mSymbol->type() )
399  {
401  {
402  QgsMarkerSymbol *marker = qgis::down_cast<QgsMarkerSymbol *>( mSymbol.get() );
403  if ( marker )
404  {
405  const double size = std::max( 0.0, marker->size() + increment );
406  marker->setSize( size );
407  symbolChanged = true;
408  }
409  break;
410  }
411 
413  {
414  QgsLineSymbol *line = qgis::down_cast<QgsLineSymbol *>( mSymbol.get() );
415  if ( line )
416  {
417  const double width = std::max( 0.0, line->width() + increment );
418  line->setWidth( width );
419  symbolChanged = true;
420  }
421  break;
422  }
423 
426  break;
427  }
428 
429  if ( symbolChanged )
430  {
431  updatePreview();
432  emit changed();
433  }
434 
435  event->accept();
436  }
437  else
438  {
439  QToolButton::wheelEvent( event );
440  }
441 }
442 
443 void QgsSymbolButton::prepareMenu()
444 {
445  //we need to tear down and rebuild this menu every time it is shown. Otherwise the space allocated to any
446  //QgsColorSwatchGridAction is not recalculated by Qt and the swatch grid may not be the correct size
447  //for the number of colors shown in the grid. Note that we MUST refresh color swatch grids every time this
448  //menu is opened, otherwise color schemes like the recent color scheme grid are meaningless
449  mMenu->clear();
450 
451  QAction *configureAction = new QAction( tr( "Configure Symbol…" ), this );
452  mMenu->addAction( configureAction );
453  connect( configureAction, &QAction::triggered, this, &QgsSymbolButton::showSettingsDialog );
454 
455  QAction *copySymbolAction = new QAction( tr( "Copy Symbol" ), this );
456  copySymbolAction->setEnabled( !isNull() );
457  mMenu->addAction( copySymbolAction );
458  connect( copySymbolAction, &QAction::triggered, this, &QgsSymbolButton::copySymbol );
459 
460  QAction *pasteSymbolAction = new QAction( tr( "Paste Symbol" ), this );
461  //enable or disable paste action based on current clipboard contents. We always show the paste
462  //action, even if it's disabled, to give hint to the user that pasting symbols is possible
463  std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
464  if ( tempSymbol && tempSymbol->type() == mType )
465  {
466  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
467  pasteSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( tempSymbol.get(), QSize( iconSize, iconSize ), 1 ) );
468  }
469  else
470  {
471  pasteSymbolAction->setEnabled( false );
472  }
473  mMenu->addAction( pasteSymbolAction );
474  connect( pasteSymbolAction, &QAction::triggered, this, &QgsSymbolButton::pasteSymbol );
475 
476  if ( mShowNull )
477  {
478  QAction *nullAction = new QAction( tr( "Clear Current Symbol" ), this );
479  nullAction->setEnabled( !isNull() );
480  mMenu->addAction( nullAction );
481  connect( nullAction, &QAction::triggered, this, &QgsSymbolButton::setToNull );
482  }
483 
484  if ( mSymbol )
485  {
486  mMenu->addSeparator();
487 
488  QgsColorWheel *colorWheel = new QgsColorWheel( mMenu );
489  colorWheel->setColor( mSymbol->color() );
490  QgsColorWidgetAction *colorAction = new QgsColorWidgetAction( colorWheel, mMenu, mMenu );
491  colorAction->setDismissOnColorSelection( false );
492  connect( colorAction, &QgsColorWidgetAction::colorChanged, this, &QgsSymbolButton::setColor );
493  mMenu->addAction( colorAction );
494 
496  QColor alphaColor = mSymbol->color();
497  alphaColor.setAlphaF( mSymbol->opacity() );
498  alphaRamp->setColor( alphaColor );
499  QgsColorWidgetAction *alphaAction = new QgsColorWidgetAction( alphaRamp, mMenu, mMenu );
500  alphaAction->setDismissOnColorSelection( false );
501  connect( alphaAction, &QgsColorWidgetAction::colorChanged, this, [ = ]( const QColor & color )
502  {
503  const double opacity = color.alphaF();
504  mSymbol->setOpacity( opacity );
505  updatePreview();
506  emit changed();
507  } );
508  connect( colorAction, &QgsColorWidgetAction::colorChanged, alphaRamp, [alphaRamp]( const QColor & color ) { alphaRamp->setColor( color, false ); }
509  );
510  mMenu->addAction( alphaAction );
511 
512  //get schemes with ShowInColorButtonMenu flag set
513  QList< QgsColorScheme * > schemeList = QgsApplication::colorSchemeRegistry()->schemes( QgsColorScheme::ShowInColorButtonMenu );
514  QList< QgsColorScheme * >::iterator it = schemeList.begin();
515  for ( ; it != schemeList.end(); ++it )
516  {
517  QgsColorSwatchGridAction *colorAction = new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral( "symbology" ), this );
518  colorAction->setBaseColor( mSymbol->color() );
519  mMenu->addAction( colorAction );
520  connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsSymbolButton::setColor );
521  connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsSymbolButton::addRecentColor );
522  }
523 
524  mMenu->addSeparator();
525 
526  QAction *copyColorAction = new QAction( tr( "Copy Color" ), this );
527  mMenu->addAction( copyColorAction );
528  connect( copyColorAction, &QAction::triggered, this, &QgsSymbolButton::copyColor );
529 
530  QAction *pasteColorAction = new QAction( tr( "Paste Color" ), this );
531  //enable or disable paste action based on current clipboard contents. We always show the paste
532  //action, even if it's disabled, to give hint to the user that pasting colors is possible
533  QColor clipColor;
534  bool hasAlpha = false;
535  if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
536  {
537  pasteColorAction->setIcon( createColorIcon( clipColor ) );
538  }
539  else
540  {
541  pasteColorAction->setEnabled( false );
542  }
543  mMenu->addAction( pasteColorAction );
544  connect( pasteColorAction, &QAction::triggered, this, &QgsSymbolButton::pasteColor );
545 
546  QAction *pickColorAction = new QAction( tr( "Pick Color" ), this );
547  mMenu->addAction( pickColorAction );
548  connect( pickColorAction, &QAction::triggered, this, &QgsSymbolButton::activatePicker );
549 
550  QAction *chooseColorAction = new QAction( tr( "Choose Color…" ), this );
551  mMenu->addAction( chooseColorAction );
552  connect( chooseColorAction, &QAction::triggered, this, &QgsSymbolButton::showColorDialog );
553  }
554 }
555 
556 void QgsSymbolButton::addRecentColor( const QColor &color )
557 {
559 }
560 
561 void QgsSymbolButton::activatePicker()
562 {
563  //activate picker color
564  QApplication::setOverrideCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Sampler ) );
565  grabMouse();
566  grabKeyboard();
567  mPickingColor = true;
568  setMouseTracking( true );
569 }
570 
571 
573 {
574  if ( e->type() == QEvent::EnabledChange )
575  {
576  updatePreview();
577  }
578  QToolButton::changeEvent( e );
579 }
580 
581 void QgsSymbolButton::showEvent( QShowEvent *e )
582 {
583  updatePreview();
584  QToolButton::showEvent( e );
585 }
586 
587 void QgsSymbolButton::resizeEvent( QResizeEvent *event )
588 {
589  QToolButton::resizeEvent( event );
590  //recalculate icon size and redraw icon
591  mIconSize = QSize();
592  updatePreview();
593 }
594 
595 void QgsSymbolButton::updatePreview( const QColor &color, QgsSymbol *tempSymbol )
596 {
597  QSize currentIconSize;
598  //icon size is button size with a small margin
599  if ( menu() )
600  {
601  if ( !mIconSize.isValid() )
602  {
603  //calculate size of push button part of widget (ie, without the menu dropdown button part)
604  QStyleOptionToolButton opt;
605  initStyleOption( &opt );
606  const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
607  this );
608  //make sure height of icon looks good under different platforms
609 #ifdef Q_OS_WIN
610  mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
611 #else
612  mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
613 #endif
614  }
615  currentIconSize = mIconSize;
616  }
617  else
618  {
619  //no menu
620 #ifdef Q_OS_WIN
621  currentIconSize = QSize( width() - 10, height() - 6 );
622 #else
623  currentIconSize = QSize( width() - 10, height() - 12 );
624 #endif
625  }
626 
627  if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
628  {
629  return;
630  }
631 
632  std::unique_ptr< QgsSymbol > previewSymbol;
633 
634  if ( tempSymbol )
635  {
636  previewSymbol.reset( tempSymbol->clone() );
637  }
638  else if ( mSymbol )
639  {
640  previewSymbol.reset( mSymbol->clone() );
641  }
642  else
643  {
644  setIconSize( currentIconSize );
645  setIcon( QIcon() );
646  setToolTip( QString( ) );
647  return;
648  }
649 
650  if ( color.isValid() )
651  previewSymbol->setColor( color );
652 
653  //create an icon pixmap
654  const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
655  setIconSize( currentIconSize );
656  setIcon( icon );
657 
658  // set tooltip
659  // create very large preview image
660  const int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
661  const int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
662 
663  const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
664  QByteArray data;
665  QBuffer buffer( &data );
666  pm.save( &buffer, "PNG", 100 );
667  setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3'>" ).arg( QString( data.toBase64() ) ) );
668 }
669 
670 bool QgsSymbolButton::colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha )
671 {
672  hasAlpha = false;
673  const QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha );
674 
675  if ( mimeColor.isValid() )
676  {
677  resultColor = mimeColor;
678  return true;
679  }
680 
681  //could not get color from mime data
682  return false;
683 }
684 
685 QPixmap QgsSymbolButton::createColorIcon( const QColor &color ) const
686 {
687  //create an icon pixmap
688  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
689  QPixmap pixmap( iconSize, iconSize );
690  pixmap.fill( Qt::transparent );
691 
692  QPainter p;
693  p.begin( &pixmap );
694 
695  //draw color over pattern
696  p.setBrush( QBrush( color ) );
697 
698  //draw border
699  p.setPen( QColor( 197, 197, 197 ) );
700  p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
701  p.end();
702  return pixmap;
703 }
704 
705 void QgsSymbolButton::stopPicking( QPoint eventPos, bool samplingColor )
706 {
707  //release mouse and keyboard, and reset cursor
708  releaseMouse();
709  releaseKeyboard();
710  QgsApplication::restoreOverrideCursor();
711  setMouseTracking( false );
712  mPickingColor = false;
713 
714  if ( !samplingColor )
715  {
716  //not sampling color, restore old icon
717  updatePreview();
718  return;
719  }
720 
721  const QColor newColor = QgsGui::sampleColor( eventPos );
722  setColor( newColor );
723  addRecentColor( newColor );
724 }
725 
726 void QgsSymbolButton::showColorDialog()
727 {
728  if ( !mSymbol )
729  return;
730 
732  if ( panel && panel->dockMode() )
733  {
734  const QColor currentColor = mSymbol->color();
736  colorWidget->setPanelTitle( tr( "Symbol Color" ) );
737  colorWidget->setAllowOpacity( true );
738 
739  if ( currentColor.isValid() )
740  {
741  colorWidget->setPreviousColor( currentColor );
742  }
743 
744  connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [ = ]( const QColor & newColor )
745  {
746  if ( newColor.isValid() )
747  {
748  setColor( newColor );
749  }
750  } );
751  panel->openPanel( colorWidget );
752  return;
753  }
754 
755  QgsColorDialog dialog( this, Qt::WindowFlags(), mSymbol->color() );
756  dialog.setTitle( tr( "Symbol Color" ) );
757  dialog.setAllowOpacity( true );
758 
759  if ( dialog.exec() && dialog.color().isValid() )
760  {
761  setColor( dialog.color() );
762  }
763 
764  // reactivate button's window
765  activateWindow();
766 }
767 
768 void QgsSymbolButton::setDialogTitle( const QString &title )
769 {
770  mDialogTitle = title;
771 }
772 
774 {
775  return mDialogTitle;
776 }
777 
779 {
780  return mSymbol.get();
781 }
782 
783 void QgsSymbolButton::setShowNull( bool showNull )
784 {
785  mShowNull = showNull;
786 }
787 
789 {
790  return mShowNull;
791 }
792 
794 {
795  return !mSymbol;
796 }
797 
799 {
800  setSymbol( nullptr );
801 }
SymbolType
Symbol types.
Definition: qgis.h:205
@ Marker
Marker symbol.
@ Line
Line symbol.
@ Fill
Fill symbol.
@ Hybrid
Hybrid symbol.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:1785
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
A custom QGIS dialog for selecting a color.
A color ramp widget.
@ Horizontal
Horizontal ramp.
QList< QgsColorScheme * > schemes() const
Returns all color schemes in the registry.
@ ShowInColorButtonMenu
Show scheme in color button drop-down menu.
A color swatch grid which can be embedded into a menu.
void setBaseColor(const QColor &baseColor)
Sets the base color for the color grid.
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
A color wheel widget.
void setColor(const QColor &color, bool emitSignals=false) override
An action containing a color widget, which can be embedded into a menu.
void setDismissOnColorSelection(bool dismiss)
Sets whether the parent menu should be dismissed and closed when a color is selected from the action'...
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
static QPixmap createDragIcon(const QColor &color)
Create an icon for dragging colors.
virtual void setColor(const QColor &color, bool emitSignals=false)
Sets the color for the widget.
@ Alpha
Alpha component (opacity) of color.
A custom QGIS widget for selecting a color, including options for selecting colors via hue wheel,...
@ LayoutVertical
Use a narrower, vertically stacked layout.
void currentColorChanged(const QColor &color)
Emitted when the dialog's color changes.
void setPreviousColor(const QColor &color)
Sets the color to show in an optional "previous color" section.
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color dialog.
Abstract interface for generating an expression context.
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
static QColor sampleColor(QPoint point)
Samples the color on screen at the specified global point (pixel).
Definition: qgsgui.cpp:237
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
void setWidth(double width) const
Sets the width for the whole line symbol.
double width() const
Returns the estimated width for the whole symbol, which is the maximum width of all marker symbol lay...
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
A marker symbol type, for rendering Point and MultiPoint geometries.
void setSize(double size) const
Sets the size for the whole symbol.
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
double size() const
Returns the estimated size for the whole symbol, which is the maximum size of all marker symbol layer...
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:61
Base class for any widget that can be shown as a inline panel.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void panelAccepted(QgsPanelWidget *panel)
Emitted when the panel is accepted by the user.
void widgetChanged()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
bool dockMode()
Returns the dock mode state.
static void addRecentColor(const QColor &color)
Adds a color to the list of recent colors.
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:143
void wheelEvent(QWheelEvent *event) override
void mouseReleaseEvent(QMouseEvent *e) override
QSize sizeHint() const override
void changeEvent(QEvent *e) override
void setColor(const QColor &color)
Sets the current color for the symbol.
void copySymbol()
Copies the current symbol to the clipboard.
QgsSymbolButton(QWidget *parent=nullptr, const QString &dialogTitle=QString())
Construct a new symbol button.
void copyColor()
Copies the current symbol color to the clipboard.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
void pasteSymbol()
Pastes a symbol from the clipboard.
void setSymbol(QgsSymbol *symbol)
Sets the symbol for the button.
void mousePressEvent(QMouseEvent *e) override
void dragEnterEvent(QDragEnterEvent *e) override
void showEvent(QShowEvent *e) override
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type which the button requires.
void setDialogTitle(const QString &title)
Sets the title for the symbol settings dialog window.
void keyPressEvent(QKeyEvent *e) override
void setLayer(QgsVectorLayer *layer)
Sets a layer to associate with the widget.
void resizeEvent(QResizeEvent *event) override
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
QSize minimumSizeHint() const override
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to associate with the widget.
void dropEvent(QDropEvent *e) override
void pasteColor()
Pastes a color from the clipboard to the symbol.
void changed()
Emitted when the symbol's settings are changed.
void dragLeaveEvent(QDragLeaveEvent *e) override
void setToNull()
Sets symbol to to null.
void setShowNull(bool showNull)
Sets whether a set to null (clear) option is shown in the button's drop-down menu.
QgsVectorLayer * layer() const
Returns the layer associated with the widget.
QgsSymbol * symbol()
Returns the current symbol defined by the button.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
void mouseMoveEvent(QMouseEvent *e) override
bool isNull() const
Returns true if the current symbol is null.
bool showNull() const
Returns whether the set to null (clear) option is shown in the button's drop-down menu.
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
static QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr, const QgsLegendPatchShape *shape=nullptr)
Returns a pixmap preview for a color ramp.
static QMimeData * symbolToMimeData(const QgsSymbol *symbol)
Creates new mime data from a symbol.
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
Symbol selector widget that can be used to select and build a symbol.
QgsSymbol * symbol()
Returns the symbol that is currently active in the widget.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
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.
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:371
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Represents a vector layer which manages a vector based data sets.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...