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 ) *
425 ( event->angleDelta().y() > 0 ? 1 : -1 );
426 switch ( mSymbol->type() )
430 QgsMarkerSymbol *marker = qgis::down_cast<QgsMarkerSymbol *>( mSymbol.get() );
433 const double size = std::max( 0.0, marker->
size() + increment );
435 symbolChanged =
true;
442 QgsLineSymbol *line = qgis::down_cast<QgsLineSymbol *>( mSymbol.get() );
445 const double width = std::max( 0.0, line->
width() + increment );
447 symbolChanged =
true;
467 QToolButton::wheelEvent( event );
471void QgsSymbolButton::prepareMenu()
479 QAction *configureAction =
new QAction( tr(
"Configure Symbol…" ),
this );
480 mMenu->addAction( configureAction );
481 connect( configureAction, &QAction::triggered,
this, &QgsSymbolButton::showSettingsDialog );
483 QAction *copySymbolAction =
new QAction( tr(
"Copy Symbol" ),
this );
484 copySymbolAction->setEnabled( !
isNull() );
485 mMenu->addAction( copySymbolAction );
490 QAction *pasteSymbolAction =
new QAction( tr(
"Paste Symbol" ),
this );
494 if ( tempSymbol && tempSymbol->type() == mType )
500 pasteSymbolAction->setEnabled(
false );
502 mMenu->addAction( pasteSymbolAction );
507 QAction *nullAction =
new QAction( tr(
"Clear Current Symbol" ),
this );
508 nullAction->setEnabled( !
isNull() );
509 mMenu->addAction( nullAction );
514 if ( mDefaultSymbol )
516 QAction *defaultSymbolAction =
new QAction( tr(
"Default Symbol" ),
this );
518 mMenu->addAction( defaultSymbolAction );
524 mMenu->addSeparator();
527 colorWheel->
setColor( mSymbol->color() );
531 mMenu->addAction( colorAction );
534 QColor alphaColor = mSymbol->color();
535 alphaColor.setAlphaF( mSymbol->opacity() );
541 const double opacity = color.alphaF();
542 mSymbol->setOpacity( opacity );
548 mMenu->addAction( alphaAction );
552 QList< QgsColorScheme * >::iterator it = schemeList.begin();
553 for ( ; it != schemeList.end(); ++it )
557 mMenu->addAction( colorAction );
562 mMenu->addSeparator();
564 QAction *copyColorAction =
new QAction( tr(
"Copy Color" ),
this );
565 mMenu->addAction( copyColorAction );
568 QAction *pasteColorAction =
new QAction( tr(
"Paste Color" ),
this );
572 bool hasAlpha =
false;
573 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
575 pasteColorAction->setIcon( createColorIcon( clipColor ) );
579 pasteColorAction->setEnabled(
false );
581 mMenu->addAction( pasteColorAction );
584 QAction *pickColorAction =
new QAction( tr(
"Pick Color" ),
this );
585 mMenu->addAction( pickColorAction );
586 connect( pickColorAction, &QAction::triggered,
this, &QgsSymbolButton::activatePicker );
588 QAction *chooseColorAction =
new QAction( tr(
"Choose Color…" ),
this );
589 mMenu->addAction( chooseColorAction );
590 connect( chooseColorAction, &QAction::triggered,
this, &QgsSymbolButton::showColorDialog );
594void QgsSymbolButton::addRecentColor(
const QColor &color )
599void QgsSymbolButton::activatePicker()
605 mPickingColor =
true;
606 setMouseTracking(
true );
612 if ( e->type() == QEvent::EnabledChange )
616 QToolButton::changeEvent( e );
622 QToolButton::showEvent( e );
627 QToolButton::resizeEvent( event );
633void QgsSymbolButton::updatePreview(
const QColor &color,
QgsSymbol *tempSymbol )
635 QSize currentIconSize;
639 if ( !mIconSize.isValid() )
642 QStyleOptionToolButton opt;
643 initStyleOption( &opt );
644 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
648 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
650 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
653 currentIconSize = mIconSize;
659 currentIconSize = QSize( width() - 10, height() - 6 );
661 currentIconSize = QSize( width() - 10, height() - 12 );
665 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
670 std::unique_ptr< QgsSymbol > previewSymbol;
674 previewSymbol.reset( tempSymbol->
clone() );
678 previewSymbol.reset( mSymbol->clone() );
682 setIconSize( currentIconSize );
684 setToolTip( QString( ) );
688 if ( color.isValid() )
689 previewSymbol->setColor( color );
693 setIconSize( currentIconSize );
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 );
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 ) );
708bool QgsSymbolButton::colorFromMimeData(
const QMimeData *mimeData, QColor &resultColor,
bool &hasAlpha )
713 if ( mimeColor.isValid() )
715 resultColor = mimeColor;
723QPixmap QgsSymbolButton::createColorIcon(
const QColor &color )
const
727 QPixmap pixmap( iconSize, iconSize );
728 pixmap.fill( Qt::transparent );
734 p.setBrush( QBrush( color ) );
737 p.setPen( QColor( 197, 197, 197 ) );
738 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
743void QgsSymbolButton::stopPicking( QPoint eventPos,
bool samplingColor )
748 QgsApplication::restoreOverrideCursor();
749 setMouseTracking(
false );
750 mPickingColor =
false;
752 if ( !samplingColor )
761 addRecentColor( newColor );
764void QgsSymbolButton::showColorDialog()
772 const QColor currentColor = mSymbol->color();
777 if ( currentColor.isValid() )
784 if ( newColor.isValid() )
786 setColor( newColor );
793 QgsColorDialog dialog(
this, Qt::WindowFlags(), mSymbol->color() );
794 dialog.setTitle( tr(
"Symbol Color" ) );
795 dialog.setAllowOpacity(
true );
797 if ( dialog.exec() && dialog.color().isValid() )
808 mDialogTitle = title;
818 return mSymbol.get();
843 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,...