QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
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 "moc_qgssymbolbutton.cpp"
18#include "qgspanelwidget.h"
21#include "qgsvectorlayer.h"
23#include "qgsstyle.h"
24#include "qgscolorwidgets.h"
26#include "qgscolorswatchgrid.h"
27#include "qgssymbollayerutils.h"
28#include "qgsapplication.h"
29#include "qgsguiutils.h"
31#include "qgsgui.h"
32#include "qgscolordialog.h"
33#include "qgsfillsymbol.h"
34#include "qgslinesymbol.h"
35#include "qgsmarkersymbol.h"
36
37#include <QMenu>
38#include <QClipboard>
39#include <QDrag>
40#include <QBuffer>
41
42QgsSymbolButton::QgsSymbolButton( QWidget *parent, const QString &dialogTitle )
43 : QToolButton( parent )
44 , mDialogTitle( dialogTitle.isEmpty() ? tr( "Symbol Settings" ) : dialogTitle )
45{
46 mSymbol.reset( QgsFillSymbol::createSimple( QVariantMap() ) );
47
48 setAcceptDrops( true );
49 connect( this, &QAbstractButton::clicked, this, &QgsSymbolButton::showSettingsDialog );
50
51 //setup dropdown menu
52 mMenu = new QMenu( this );
53 connect( mMenu, &QMenu::aboutToShow, this, &QgsSymbolButton::prepareMenu );
54 setMenu( mMenu );
55 setPopupMode( QToolButton::MenuButtonPopup );
56
57 updateSizeHint();
58}
59
60void QgsSymbolButton::updateSizeHint()
61{
62 //make sure height of button looks good under different platforms
63 const QSize size = QToolButton::minimumSizeHint();
64 const int fontHeight = static_cast<int>( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
65 switch ( mType )
66 {
68 if ( mSymbol )
69 {
70 mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight * 3 ) );
71 setMaximumWidth( mSizeHint.height() * 1.5 );
72 setMinimumWidth( maximumWidth() );
73 }
74 else
75 {
76 mSizeHint = QSize( size.width(), fontHeight );
77 setMaximumWidth( 999999 );
78 mSizeHint.setWidth( QToolButton::sizeHint().width() );
79 }
80 break;
81
85 mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight ) );
86 break;
87 }
88
89 setMinimumHeight( mSizeHint.height() );
90
91 updateGeometry();
92}
93
95
97{
98 return mSizeHint;
99}
100
102{
103 return mSizeHint;
104}
105
107{
108 if ( type != mType )
109 {
110 switch ( type )
111 {
113 mSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
114 break;
115
117 mSymbol.reset( QgsLineSymbol::createSimple( QVariantMap() ) );
118 break;
119
121 mSymbol.reset( QgsFillSymbol::createSimple( QVariantMap() ) );
122 break;
123
125 break;
126 }
127 }
128 mType = type;
129 updateSizeHint();
130 updatePreview();
131}
132
133void QgsSymbolButton::showSettingsDialog()
134{
135 QgsExpressionContext context;
136 if ( mExpressionContextGenerator )
137 context = mExpressionContextGenerator->createExpressionContext();
138 else
139 {
141 }
142
143 std::unique_ptr<QgsSymbol> newSymbol;
144 if ( mSymbol )
145 {
146 newSymbol.reset( mSymbol->clone() );
147 }
148 else
149 {
150 switch ( mType )
151 {
154 break;
157 break;
160 break;
162 break;
163 }
164 }
165
166 QgsSymbolWidgetContext symbolContext;
167 symbolContext.setExpressionContext( &context );
168 symbolContext.setMapCanvas( mMapCanvas );
169 symbolContext.setMessageBar( mMessageBar );
170
172 if ( panel && panel->dockMode() )
173 {
175 widget->setPanelTitle( mDialogTitle );
176 widget->setContext( symbolContext );
177 connect( widget, &QgsPanelWidget::widgetChanged, this, [=] { updateSymbolFromWidget( widget ); } );
178 panel->openPanel( widget );
179 }
180 else
181 {
182 QgsSymbolSelectorDialog dialog( newSymbol.get(), QgsStyle::defaultStyle(), mLayer, this );
183 dialog.setWindowTitle( mDialogTitle );
184 dialog.setContext( symbolContext );
185 if ( dialog.exec() )
186 {
187 setSymbol( newSymbol.release() );
188 }
189
190 // reactivate button's window
191 activateWindow();
192 }
193}
194
195void QgsSymbolButton::updateSymbolFromWidget( QgsSymbolSelectorWidget *widget )
196{
197 setSymbol( widget->symbol()->clone() );
198}
199
201{
202 return mMapCanvas;
203}
204
206{
207 mMapCanvas = mapCanvas;
208}
209
211{
212 mMessageBar = bar;
213}
214
216{
217 return mMessageBar;
218}
219
221{
222 return mLayer;
223}
224
226{
227 mLayer = layer;
228}
229
231{
232 mExpressionContextGenerator = generator;
233}
234
236{
237 mDefaultSymbol.reset( symbol );
238}
239
241{
242 return mDefaultSymbol.get();
243}
244
246{
247 mSymbol.reset( symbol );
248 updateSizeHint();
249 updatePreview();
250 emit changed();
251}
252
253void QgsSymbolButton::setColor( const QColor &color )
254{
255 if ( !mSymbol )
256 return;
257
258 QColor opaque = color;
259 opaque.setAlphaF( 1.0 );
260
261 if ( opaque == mSymbol->color() )
262 return;
263
264 mSymbol->setColor( opaque );
265 updatePreview();
266 emit changed();
267}
268
270{
271 QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::symbolToMimeData( mSymbol.get() ) );
272}
273
275{
276 std::unique_ptr<QgsSymbol> symbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
277 if ( symbol && symbol->type() == mType )
278 setSymbol( symbol.release() );
279}
280
282{
283 QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
284}
285
287{
288 QColor clipColor;
289 bool hasAlpha = false;
290 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
291 {
292 //paste color
293 setColor( clipColor );
295 }
296}
297
299{
300 if ( mPickingColor )
301 {
302 //don't show dialog if in color picker mode
303 e->accept();
304 return;
305 }
306
307 if ( e->button() == Qt::RightButton )
308 {
309 QToolButton::showMenu();
310 return;
311 }
312 else if ( e->button() == Qt::LeftButton )
313 {
314 mDragStartPosition = e->pos();
315 }
316 QToolButton::mousePressEvent( e );
317}
318
320{
321 if ( mPickingColor )
322 {
323 updatePreview( QgsGui::sampleColor( e->globalPos() ) );
324 e->accept();
325 return;
326 }
327
328 //handle dragging colors/symbols from button
329
330 if ( !( e->buttons() & Qt::LeftButton ) )
331 {
332 //left button not depressed, so not a drag
333 QToolButton::mouseMoveEvent( e );
334 return;
335 }
336
337 if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
338 {
339 //mouse not moved, so not a drag
340 QToolButton::mouseMoveEvent( e );
341 return;
342 }
343
344 //user is dragging
345 QDrag *drag = new QDrag( this );
346 drag->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
347 drag->setPixmap( QgsColorWidget::createDragIcon( mSymbol->color() ) );
348 drag->exec( Qt::CopyAction );
349 setDown( false );
350}
351
353{
354 if ( mPickingColor )
355 {
356 //end color picking operation by sampling the color under cursor
357 stopPicking( e->globalPos() );
358 e->accept();
359 return;
360 }
361
362 QToolButton::mouseReleaseEvent( e );
363}
364
366{
367 if ( !mPickingColor )
368 {
369 //if not picking a color, use default tool button behavior
370 QToolButton::keyPressEvent( e );
371 return;
372 }
373
374 //cancel picking, sampling the color if space was pressed
375 stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
376}
377
378void QgsSymbolButton::dragEnterEvent( QDragEnterEvent *e )
379{
380 //is dragged data valid color data?
381 QColor mimeColor;
382 bool hasAlpha = false;
383
384 if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
385 {
386 //if so, we accept the drag, and temporarily change the button's color
387 //to match the dragged color. This gives immediate feedback to the user
388 //that colors can be dropped here
389 e->acceptProposedAction();
390 updatePreview( mimeColor );
391 }
392}
393
394void QgsSymbolButton::dragLeaveEvent( QDragLeaveEvent *e )
395{
396 Q_UNUSED( e )
397 //reset button color
398 updatePreview();
399}
400
401void QgsSymbolButton::dropEvent( QDropEvent *e )
402{
403 //is dropped data valid format data?
404 QColor mimeColor;
405 bool hasAlpha = false;
406 if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
407 {
408 //accept drop and set new color
409 e->acceptProposedAction();
410 mimeColor.setAlphaF( 1.0 );
411 mSymbol->setColor( mimeColor );
413 updatePreview();
414 emit changed();
415 }
416 updatePreview();
417}
418
419void QgsSymbolButton::wheelEvent( QWheelEvent *event )
420{
421 if ( isEnabled() && mSymbol )
422 {
423 bool symbolChanged = false;
424 const double increment = ( ( event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1 ) * ( event->angleDelta().y() > 0 ? 1 : -1 );
425 switch ( mSymbol->type() )
426 {
428 {
429 QgsMarkerSymbol *marker = qgis::down_cast<QgsMarkerSymbol *>( mSymbol.get() );
430 if ( marker )
431 {
432 const double size = std::max( 0.0, marker->size() + increment );
433 marker->setSize( size );
434 symbolChanged = true;
435 }
436 break;
437 }
438
440 {
441 QgsLineSymbol *line = qgis::down_cast<QgsLineSymbol *>( mSymbol.get() );
442 if ( line )
443 {
444 const double width = std::max( 0.0, line->width() + increment );
445 line->setWidth( width );
446 symbolChanged = true;
447 }
448 break;
449 }
450
453 break;
454 }
455
456 if ( symbolChanged )
457 {
458 updatePreview();
459 emit changed();
460 }
461
462 event->accept();
463 }
464 else
465 {
466 QToolButton::wheelEvent( event );
467 }
468}
469
470void QgsSymbolButton::prepareMenu()
471{
472 //we need to tear down and rebuild this menu every time it is shown. Otherwise the space allocated to any
473 //QgsColorSwatchGridAction is not recalculated by Qt and the swatch grid may not be the correct size
474 //for the number of colors shown in the grid. Note that we MUST refresh color swatch grids every time this
475 //menu is opened, otherwise color schemes like the recent color scheme grid are meaningless
476 mMenu->clear();
477
478 QAction *configureAction = new QAction( tr( "Configure Symbol…" ), this );
479 mMenu->addAction( configureAction );
480 connect( configureAction, &QAction::triggered, this, &QgsSymbolButton::showSettingsDialog );
481
482 QAction *copySymbolAction = new QAction( tr( "Copy Symbol" ), this );
483 copySymbolAction->setEnabled( !isNull() );
484 mMenu->addAction( copySymbolAction );
485 connect( copySymbolAction, &QAction::triggered, this, &QgsSymbolButton::copySymbol );
486
487 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
488
489 QAction *pasteSymbolAction = new QAction( tr( "Paste Symbol" ), this );
490 //enable or disable paste action based on current clipboard contents. We always show the paste
491 //action, even if it's disabled, to give hint to the user that pasting symbols is possible
492 std::unique_ptr<QgsSymbol> tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
493 if ( tempSymbol && tempSymbol->type() == mType )
494 {
495 pasteSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( tempSymbol.get(), QSize( iconSize, iconSize ), 1, nullptr, QgsScreenProperties( screen() ) ) );
496 }
497 else
498 {
499 pasteSymbolAction->setEnabled( false );
500 }
501 mMenu->addAction( pasteSymbolAction );
502 connect( pasteSymbolAction, &QAction::triggered, this, &QgsSymbolButton::pasteSymbol );
503
504 if ( mShowNull )
505 {
506 QAction *nullAction = new QAction( tr( "Clear Current Symbol" ), this );
507 nullAction->setEnabled( !isNull() );
508 mMenu->addAction( nullAction );
509 connect( nullAction, &QAction::triggered, this, &QgsSymbolButton::setToNull );
510 }
511
512 //show default symbol option if set
513 if ( mDefaultSymbol )
514 {
515 QAction *defaultSymbolAction = new QAction( tr( "Default Symbol" ), this );
516 defaultSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( mDefaultSymbol.get(), QSize( iconSize, iconSize ), 1, nullptr, QgsScreenProperties( screen() ) ) );
517 mMenu->addAction( defaultSymbolAction );
518 connect( defaultSymbolAction, &QAction::triggered, this, &QgsSymbolButton::setToDefaultSymbol );
519 }
520
521 if ( mSymbol )
522 {
523 mMenu->addSeparator();
524
525 QgsColorWheel *colorWheel = new QgsColorWheel( mMenu );
526 colorWheel->setColor( mSymbol->color() );
527 QgsColorWidgetAction *colorAction = new QgsColorWidgetAction( colorWheel, mMenu, mMenu );
528 colorAction->setDismissOnColorSelection( false );
529 connect( colorAction, &QgsColorWidgetAction::colorChanged, this, &QgsSymbolButton::setColor );
530 mMenu->addAction( colorAction );
531
533 QColor alphaColor = mSymbol->color();
534 alphaColor.setAlphaF( mSymbol->opacity() );
535 alphaRamp->setColor( alphaColor );
536 QgsColorWidgetAction *alphaAction = new QgsColorWidgetAction( alphaRamp, mMenu, mMenu );
537 alphaAction->setDismissOnColorSelection( false );
538 connect( alphaAction, &QgsColorWidgetAction::colorChanged, this, [=]( const QColor &color ) {
539 const double opacity = color.alphaF();
540 mSymbol->setOpacity( opacity );
541 updatePreview();
542 emit changed();
543 } );
544 connect( colorAction, &QgsColorWidgetAction::colorChanged, alphaRamp, [alphaRamp]( const QColor &color ) { alphaRamp->setColor( color, false ); } );
545 mMenu->addAction( alphaAction );
546
547 //get schemes with ShowInColorButtonMenu flag set
549 QList<QgsColorScheme *>::iterator it = schemeList.begin();
550 for ( ; it != schemeList.end(); ++it )
551 {
552 QgsColorSwatchGridAction *colorAction = new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral( "symbology" ), this );
553 colorAction->setBaseColor( mSymbol->color() );
554 mMenu->addAction( colorAction );
556 connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsSymbolButton::addRecentColor );
557 }
558
559 mMenu->addSeparator();
560
561 QAction *copyColorAction = new QAction( tr( "Copy Color" ), this );
562 mMenu->addAction( copyColorAction );
563 connect( copyColorAction, &QAction::triggered, this, &QgsSymbolButton::copyColor );
564
565 QAction *pasteColorAction = new QAction( tr( "Paste Color" ), this );
566 //enable or disable paste action based on current clipboard contents. We always show the paste
567 //action, even if it's disabled, to give hint to the user that pasting colors is possible
568 QColor clipColor;
569 bool hasAlpha = false;
570 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
571 {
572 pasteColorAction->setIcon( createColorIcon( clipColor ) );
573 }
574 else
575 {
576 pasteColorAction->setEnabled( false );
577 }
578 mMenu->addAction( pasteColorAction );
579 connect( pasteColorAction, &QAction::triggered, this, &QgsSymbolButton::pasteColor );
580
581 QAction *pickColorAction = new QAction( tr( "Pick Color" ), this );
582 mMenu->addAction( pickColorAction );
583 connect( pickColorAction, &QAction::triggered, this, &QgsSymbolButton::activatePicker );
584
585 QAction *chooseColorAction = new QAction( tr( "Choose Color…" ), this );
586 mMenu->addAction( chooseColorAction );
587 connect( chooseColorAction, &QAction::triggered, this, &QgsSymbolButton::showColorDialog );
588 }
589}
590
591void QgsSymbolButton::addRecentColor( const QColor &color )
592{
594}
595
596void QgsSymbolButton::activatePicker()
597{
598 //activate picker color
599 QApplication::setOverrideCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Sampler ) );
600 grabMouse();
601 grabKeyboard();
602 mPickingColor = true;
603 setMouseTracking( true );
604}
605
606
608{
609 if ( e->type() == QEvent::EnabledChange )
610 {
611 updatePreview();
612 }
613 QToolButton::changeEvent( e );
614}
615
616void QgsSymbolButton::showEvent( QShowEvent *e )
617{
618 updatePreview();
619 QToolButton::showEvent( e );
620}
621
622void QgsSymbolButton::resizeEvent( QResizeEvent *event )
623{
624 QToolButton::resizeEvent( event );
625 //recalculate icon size and redraw icon
626 mIconSize = QSize();
627 updatePreview();
628}
629
630void QgsSymbolButton::updatePreview( const QColor &color, QgsSymbol *tempSymbol )
631{
632 QSize currentIconSize;
633 //icon size is button size with a small margin
634 if ( menu() )
635 {
636 if ( !mIconSize.isValid() )
637 {
638 //calculate size of push button part of widget (ie, without the menu dropdown button part)
639 QStyleOptionToolButton opt;
640 initStyleOption( &opt );
641 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton, this );
642 //make sure height of icon looks good under different platforms
643#ifdef Q_OS_WIN
644 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
645#else
646 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
647#endif
648 }
649 currentIconSize = mIconSize;
650 }
651 else
652 {
653 //no menu
654#ifdef Q_OS_WIN
655 currentIconSize = QSize( width() - 10, height() - 6 );
656#else
657 currentIconSize = QSize( width() - 10, height() - 12 );
658#endif
659 }
660
661 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
662 {
663 return;
664 }
665
666 std::unique_ptr<QgsSymbol> previewSymbol;
667
668 if ( tempSymbol )
669 {
670 previewSymbol.reset( tempSymbol->clone() );
671 }
672 else if ( mSymbol )
673 {
674 previewSymbol.reset( mSymbol->clone() );
675 }
676 else
677 {
678 setIconSize( currentIconSize );
679 setIcon( QIcon() );
680 setToolTip( QString() );
681 return;
682 }
683
684 if ( color.isValid() )
685 previewSymbol->setColor( color );
686
687 //create an icon pixmap
688 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize, 0, nullptr, QgsScreenProperties( screen() ) );
689 setIconSize( currentIconSize );
690 setIcon( icon );
691
692 // set tooltip
693 // create very large preview image
694 const int width = static_cast<int>( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
695 const int height = static_cast<int>( width / 1.61803398875 ); // golden ratio
696
697 const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20, nullptr, false, nullptr, nullptr, QgsScreenProperties( screen() ) );
698 QByteArray data;
699 QBuffer buffer( &data );
700 pm.save( &buffer, "PNG", 100 );
701 setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3' width=\"%4\">" ).arg( QString( data.toBase64() ) ).arg( width ) );
702}
703
704bool QgsSymbolButton::colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha )
705{
706 hasAlpha = false;
707 const QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha );
708
709 if ( mimeColor.isValid() )
710 {
711 resultColor = mimeColor;
712 return true;
713 }
714
715 //could not get color from mime data
716 return false;
717}
718
719QPixmap QgsSymbolButton::createColorIcon( const QColor &color ) const
720{
721 //create an icon pixmap
722 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
723 QPixmap pixmap( iconSize, iconSize );
724 pixmap.fill( Qt::transparent );
725
726 QPainter p;
727 p.begin( &pixmap );
728
729 //draw color over pattern
730 p.setBrush( QBrush( color ) );
731
732 //draw border
733 p.setPen( QColor( 197, 197, 197 ) );
734 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
735 p.end();
736 return pixmap;
737}
738
739void QgsSymbolButton::stopPicking( QPoint eventPos, bool samplingColor )
740{
741 //release mouse and keyboard, and reset cursor
742 releaseMouse();
743 releaseKeyboard();
744 QgsApplication::restoreOverrideCursor();
745 setMouseTracking( false );
746 mPickingColor = false;
747
748 if ( !samplingColor )
749 {
750 //not sampling color, restore old icon
751 updatePreview();
752 return;
753 }
754
755 const QColor newColor = QgsGui::sampleColor( eventPos );
756 setColor( newColor );
757 addRecentColor( newColor );
758}
759
760void QgsSymbolButton::showColorDialog()
761{
762 if ( !mSymbol )
763 return;
764
766 if ( panel && panel->dockMode() )
767 {
768 const QColor currentColor = mSymbol->color();
770 colorWidget->setPanelTitle( tr( "Symbol Color" ) );
771 colorWidget->setAllowOpacity( true );
772
773 if ( currentColor.isValid() )
774 {
775 colorWidget->setPreviousColor( currentColor );
776 }
777
778 connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [=]( const QColor &newColor ) {
779 if ( newColor.isValid() )
780 {
781 setColor( newColor );
782 }
783 } );
784 panel->openPanel( colorWidget );
785 return;
786 }
787
788 QgsColorDialog dialog( this, Qt::WindowFlags(), mSymbol->color() );
789 dialog.setTitle( tr( "Symbol Color" ) );
790 dialog.setAllowOpacity( true );
791
792 if ( dialog.exec() && dialog.color().isValid() )
793 {
794 setColor( dialog.color() );
795 }
796
797 // reactivate button's window
798 activateWindow();
799}
800
801void QgsSymbolButton::setDialogTitle( const QString &title )
802{
803 mDialogTitle = title;
804}
805
807{
808 return mDialogTitle;
809}
810
812{
813 return mSymbol.get();
814}
815
816void QgsSymbolButton::setShowNull( bool showNull )
817{
818 mShowNull = showNull;
819}
820
822{
823 return mShowNull;
824}
825
827{
828 return !mSymbol;
829}
830
832{
833 setSymbol( nullptr );
834}
835
837{
838 if ( !mDefaultSymbol )
839 {
840 return;
841 }
842
843 setSymbol( mDefaultSymbol->clone() );
844}
@ Polygon
Polygons.
SymbolType
Symbol types.
Definition qgis.h:574
@ Marker
Marker symbol.
@ Line
Line symbol.
@ Fill
Fill symbol.
@ Hybrid
Hybrid symbol.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:5775
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.
@ Sampler
Color/Value picker.
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:277
A line symbol type, for rendering LineString and MultiLineString geometries.
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.
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.
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 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.
Stores properties relating to a screen.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition qgsstyle.cpp:146
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 setDefaultSymbol(QgsSymbol *symbol)
Sets the default symbol for the button, which is shown in the button's drop-down menu for the "defaul...
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 setToDefaultSymbol()
Sets symbol to the button's default symbol, if set.
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.
const QgsSymbol * defaultSymbol() const
Returns the default symbol for the button, which is shown in the button's drop-down menu for the "def...
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, const QgsScreenProperties &screen=QgsScreenProperties())
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, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
A dialog that can be used to select and build a symbol.
Symbol selector widget that can be used to select and build a symbol.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsSymbol * symbol()
Returns the symbol that is currently active in the widget.
static QgsSymbolSelectorWidget * createWidgetWithSymbolOwnership(std::unique_ptr< QgsSymbol > symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent=nullptr)
Creates a QgsSymbolSelectorWidget which takes ownership of a symbol and maintains the ownership for t...
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:231
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:294
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
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,...