35#include <QStyleOptionToolButton> 
   36#include <QWidgetAction> 
   44  : QToolButton( parent )
 
   45  , mColorDialogTitle( cdt.isEmpty() ? tr( 
"Select Color" ) : cdt )
 
   46  , mNoColorString( tr( 
"No color" ) )
 
   51  setAcceptDrops( 
true );
 
   52  setMinimumSize( QSize( 24, 16 ) );
 
   53  connect( 
this, &QAbstractButton::clicked, 
this, &QgsColorButton::buttonClicked );
 
   56  mMenu = 
new QMenu( 
this );
 
   57  connect( mMenu, &QMenu::aboutToShow, 
this, &QgsColorButton::prepareMenu );
 
   59  setPopupMode( QToolButton::MenuButtonPopup );
 
   62  mMinimumSize = QSize( 120, 22 );
 
   64  mMinimumSize = QSize( 120, 28 );
 
   67  mMinimumSize.setHeight( std::max( 
static_cast<int>( 
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.1 ), mMinimumSize.height() ) );
 
 
   88  static QPixmap sTranspBkgrd;
 
   90  if ( sTranspBkgrd.isNull() )
 
 
   96void QgsColorButton::showColorDialog()
 
  101    const QColor currentColor = 
color();
 
  106    if ( currentColor.isValid() )
 
  120  const bool useNative = settings.
value( QStringLiteral( 
"qgis/native_color_dialogs" ), 
false ).toBool();
 
  124    newColor = QColorDialog::getColor( 
color(), 
this, mColorDialogTitle, mAllowOpacity ? QColorDialog::ShowAlphaChannel : ( QColorDialog::ColorDialogOption )0 );
 
  129    dialog.setTitle( mColorDialogTitle );
 
  130    dialog.setAllowOpacity( mAllowOpacity );
 
  134      newColor = dialog.color();
 
  138  if ( newColor.isValid() )
 
  140    setValidColor( newColor );
 
  149  if ( !mDefaultColor.isValid() )
 
 
  171  if ( e->type() == QEvent::ToolTip && isEnabled() )
 
  173    QColor 
c = linkedProjectColor();
 
  174    const bool isProjectColor = 
c.isValid();
 
  175    if ( !isProjectColor )
 
  178    QString info = ( isProjectColor ? QStringLiteral( 
"<p>%1: %2</p>" ).arg( tr( 
"Linked color" ), mLinkedColorName ) : QString() );
 
  184  return QToolButton::event( e );
 
 
  189  QColor noColor = QColor( mColor );
 
  190  noColor.setAlpha( 0 );
 
 
  203  if ( e->button() == Qt::RightButton )
 
  205    QToolButton::showMenu();
 
  208  else if ( e->button() == Qt::LeftButton )
 
  210    mDragStartPosition = e->pos();
 
  212  QToolButton::mousePressEvent( e );
 
 
  215bool QgsColorButton::colorFromMimeData( 
const QMimeData *mimeData, QColor &resultColor )
 
  217  bool hasAlpha = 
false;
 
  220  if ( mimeColor.isValid() )
 
  222    if ( !mAllowOpacity )
 
  225      mimeColor.setAlpha( 255 );
 
  227    else if ( !hasAlpha )
 
  230      mimeColor.setAlpha( mColor.alpha() );
 
  232    resultColor = mimeColor;
 
  250  QColor 
c = linkedProjectColor();
 
  254  if ( !( e->buttons() & Qt::LeftButton ) || !
c.isValid() )
 
  257    QToolButton::mouseMoveEvent( e );
 
  261  if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
 
  264    QToolButton::mouseMoveEvent( e );
 
  269  QDrag *drag = 
new QDrag( 
this );
 
  272  drag->exec( Qt::CopyAction );
 
 
  281    stopPicking( e->globalPos() );
 
  286  QToolButton::mouseReleaseEvent( e );
 
 
  289void QgsColorButton::stopPicking( QPoint eventPos, 
bool samplingColor )
 
  294  QgsApplication::restoreOverrideCursor();
 
  295  setMouseTracking( 
false );
 
  296  mPickingColor = 
