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 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.
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.
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 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 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,...