17#include "moc_qgssymbolbutton.cpp"
43 : QToolButton( parent )
44 , mDialogTitle( dialogTitle.isEmpty() ? tr(
"Symbol Settings" ) : dialogTitle )
48 setAcceptDrops(
true );
49 connect(
this, &QAbstractButton::clicked,
this, &QgsSymbolButton::showSettingsDialog );
52 mMenu =
new QMenu(
this );
53 connect( mMenu, &QMenu::aboutToShow,
this, &QgsSymbolButton::prepareMenu );
55 setPopupMode( QToolButton::MenuButtonPopup );
60void QgsSymbolButton::updateSizeHint()
63 const QSize size = QToolButton::minimumSizeHint();
70 mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight * 3 ) );
71 setMaximumWidth( mSizeHint.height() * 1.5 );
72 setMinimumWidth( maximumWidth() );
76 mSizeHint = QSize( size.width(), fontHeight );
77 setMaximumWidth( 999999 );
78 mSizeHint.setWidth( QToolButton::sizeHint().width() );
85 mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight ) );
89 setMinimumHeight( mSizeHint.height() );
133void QgsSymbolButton::showSettingsDialog()
136 if ( mExpressionContextGenerator )
143 std::unique_ptr<QgsSymbol> newSymbol;
146 newSymbol.reset( mSymbol->clone() );
183 dialog.setWindowTitle( mDialogTitle );
184 dialog.setContext( symbolContext );
232 mExpressionContextGenerator = generator;
237 mDefaultSymbol.reset(
symbol );
242 return mDefaultSymbol.get();
258 QColor opaque = color;
259 opaque.setAlphaF( 1.0 );
261 if ( opaque == mSymbol->color() )
264 mSymbol->setColor( opaque );
289 bool hasAlpha =
false;
290 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
307 if ( e->button() == Qt::RightButton )
309 QToolButton::showMenu();
312 else if ( e->button() == Qt::LeftButton )
314 mDragStartPosition = e->pos();
316 QToolButton::mousePressEvent( e );
330 if ( !( e->buttons() & Qt::LeftButton ) )
333 QToolButton::mouseMoveEvent( e );
337 if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
340 QToolButton::mouseMoveEvent( e );
345 QDrag *drag =
new QDrag(
this );
348 drag->exec( Qt::CopyAction );
357 stopPicking( e->globalPos() );
362 QToolButton::mouseReleaseEvent( e );
367 if ( !mPickingColor )
370 QToolButton::keyPressEvent( e );
375 stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
382 bool hasAlpha =
false;
384 if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
389 e->acceptProposedAction();
390 updatePreview( mimeColor );
405 bool hasAlpha =
false;
406 if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
409 e->acceptProposedAction();
410 mimeColor.setAlphaF( 1.0 );
411 mSymbol->setColor( mimeColor );
421 if ( isEnabled() && mSymbol )
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() )
429 QgsMarkerSymbol *marker = qgis::down_cast<QgsMarkerSymbol *>( mSymbol.get() );
432 const double size = std::max( 0.0, marker->
size() + increment );
434 symbolChanged =
true;
441 QgsLineSymbol *line = qgis::down_cast<QgsLineSymbol *>( mSymbol.get() );
444 const double width = std::max( 0.0, line->
width() + increment );
446 symbolChanged =
true;
466 QToolButton::wheelEvent( event );
470void QgsSymbolButton::prepareMenu()
478 QAction *configureAction =
new QAction( tr(
"Configure Symbol…" ),
this );
479 mMenu->addAction( configureAction );
480 connect( configureAction, &QAction::triggered,
this, &QgsSymbolButton::showSettingsDialog );
482 QAction *copySymbolAction =
new QAction( tr(
"Copy Symbol" ),
this );
483 copySymbolAction->setEnabled( !
isNull() );
484 mMenu->addAction( copySymbolAction );
489 QAction *pasteSymbolAction =
new QAction( tr(
"Paste Symbol" ),
this );
493 if ( tempSymbol && tempSymbol->type() == mType )
499 pasteSymbolAction->setEnabled(
false );
501 mMenu->addAction( pasteSymbolAction );
506 QAction *nullAction =
new QAction( tr(
"Clear Current Symbol" ),
this );
507 nullAction->setEnabled( !
isNull() );
508 mMenu->addAction( nullAction );
513 if ( mDefaultSymbol )
515 QAction *defaultSymbolAction =
new QAction( tr(
"Default Symbol" ),
this );
517 mMenu->addAction( defaultSymbolAction );
523 mMenu->addSeparator();
526 colorWheel->
setColor( mSymbol->color() );
530 mMenu->addAction( colorAction );
533 QColor alphaColor = mSymbol->color();
534 alphaColor.setAlphaF( mSymbol->opacity() );
539 const double opacity = color.alphaF();
540 mSymbol->setOpacity( opacity );
545 mMenu->addAction( alphaAction );
549 QList<QgsColorScheme *>::iterator it = schemeList.begin();
550 for ( ; it != schemeList.end(); ++it )
554 mMenu->addAction( colorAction );
559 mMenu->addSeparator();
561 QAction *copyColorAction =
new QAction( tr(
"Copy Color" ),
this );
562 mMenu->addAction( copyColorAction );
565 QAction *pasteColorAction =
new QAction( tr(
"Paste Color" ),
this );
569 bool hasAlpha =
false;
570 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
572 pasteColorAction->setIcon( createColorIcon( clipColor ) );
576 pasteColorAction->setEnabled(
false );
578 mMenu->addAction( pasteColorAction );
581 QAction *pickColorAction =
new QAction( tr(
"Pick Color" ),
this );
582 mMenu->addAction( pickColorAction );
583 connect( pickColorAction, &QAction::triggered,
this, &QgsSymbolButton::activatePicker );
585 QAction *chooseColorAction =
new QAction( tr(
"Choose Color…" ),
this );
586 mMenu->addAction( chooseColorAction );
587 connect( chooseColorAction, &QAction::triggered,
this, &QgsSymbolButton::showColorDialog );
591void QgsSymbolButton::addRecentColor(
const QColor &color )
596void QgsSymbolButton::activatePicker()
602 mPickingColor =
true;
603 setMouseTracking(
true );
609 if ( e->type() == QEvent::EnabledChange )
613 QToolButton::changeEvent( e );
619 QToolButton::showEvent( e );
624 QToolButton::resizeEvent( event );
630void QgsSymbolButton::updatePreview(
const QColor &color,
QgsSymbol *tempSymbol )
632 QSize currentIconSize;
636 if ( !mIconSize.isValid() )
639 QStyleOptionToolButton opt;
640 initStyleOption( &opt );
641 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
this );
644 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
646 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
649 currentIconSize = mIconSize;
655 currentIconSize = QSize( width() - 10, height() - 6 );
657 currentIconSize = QSize( width() - 10, height() - 12 );
661 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
666 std::unique_ptr<QgsSymbol> previewSymbol;
670 previewSymbol.reset( tempSymbol->
clone() );
674 previewSymbol.reset( mSymbol->clone() );
678 setIconSize( currentIconSize );
680 setToolTip( QString() );
684 if ( color.isValid() )
685 previewSymbol->setColor( color );
689 setIconSize( currentIconSize );
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 );
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 ) );
704bool QgsSymbolButton::colorFromMimeData(
const QMimeData *mimeData, QColor &resultColor,
bool &hasAlpha )
709 if ( mimeColor.isValid() )
711 resultColor = mimeColor;
719QPixmap QgsSymbolButton::createColorIcon(
const QColor &color )
const
723 QPixmap pixmap( iconSize, iconSize );
724 pixmap.fill( Qt::transparent );
730 p.setBrush( QBrush( color ) );
733 p.setPen( QColor( 197, 197, 197 ) );
734 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
739void QgsSymbolButton::stopPicking( QPoint eventPos,
bool samplingColor )
744 QgsApplication::restoreOverrideCursor();
745 setMouseTracking(
false );
746 mPickingColor =
false;
748 if ( !samplingColor )
757 addRecentColor( newColor );
760void QgsSymbolButton::showColorDialog()
768 const QColor currentColor = mSymbol->color();
773 if ( currentColor.isValid() )
779 if ( newColor.isValid() )
781 setColor( newColor );
788 QgsColorDialog dialog(
this, Qt::WindowFlags(), mSymbol->color() );
789 dialog.setTitle( tr(
"Symbol Color" ) );
790 dialog.setAllowOpacity(
true );
792 if ( dialog.exec() && dialog.color().isValid() )
803 mDialogTitle = title;
813 return mSymbol.get();
838 if ( !mDefaultSymbol )
static const double UI_SCALE_FACTOR
UI scaling factor.
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.
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.
void setColor(const QColor &color, bool emitSignals=false) override
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 std::unique_ptr< 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).
A line symbol type, for rendering LineString and MultiLineString geometries.
void setWidth(double width) const
Sets the width for the whole line symbol.
static std::unique_ptr< QgsLineSymbol > createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
double width() const
Returns the estimated width for the whole symbol, which is the maximum width of all marker symbol lay...
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 std::unique_ptr< 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.
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.
static std::unique_ptr< 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.
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.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
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 dataset.
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,...