QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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"
20#include "qgsvectorlayer.h"
22#include "qgsstyle.h"
23#include "qgscolorwidgets.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
41QgsSymbolButton::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 updateSizeHint();
57}
58
59void QgsSymbolButton::updateSizeHint()
60{
61 //make sure height of button looks good under different platforms
62 const QSize size = QToolButton::minimumSizeHint();
63 const int fontHeight = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4 );
64 switch ( mType )
65 {
67 if ( mSymbol )
68 {
69 mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight * 3 ) );
70 setMaximumWidth( mSizeHint.height() * 1.5 );
71 setMinimumWidth( maximumWidth() );
72 }
73 else
74 {
75 mSizeHint = QSize( size.width(), fontHeight );
76 setMaximumWidth( 999999 );
77 mSizeHint.setWidth( QToolButton::sizeHint().width() );
78 }
79 break;
80
84 mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight ) );
85 break;
86 }
87
88 setMinimumHeight( mSizeHint.height( ) );
89
90 updateGeometry();
91}
92
94
96{
97 return mSizeHint;
98}
99
101{
102 return mSizeHint;
103}
104
106{
107 if ( type != mType )
108 {
109 switch ( type )
110 {
112 mSymbol.reset( QgsMarkerSymbol::createSimple( QVariantMap() ) );
113 break;
114
116 mSymbol.reset( QgsLineSymbol::createSimple( QVariantMap() ) );
117 break;
118
120 mSymbol.reset( QgsFillSymbol::createSimple( QVariantMap() ) );
121 break;
122
124 break;
125 }
126 }
127 mType = type;
128 updateSizeHint();
129 updatePreview();
130}
131
132void QgsSymbolButton::showSettingsDialog()
133{
134 QgsExpressionContext context;
135 if ( mExpressionContextGenerator )
136 context = mExpressionContextGenerator->createExpressionContext();
137 else
138 {
140 }
141
142 std::unique_ptr< QgsSymbol > newSymbol;
143 if ( mSymbol )
144 {
145 newSymbol.reset( mSymbol->clone() );
146 }
147 else
148 {
149 switch ( mType )
150 {
153 break;
156 break;
159 break;
161 break;
162 }
163 }
164
165 QgsSymbolWidgetContext symbolContext;
166 symbolContext.setExpressionContext( &context );
167 symbolContext.setMapCanvas( mMapCanvas );
168 symbolContext.setMessageBar( mMessageBar );
169
171 if ( panel && panel->dockMode() )
172 {
174 widget->setPanelTitle( mDialogTitle );
175 widget->setContext( symbolContext );
176 connect( widget, &QgsPanelWidget::widgetChanged, this, [ = ] { updateSymbolFromWidget( widget ); } );
177 panel->openPanel( widget );
178 }
179 else
180 {
181 QgsSymbolSelectorDialog dialog( newSymbol.get(), QgsStyle::defaultStyle(), mLayer, this );
182 dialog.setWindowTitle( mDialogTitle );
183 dialog.setContext( symbolContext );
184 if ( dialog.exec() )
185 {
186 setSymbol( newSymbol.release() );
187 }
188
189 // reactivate button's window
190 activateWindow();
191 }
192}
193
194void QgsSymbolButton::updateSymbolFromWidget( QgsSymbolSelectorWidget *widget )
195{
196 setSymbol( widget->symbol()->clone() );
197}
198
200{
201 return mMapCanvas;
202}
203
205{
206 mMapCanvas = mapCanvas;
207}
208
210{
211 mMessageBar = bar;
212}
213
215{
216 return mMessageBar;
217}
218
220{
221 return mLayer;
222}
223
225{
226 mLayer = layer;
227}
228
230{
231 mExpressionContextGenerator = generator;
232}
233
235{
236 mDefaultSymbol.reset( symbol );
237}
238
240{
241 return mDefaultSymbol.get();
242}
243
245{
246 mSymbol.reset( symbol );
247 updateSizeHint();
248 updatePreview();
249 emit changed();
250}
251
252void QgsSymbolButton::setColor( const QColor &color )
253{
254 if ( !mSymbol )
255 return;
256
257 QColor opaque = color;
258 opaque.setAlphaF( 1.0 );
259
260 if ( opaque == mSymbol->color() )
261 return;
262
263 mSymbol->setColor( opaque );
264 updatePreview();
265 emit changed();
266}
267
269{
270 QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::symbolToMimeData( mSymbol.get() ) );
271}
272
274{
275 std::unique_ptr< QgsSymbol > symbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
276 if ( symbol && symbol->type() == mType )
277 setSymbol( symbol.release() );
278}
279
281{
282 QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
283}
284
286{
287 QColor clipColor;
288 bool hasAlpha = false;
289 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
290 {
291 //paste color
292 setColor( clipColor );
294 }
295}
296
298{
299 if ( mPickingColor )
300 {
301 //don't show dialog if in color picker mode
302 e->accept();
303 return;
304 }
305
306 if ( e->button() == Qt::RightButton )
307 {
308 QToolButton::showMenu();
309 return;
310 }
311 else if ( e->button() == Qt::LeftButton )
312 {
313 mDragStartPosition = e->pos();
314 }
315 QToolButton::mousePressEvent( e );
316}
317
319{
320 if ( mPickingColor )
321 {
322 updatePreview( QgsGui::sampleColor( e->globalPos() ) );
323 e->accept();
324 return;
325 }
326
327 //handle dragging colors/symbols from button
328
329 if ( !( e->buttons() & Qt::LeftButton ) )
330 {
331 //left button not depressed, so not a drag
332 QToolButton::mouseMoveEvent( e );
333 return;
334 }
335
336 if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
337 {
338 //mouse not moved, so not a drag
339 QToolButton::mouseMoveEvent( e );
340 return;
341 }
342
343 //user is dragging
344 QDrag *drag = new QDrag( this );
345 drag->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mSymbol->color() ) );
346 drag->setPixmap( QgsColorWidget::createDragIcon( mSymbol->color() ) );
347 drag->exec( Qt::CopyAction );
348 setDown( false );
349}
350
352{
353 if ( mPickingColor )
354 {
355 //end color picking operation by sampling the color under cursor
356 stopPicking( e->globalPos() );
357 e->accept();
358 return;
359 }
360
361 QToolButton::mouseReleaseEvent( e );
362}
363
365{
366 if ( !mPickingColor )
367 {
368 //if not picking a color, use default tool button behavior
369 QToolButton::keyPressEvent( e );
370 return;
371 }
372
373 //cancel picking, sampling the color if space was pressed
374 stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
375}
376
377void QgsSymbolButton::dragEnterEvent( QDragEnterEvent *e )
378{
379 //is dragged data valid color data?
380 QColor mimeColor;
381 bool hasAlpha = false;
382
383 if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
384 {
385 //if so, we accept the drag, and temporarily change the button's color
386 //to match the dragged color. This gives immediate feedback to the user
387 //that colors can be dropped here
388 e->acceptProposedAction();
389 updatePreview( mimeColor );
390 }
391}
392
393void QgsSymbolButton::dragLeaveEvent( QDragLeaveEvent *e )
394{
395 Q_UNUSED( e )
396 //reset button color
397 updatePreview();
398}
399
400void QgsSymbolButton::dropEvent( QDropEvent *e )
401{
402 //is dropped data valid format data?
403 QColor mimeColor;
404 bool hasAlpha = false;
405 if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
406 {
407 //accept drop and set new color
408 e->acceptProposedAction();
409 mimeColor.setAlphaF( 1.0 );
410 mSymbol->setColor( mimeColor );
412 updatePreview();
413 emit changed();
414 }
415 updatePreview();
416}
417
418void QgsSymbolButton::wheelEvent( QWheelEvent *event )
419{
420 if ( isEnabled() && mSymbol )
421 {
422 bool symbolChanged = false;
423 const double increment = ( ( event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1 ) *
424 ( 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 {
540 const double opacity = color.alphaF();
541 mSymbol->setOpacity( opacity );
542 updatePreview();
543 emit changed();
544 } );
545 connect( colorAction, &QgsColorWidgetAction::colorChanged, alphaRamp, [alphaRamp]( const QColor & color ) { alphaRamp->setColor( color, false ); }
546 );
547 mMenu->addAction( alphaAction );
548
549 //get schemes with ShowInColorButtonMenu flag set
550 QList< QgsColorScheme * > schemeList = QgsApplication::colorSchemeRegistry()->schemes( QgsColorScheme::ShowInColorButtonMenu );
551 QList< QgsColorScheme * >::iterator it = schemeList.begin();
552 for ( ; it != schemeList.end(); ++it )
553 {
554 QgsColorSwatchGridAction *colorAction = new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral( "symbology" ), this );
555 colorAction->setBaseColor( mSymbol->color() );
556 mMenu->addAction( colorAction );
558 connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsSymbolButton::addRecentColor );
559 }
560
561 mMenu->addSeparator();
562
563 QAction *copyColorAction = new QAction( tr( "Copy Color" ), this );
564 mMenu->addAction( copyColorAction );
565 connect( copyColorAction, &QAction::triggered, this, &QgsSymbolButton::copyColor );
566
567 QAction *pasteColorAction = new QAction( tr( "Paste Color" ), this );
568 //enable or disable paste action based on current clipboard contents. We always show the paste
569 //action, even if it's disabled, to give hint to the user that pasting colors is possible
570 QColor clipColor;
571 bool hasAlpha = false;
572 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
573 {
574 pasteColorAction->setIcon( createColorIcon( clipColor ) );
575 }
576 else
577 {
578 pasteColorAction->setEnabled( false );
579 }
580 mMenu->addAction( pasteColorAction );
581 connect( pasteColorAction, &QAction::triggered, this, &QgsSymbolButton::pasteColor );
582
583 QAction *pickColorAction = new QAction( tr( "Pick Color" ), this );
584 mMenu->addAction( pickColorAction );
585 connect( pickColorAction, &QAction::triggered, this, &QgsSymbolButton::activatePicker );
586
587 QAction *chooseColorAction = new QAction( tr( "Choose Color…" ), this );
588 mMenu->addAction( chooseColorAction );
589 connect( chooseColorAction, &QAction::triggered, this, &QgsSymbolButton::showColorDialog );
590 }
591}
592
593void QgsSymbolButton::addRecentColor( const QColor &color )
594{
596}
597
598void QgsSymbolButton::activatePicker()
599{
600 //activate picker color
601 QApplication::setOverrideCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Sampler ) );
602 grabMouse();
603 grabKeyboard();
604 mPickingColor = true;
605 setMouseTracking( true );
606}
607
608
610{
611 if ( e->type() == QEvent::EnabledChange )
612 {
613 updatePreview();
614 }
615 QToolButton::changeEvent( e );
616}
617
618void QgsSymbolButton::showEvent( QShowEvent *e )
619{
620 updatePreview();
621 QToolButton::showEvent( e );
622}
623
624void QgsSymbolButton::resizeEvent( QResizeEvent *event )
625{
626 QToolButton::resizeEvent( event );
627 //recalculate icon size and redraw icon
628 mIconSize = QSize();
629 updatePreview();
630}
631
632void QgsSymbolButton::updatePreview( const QColor &color, QgsSymbol *tempSymbol )
633{
634 QSize currentIconSize;
635 //icon size is button size with a small margin
636 if ( menu() )
637 {
638 if ( !mIconSize.isValid() )
639 {
640 //calculate size of push button part of widget (ie, without the menu dropdown button part)
641 QStyleOptionToolButton opt;
642 initStyleOption( &opt );
643 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
644 this );
645 //make sure height of icon looks good under different platforms
646#ifdef Q_OS_WIN
647 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
648#else
649 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
650#endif
651 }
652 currentIconSize = mIconSize;
653 }
654 else
655 {
656 //no menu
657#ifdef Q_OS_WIN
658 currentIconSize = QSize( width() - 10, height() - 6 );
659#else
660 currentIconSize = QSize( width() - 10, height() - 12 );
661#endif
662 }
663
664 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
665 {
666 return;
667 }
668
669 std::unique_ptr< QgsSymbol > previewSymbol;
670
671 if ( tempSymbol )
672 {
673 previewSymbol.reset( tempSymbol->clone() );
674 }
675 else if ( mSymbol )
676 {
677 previewSymbol.reset( mSymbol->clone() );
678 }
679 else
680 {
681 setIconSize( currentIconSize );
682 setIcon( QIcon() );
683 setToolTip( QString( ) );
684 return;
685 }
686
687 if ( color.isValid() )
688 previewSymbol->setColor( color );
689
690 //create an icon pixmap
691 const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize, 0, nullptr, QgsScreenProperties( screen() ) );
692 setIconSize( currentIconSize );
693 setIcon( icon );
694
695 // set tooltip
696 // create very large preview image
697 const int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
698 const int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
699
700 const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20, nullptr, false, nullptr, nullptr, QgsScreenProperties( screen() ) );
701 QByteArray data;
702 QBuffer buffer( &data );
703 pm.save( &buffer, "PNG", 100 );
704 setToolTip( QStringLiteral( "<img src='data:image/png;base64, %3' width=\"%4\">" ).arg( QString( data.toBase64() ) ).arg( width ) );
705}
706
707bool QgsSymbolButton::colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha )
708{
709 hasAlpha = false;
710 const QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha );
711
712 if ( mimeColor.isValid() )
713 {
714 resultColor = mimeColor;
715 return true;
716 }
717
718 //could not get color from mime data
719 return false;
720}
721
722QPixmap QgsSymbolButton::createColorIcon( const QColor &color ) const
723{
724 //create an icon pixmap
725 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
726 QPixmap pixmap( iconSize, iconSize );
727 pixmap.fill( Qt::transparent );
728
729 QPainter p;
730 p.begin( &pixmap );
731
732 //draw color over pattern
733 p.setBrush( QBrush( color ) );
734
735 //draw border
736 p.setPen( QColor( 197, 197, 197 ) );
737 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
738 p.end();
739 return pixmap;
740}
741
742void QgsSymbolButton::stopPicking( QPoint eventPos, bool samplingColor )
743{
744 //release mouse and keyboard, and reset cursor
745 releaseMouse();
746 releaseKeyboard();
747 QgsApplication::restoreOverrideCursor();
748 setMouseTracking( false );
749 mPickingColor = false;
750
751 if ( !samplingColor )
752 {
753 //not sampling color, restore old icon
754 updatePreview();
755 return;
756 }
757
758 const QColor newColor = QgsGui::sampleColor( eventPos );
759 setColor( newColor );
760 addRecentColor( newColor );
761}
762
763void QgsSymbolButton::showColorDialog()
764{
765 if ( !mSymbol )
766 return;
767
769 if ( panel && panel->dockMode() )
770 {
771 const QColor currentColor = mSymbol->color();
773 colorWidget->setPanelTitle( tr( "Symbol Color" ) );
774 colorWidget->setAllowOpacity( true );
775
776 if ( currentColor.isValid() )
777 {
778 colorWidget->setPreviousColor( currentColor );
779 }
780
781 connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [ = ]( const QColor & newColor )
782 {
783 if ( newColor.isValid() )
784 {
785 setColor( newColor );
786 }
787 } );
788 panel->openPanel( colorWidget );
789 return;
790 }
791
792 QgsColorDialog dialog( this, Qt::WindowFlags(), mSymbol->color() );
793 dialog.setTitle( tr( "Symbol Color" ) );
794 dialog.setAllowOpacity( true );
795
796 if ( dialog.exec() && dialog.color().isValid() )
797 {
798 setColor( dialog.color() );
799 }
800
801 // reactivate button's window
802 activateWindow();
803}
804
805void QgsSymbolButton::setDialogTitle( const QString &title )
806{
807 mDialogTitle = title;
808}
809
811{
812 return mDialogTitle;
813}
814
816{
817 return mSymbol.get();
818}
819
820void QgsSymbolButton::setShowNull( bool showNull )
821{
822 mShowNull = showNull;
823}
824
826{
827 return mShowNull;
828}
829
831{
832 return !mSymbol;
833}
834
836{
837 setSymbol( nullptr );
838}
839
841{
842 if ( !mDefaultSymbol )
843 {
844 return;
845 }
846
847 setSymbol( mDefaultSymbol->clone() );
848}
@ Polygon
Polygons.
SymbolType
Symbol types.
Definition: qgis.h:401
@ Marker
Marker symbol.
@ Line
Line symbol.
@ Fill
Fill symbol.
@ Hybrid
Hybrid symbol.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:4927
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:259
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:93
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 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:145
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.
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:94
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:156
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:705
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,...