QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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 ) *
425 ( event->angleDelta().y() > 0 ? 1 : -1 );
426 switch ( mSymbol->type() )
427 {
429 {
430 QgsMarkerSymbol *marker = qgis::down_cast<QgsMarkerSymbol *>( mSymbol.get() );
431 if ( marker )
432 {
433 const double size = std::max( 0.0, marker->size() + increment );
434 marker->setSize( size );
435 symbolChanged = true;
436 }
437 break;
438 }
439
441 {
442 QgsLineSymbol *line = qgis::down_cast<QgsLineSymbol *>( mSymbol.get() );
443 if ( line )
444 {
445 const double width = std::max( 0.0, line->width() + increment );
446 line->setWidth( width );
447 symbolChanged = true;
448 }
449 break;
450 }
451
454 break;
455 }
456
457 if ( symbolChanged )
458 {
459 updatePreview();
460 emit changed();
461 }
462
463 event->accept();
464 }
465 else
466 {
467 QToolButton::wheelEvent( event );
468 }
469}
470
471void QgsSymbolButton::prepareMenu()
472{
473 //we need to tear down and rebuild this menu every time it is shown. Otherwise the space allocated to any
474 //QgsColorSwatchGridAction is not recalculated by Qt and the swatch grid may not be the correct size
475 //for the number of colors shown in the grid. Note that we MUST refresh color swatch grids every time this
476 //menu is opened, otherwise color schemes like the recent color scheme grid are meaningless
477 mMenu->clear();
478
479 QAction *configureAction = new QAction( tr( "Configure Symbol…" ), this );
480 mMenu->addAction( configureAction );
481 connect( configureAction, &QAction::triggered, this, &QgsSymbolButton::showSettingsDialog );
482
483 QAction *copySymbolAction = new QAction( tr( "Copy Symbol" ), this );
484 copySymbolAction->setEnabled( !isNull() );
485 mMenu->addAction( copySymbolAction );
486 connect( copySymbolAction, &QAction::triggered, this, &QgsSymbolButton::copySymbol );
487
488 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
489
490 QAction *pasteSymbolAction = new QAction( tr( "Paste Symbol" ), this );
491 //enable or disable paste action based on current clipboard contents. We always show the paste
492 //action, even if it's disabled, to give hint to the user that pasting symbols is possible
493 std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
494 if ( tempSymbol && tempSymbol->type() == mType )
495 {
496 pasteSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( tempSymbol.get(), QSize( iconSize, iconSize ), 1, nullptr, QgsScreenProperties( screen() ) ) );
497 }
498 else
499 {
500 pasteSymbolAction->setEnabled( false );
501 }
502 mMenu->addAction( pasteSymbolAction );
503 connect( pasteSymbolAction, &QAction::triggered, this, &QgsSymbolButton::pasteSymbol );
504
505 if ( mShowNull )
506 {
507 QAction *nullAction = new QAction( tr( "Clear Current Symbol" ), this );
508 nullAction->setEnabled( !isNull() );
509 mMenu->addAction( nullAction );
510 connect( nullAction, &QAction::triggered, this, &QgsSymbolButton::setToNull );
511 }
512
513 //show default symbol option if set
514 if ( mDefaultSymbol )
515 {
516 QAction *defaultSymbolAction = new QAction( tr( "Default Symbol" ), this );
517 defaultSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( mDefaultSymbol.get(), QSize( iconSize, iconSize ), 1, nullptr, QgsScreenProperties( screen() ) ) );
518 mMenu->addAction( defaultSymbolAction );
519 connect( defaultSymbolAction, &QAction::triggered, this, &QgsSymbolButton::setToDefaultSymbol );
520 }
521
522 if ( mSymbol )
523 {
524 mMenu->addSeparator();
525
526 QgsColorWheel *colorWheel = new QgsColorWheel( mMenu );
527 colorWheel->setColor( mSymbol->color() );
528 QgsColorWidgetAction *colorAction = new QgsColorWidgetAction( colorWheel, mMenu, mMenu );
529 colorAction->setDismissOnColorSelection( false );
530 connect( colorAction, &QgsColorWidgetAction::colorChanged, this, &QgsSymbolButton::setColor );
531 mMenu->addAction( colorAction );
532
534 QColor alphaColor = mSymbol->color();
535 alphaColor.setAlphaF( mSymbol->opacity() );
536 alphaRamp->setColor( alphaColor );
537 QgsColorWidgetAction *alphaAction = new QgsColorWidgetAction( alphaRamp, mMenu, mMenu );
538 alphaAction->setDismissOnColorSelection( false );
539 connect( alphaAction, &QgsColorWidgetAction::colorChanged, this, [ = ]( const QColor & color )
540 {
541 const double opacity = color.alphaF();
542 mSymbol->setOpacity( opacity );
543 updatePreview();
544 emit changed();
545 } );
546 connect( colorAction, &QgsColorWidgetAction::colorChanged, alphaRamp, [alphaRamp]( const QColor & color ) { alphaRamp->setColor( color, false ); }
547 );
548 mMenu->addAction( alphaAction );
549
550 //get schemes with ShowInColorButtonMenu flag set
551 QList< QgsColorScheme * > schemeList = QgsApplication::colorSchemeRegistry()->schemes( QgsColorScheme::ShowInColorButtonMenu );
552 QList< QgsColorScheme * >::iterator it = schemeList.begin();
553 for ( ; it != schemeList.end(); ++it )
554 {
555 QgsColorSwatchGridAction *colorAction = new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral( "symbology" ), this );
556 colorAction->setBaseColor( mSymbol->color() );
557 mMenu->addAction( colorAction );
559 connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsSymbolButton::addRecentColor );
560 }
561
562 mMenu->addSeparator();
563
564 QAction *copyColorAction = new QAction( tr( "Copy Color" ), this );
565 mMenu->addAction( copyColorAction );
566 connect( copyColorAction, &QAction::triggered, this, &QgsSymbolButton::copyColor );
567
568 QAction *pasteColorAction = new QAction( tr( "Paste Color" ), this );
569 //enable or disable paste action based on current clipboard contents. We always show the paste
570 //action, even if it's disabled, to give hint to the user that pasting colors is possible
571 QColor clipColor;
572 bool hasAlpha = false;
573 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
574 {
575 pasteColorAction->setIcon( createColorIcon( clipColor ) );
576 }
577 else
578 {
579 pasteColorAction->setEnabled( false );
580 }
581 mMenu->addAction( pasteColorAction );
582 connect( pasteColorAction, &QAction::triggered, this, &QgsSymbolButton::pasteColor );
583
584 QAction *pickColorAction = new QAction( tr( "Pick Color" ), this );
585 mMenu->addAction( pickColorAction );
586 connect( pickColorAction, &QAction::triggered, this, &QgsSymbolButton::activatePicker );
587
588 QAction *chooseColorAction = new QAction( tr( "Choose Color…" ), this );
589 mMenu->addAction( chooseColorAction );
590 connect( chooseColorAction, &QAction::triggered, this, &QgsSymbolButton::showColorDialog );
591 }
592}
593
594void QgsSymbolButton::addRecentColor( const QColor &color )
595{
597}
598
599void QgsSymbolButton::activatePicker()
600{
601 //activate picker color
602 QApplication::setOverrideCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Sampler ) );
603 grabMouse();
604 grabKeyboard();
605 mPickingColor = true;
606 setMouseTracking( true );
607}
608
609
611{
612 if ( e->type() == QEvent::EnabledChange )
613 {
614 updatePreview();
615 }
616 QToolButton::changeEvent( e );
617}
618
619void QgsSymbolButton::showEvent( QShowEvent *e )
620{
621 updatePreview();
622 QToolButton::showEvent( e );
623}
624
625void QgsSymbolButton::resizeEvent( QResizeEvent *event )
626{
627 QToolButton::resizeEvent( event );
628 //recalculate icon size and redraw icon
629 mIconSize = QSize();
630 updatePreview();
631}
632
633void QgsSymbolButton::updatePreview( const QColor &color, QgsSymbol *tempSymbol )
634{
635 QSize currentIconSize;
636 //icon size is button size with a small margin
637 if ( menu() )
638 {
639 if ( !mIconSize.isValid() )
640 {
641 //calculate size of push button part of widget (ie, without the menu dropdown button part)
642 QStyleOptionToolButton opt;
643 initStyleOption( &opt );
644 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
645 this );
646 //make sure height of icon looks good under different platforms
647#ifdef Q_OS_WIN
648 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
649#else
650 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
651#endif
652 }
653 currentIconSize = mIconSize;
654 }
655 else
656 {
657 //no menu
658#ifdef Q_OS_WIN
659 currentIconSize = QSize( width() - 10, height() - 6 );
660#else
661 currentIconSize = QSize( width() - 10, height() - 12 );
662#endif
663 }
664
665 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
666 {
667 return;
668 }
669
670 std::unique_ptr< QgsSymbol > previewSymbol;
671
672 if ( tempSymbol )
673 {
674 previewSymbol.reset( tempSymbol->clone() );
675 }
676 else if ( mSymbol )
677 {
678 previewSymbol.reset( mSymbol->clone() );
679 }
680 else
681 {
682 setIconSize( currentIconSize );
683 setIcon( QIcon() );
684 setToolTip( QString( ) );
685 return;
686 }
687
688 if ( color.isValid() )
689 previewSymbol->setColor( color );
690
691 //create an icon pixmap
692 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize, 0, nullptr, QgsScreenProperties( screen() ) );
693 setIconSize( currentIconSize );
694 setIcon( icon );
695
696 // set tooltip
697 // create very large preview image
698 const int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
699 const int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
700
701 const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20, nullptr, false, nullptr, nullptr, QgsScreenProperties( screen() ) );
702 QByteArray data;
703 QBuffer buffer( &data );
704 pm.save( &buffer, "PNG", 100 );
705 setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3' width=\"%4\">" ).arg( QString( data.toBase64() ) ).arg( width ) );
706}
707
708bool QgsSymbolButton::colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha )
709{
710 hasAlpha = false;
711 const QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha );
712
713 if ( mimeColor.isValid() )
714 {
715 resultColor = mimeColor;
716 return true;
717 }
718
719 //could not get color from mime data
720 return false;
721}
722
723QPixmap QgsSymbolButton::createColorIcon( const QColor &color ) const
724{
725 //create an icon pixmap
726 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
727 QPixmap pixmap( iconSize, iconSize );
728 pixmap.fill( Qt::transparent );
729
730 QPainter p;
731 p.begin( &pixmap );
732
733 //draw color over pattern
734 p.setBrush( QBrush( color ) );
735
736 //draw border
737 p.setPen( QColor( 197, 197, 197 ) );
738 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
739 p.end();
740 return pixmap;
741}
742
743void QgsSymbolButton::stopPicking( QPoint eventPos, bool samplingColor )
744{
745 //release mouse and keyboard, and reset cursor
746 releaseMouse();
747 releaseKeyboard();
748 QgsApplication::restoreOverrideCursor();
749 setMouseTracking( false );
750 mPickingColor = false;
751
752 if ( !samplingColor )
753 {
754 //not sampling color, restore old icon
755 updatePreview();
756 return;
757 }
758
759 const QColor newColor = QgsGui::sampleColor( eventPos );
760 setColor( newColor );
761 addRecentColor( newColor );
762}
763
764void QgsSymbolButton::showColorDialog()
765{
766 if ( !mSymbol )
767 return;
768
770 if ( panel && panel->dockMode() )
771 {
772 const QColor currentColor = mSymbol->color();
774 colorWidget->setPanelTitle( tr( "Symbol Color" ) );
775 colorWidget->setAllowOpacity( true );
776
777 if ( currentColor.isValid() )
778 {
779 colorWidget->setPreviousColor( currentColor );
780 }
781
782 connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [ = ]( const QColor & newColor )
783 {
784 if ( newColor.isValid() )
785 {
786 setColor( newColor );
787 }
788 } );
789 panel->openPanel( colorWidget );
790 return;
791 }
792
793 QgsColorDialog dialog( this, Qt::WindowFlags(), mSymbol->color() );
794 dialog.setTitle( tr( "Symbol Color" ) );
795 dialog.setAllowOpacity( true );
796
797 if ( dialog.exec() && dialog.color().isValid() )
798 {
799 setColor( dialog.color() );
800 }
801
802 // reactivate button's window
803 activateWindow();
804}
805
806void QgsSymbolButton::setDialogTitle( const QString &title )
807{
808 mDialogTitle = title;
809}
810
812{
813 return mDialogTitle;
814}
815
817{
818 return mSymbol.get();
819}
820
821void QgsSymbolButton::setShowNull( bool showNull )
822{
823 mShowNull = showNull;
824}
825
827{
828 return mShowNull;
829}
830
832{
833 return !mSymbol;
834}
835
837{
838 setSymbol( nullptr );
839}
840
842{
843 if ( !mDefaultSymbol )
844 {
845 return;
846 }
847
848 setSymbol( mDefaultSymbol->clone() );
849}
@ 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:5667
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:276
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:293
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,...