false;
 
  298  if ( !samplingColor )
 
  306  addRecentColor( mColor );
 
  309QColor QgsColorButton::linkedProjectColor()
 const 
  311  QList<QgsProjectColorScheme *> projectSchemes;
 
  313  if ( projectSchemes.length() > 0 )
 
  317    for ( 
const auto &
color : colors )
 
  319      if ( 
color.second.isEmpty() )
 
  322      if ( 
color.second == mLinkedColorName )
 
  333  if ( !mPickingColor )
 
  336    QToolButton::keyPressEvent( e );
 
  341  stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
 
 
  346  const bool isProjectColor = linkedProjectColor().isValid();
 
  347  if ( isProjectColor )
 
  352  if ( colorFromMimeData( e->mimeData(), mimeColor ) )
 
  357    e->acceptProposedAction();
 
 
  371  const bool isProjectColor = linkedProjectColor().isValid();
 
  372  if ( isProjectColor )
 
  377  if ( colorFromMimeData( e->mimeData(), mimeColor ) )
 
  380    e->acceptProposedAction();
 
  382    addRecentColor( mimeColor );
 
 
  388  if ( mAllowOpacity && isEnabled() && !
isNull() )
 
  390    const double increment = ( ( 
event->modifiers() & Qt::ControlModifier ) ? 0.01 : 0.1 ) *
 
  391                             ( 
event->angleDelta().y() > 0 ? 1 : -1 );
 
  392    const double alpha = std::min( std::max( 0.0, mColor.alphaF() + increment ), 1.0 );
 
  393    mColor.setAlphaF( alpha );
 
  401    QToolButton::wheelEvent( 
event );
 
 
  405void QgsColorButton::setValidColor( 
const QColor &newColor )
 
  407  if ( newColor.isValid() )
 
  410    addRecentColor( newColor );
 
  414void QgsColorButton::setValidTemporaryColor( 
const QColor &newColor )
 
  416  if ( newColor.isValid() )
 
  427  QPixmap pixmap( iconSize, iconSize );
 
  428  pixmap.fill( Qt::transparent );
 
  437    p.setPen( Qt::NoPen );
 
  438    p.setBrush( checkBrush );
 
  439    p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
 
  443  p.setBrush( QBrush( 
color ) );
 
  446  p.setPen( QColor( 197, 197, 197 ) );
 
  447  p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
 
 
  452void QgsColorButton::buttonClicked()
 
  454  if ( linkedProjectColor().isValid() )
 
  456    QToolButton::showMenu();
 
  472void QgsColorButton::prepareMenu()
 
  480  const bool isProjectColor = linkedProjectColor().isValid();
 
  482  if ( !isProjectColor )
 
  486      QAction *nullAction = 
new QAction( mNullColorString.isEmpty() ? tr( 
"Clear Color" ) : mNullColorString, this );
 
  488      mMenu->addAction( nullAction );
 
  493    if ( mDefaultColor.isValid() )
 
  495      QAction *defaultColorAction = 
new QAction( tr( 
"Default Color" ), 
this );
 
  497      mMenu->addAction( defaultColorAction );
 
  501    if ( mShowNoColorOption )
 
  503      QAction *noColorAction = 
new QAction( mNoColorString, 
this );
 
  504      noColorAction->setIcon( 
createMenuIcon( Qt::transparent, 
false ) );
 
  505      mMenu->addAction( noColorAction );
 
  509    mMenu->addSeparator();
 
  515    mMenu->addAction( colorAction );
 
  527      mMenu->addAction( alphaAction );
 
  530    if ( mColorSchemeRegistry )
 
  534      QList< QgsColorScheme * >::iterator it = schemeList.begin();
 
  535      for ( ; it != schemeList.end(); ++it )
 
  539        mMenu->addAction( colorAction );
 
  545    mMenu->addSeparator();
 
  548  if ( isProjectColor )
 
  550    QAction *unlinkAction = 
new QAction( tr( 
"Unlink Color" ), mMenu );
 
  551    mMenu->addAction( unlinkAction );
 
  555  QAction *copyColorAction = 
new QAction( tr( 
"Copy Color" ), 
this );
 
  556  mMenu->addAction( copyColorAction );
 
  559  if ( !isProjectColor )
 
  561    QAction *pasteColorAction = 
new QAction( tr( 
"Paste Color" ), 
this );
 
  565    if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
 
  571      pasteColorAction->setEnabled( 
false );
 
  573    mMenu->addAction( pasteColorAction );
 
  576    QAction *pickColorAction = 
new QAction( tr( 
"Pick Color" ), 
this );
 
  577    mMenu->addAction( pickColorAction );
 
  580    QAction *chooseColorAction = 
new QAction( tr( 
"Choose Color…" ), 
this );
 
  581    mMenu->addAction( chooseColorAction );
 
  582    connect( chooseColorAction, &QAction::triggered, 
this, &QgsColorButton::showColorDialog );
 
  588  if ( e->type() == QEvent::EnabledChange )
 
  592  QToolButton::changeEvent( e );
 
 
  596void QgsColorButton::paintEvent( QPaintEvent *e )
 
  598  QToolButton::paintEvent( e );
 
  600  if ( !mBackgroundSet )
 
  610  QToolButton::showEvent( e );
 
 
  615  QToolButton::resizeEvent( 
event );
 
 
  623  const QColor oldColor = mColor;
 
  627  if ( oldColor != mColor || ( mColor == QColor( Qt::black ) && !mColorSet ) )
 
 
  640void QgsColorButton::addRecentColor( 
const QColor &color )
 
  647  QColor backgroundColor = 
color;
 
  648  bool isProjectColor = 
false;
 
  649  if ( !backgroundColor.isValid() && !mLinkedColorName.isEmpty() )
 
  651    backgroundColor = linkedProjectColor();
 
  652    isProjectColor = backgroundColor.isValid();
 
  653    if ( !isProjectColor )
 
  655      mLinkedColorName.clear(); 
 
  659  if ( !backgroundColor.isValid() )
 
  661    backgroundColor = mColor;
 
  664  QSize currentIconSize;
 
  668    if ( !mIconSize.isValid() )
 
  671      QStyleOptionToolButton opt;
 
  672      initStyleOption( &opt );
 
  673      const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
 
  677      mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
 
  679      mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
 
  682    currentIconSize = mIconSize;
 
  688    currentIconSize = QSize( width() - 10, height() - 6 );
 
  690    currentIconSize = QSize( width() - 10, height() - 12 );
 
  694  if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
 
  700  const double pixelRatio = devicePixelRatioF();
 
  701  QPixmap pixmap( currentIconSize * pixelRatio );
 
  702  pixmap.setDevicePixelRatio( pixelRatio );
 
  703  pixmap.fill( Qt::transparent );
 
  705  if ( backgroundColor.isValid() )
 
  707    const QRectF rect( 0, 0,
 
  708                       currentIconSize.width(),
 
  709                       currentIconSize.height() );
 
  712    p.setRenderHint( QPainter::Antialiasing );
 
  713    p.setPen( Qt::NoPen );
 
  714    if ( mAllowOpacity && backgroundColor.alpha() < 255 )
 
  718      p.setBrush( checkBrush );
 
  719      p.drawRoundedRect( rect, 3, 3 );
 
  723    p.setBrush( backgroundColor );
 
  724    p.drawRoundedRect( rect, 3, 3 );
 
  728  setIconSize( currentIconSize );
 
 
  735  QColor 
c = linkedProjectColor();
 
 
  744  if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
 
  748    addRecentColor( clipColor );
 
 
  756  mCurrentColor = mColor;
 
  760  mPickingColor = 
true;
 
  761  setMouseTracking( 
true );
 
 
  766  QColor 
c = linkedProjectColor();
 
 
  774  mAllowOpacity = allow;
 
 
  779  mColorDialogTitle = title;
 
 
  784  return mColorDialogTitle;
 
 
  790  setMenu( 
showMenu ? mMenu : nullptr );
 
  791  setPopupMode( 
showMenu ? QToolButton::MenuButtonPopup : QToolButton::DelayedPopup );
 
 
  804  mDefaultColor = 
color;
 
 
  810  mNullColorString = nullString;
 
 
  820  return !mColor.isValid();
 
 
  825  mLinkedColorName = name;
 
 
static const double UI_SCALE_FACTOR
UI scaling factor.
 
static QPixmap getThemePixmap(const QString &name, const QColor &foreColor=QColor(), const QColor &backColor=QColor(), int size=16)
Helper to get a theme icon as a pixmap.
 
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.
 
Registry of color schemes.
 
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
 
static QColor sampleColor(QPoint point)
Samples the color on screen at the specified global point (pixel).
 
A color scheme which contains project specific colors set through project properties dialog.
 
QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor()) override
Gets a list of colors from the scheme.
 
static QgsProject * instance()
Returns the QgsProject singleton instance.
 
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
 
static void addRecentColor(const QColor &color)
Adds a color to the list of recent colors.
 
This class is a composition of two QSettings instances:
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
 
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
 
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
 
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c