21 #include <QMouseEvent>    25 #define NUMBER_COLORS_PER_ROW 10 //number of color swatches per row    31   , mDrawBoxDepressed( false )
    32   , mCurrentHoverBox( -1 )
    34   , mCurrentFocusBox( 0 )
    35   , mPressedOnWidget( false )
    38   setMouseTracking( 
true );
    40   setFocusPolicy( Qt::StrongFocus );
    41   setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
    45 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)    51 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)    57 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)    58   mSwatchOutlineSize = std::max( fontMetrics().width( QStringLiteral( 
"." ) ) * 0.4, 1.0 );
    60   mSwatchOutlineSize = std::max( fontMetrics().horizontalAdvance( 
'.' ) * 0.4, 1.0 );
    63   mSwatchSpacing = mSwatchSize * 0.3;
    64   mSwatchMargin = mLabelMargin;
    74   return QSize( mWidth, calculateHeight() );
    79   return QSize( mWidth, calculateHeight() );
    97   mColors = mScheme->
fetchColors( mContext, mBaseColor );
   107   QPainter painter( 
this );
   115   int newBox = swatchForPosition( event->pos() );
   117   mDrawBoxDepressed = 
event->buttons() & Qt::LeftButton;
   118   if ( newBox != mCurrentHoverBox )
   121     mCurrentHoverBox = newBox;
   124     updateTooltip( newBox );
   130 void QgsColorSwatchGrid::updateTooltip( 
const int colorIdx )
   132   if ( colorIdx >= 0 && colorIdx < mColors.length() )
   134     QColor color = mColors.at( colorIdx ).first;
   137     QString colorName = mColors.at( colorIdx ).second;
   140 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)   143     int width = 
static_cast< int >( 
Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 
'X' ) * 23 );
   145     int height = 
static_cast< int >( width / 1.61803398875 ); 
   146     int margin = 
static_cast< int >( height * 0.1 );
   147     QImage icon = QImage( width + 2 * margin, height + 2 * margin, QImage::Format_ARGB32 );
   148     icon.fill( Qt::transparent );
   154     QBrush checkBrush = QBrush( transparentBackground() );
   155     p.setPen( Qt::NoPen );
   156     p.setBrush( checkBrush );
   157     p.drawRect( margin, margin, width, height );
   160     p.setBrush( QBrush( mColors.at( colorIdx ).first ) );
   163     p.setPen( QColor( 197, 197, 197 ) );
   164     p.drawRect( margin, margin, width, height );
   168     QBuffer buffer( &data );
   169     icon.save( &buffer, 
"PNG", 100 );
   172     if ( !colorName.isEmpty() )
   173       info += QStringLiteral( 
"<h3>%1</h3><p>" ).arg( colorName );
   175     info += QStringLiteral( 
"<b>HEX</b> %1<br>"   177                             "<b>HSV</b> %3,%4,%5<p>" ).arg( color.name(),
   179             .arg( color.hue() ).arg( color.saturation() ).arg( color.value() );
   180     info += QStringLiteral( 
"<img src='data:image/png;base64, %0'>" ).arg( QString( data.toBase64() ) );
   188     setToolTip( QString() );
   194   if ( !mDrawBoxDepressed && event->buttons() & Qt::LeftButton )
   196     mCurrentHoverBox = swatchForPosition( event->pos() );
   197     mDrawBoxDepressed = 
true;
   200   mPressedOnWidget = 
true;
   205   if ( ! mPressedOnWidget )
   210   int box = swatchForPosition( event->pos() );
   211   if ( mDrawBoxDepressed && event->button() == Qt::LeftButton )
   213     mCurrentHoverBox = box;
   214     mDrawBoxDepressed = 
false;
   218   if ( box >= 0 && box < mColors.length() && 
event->button() == Qt::LeftButton )
   228   if ( event->key() == Qt::Key_Right )
   230     mCurrentFocusBox = std::min( mCurrentFocusBox + 1, mColors.length() - 1 );
   232   else if ( event->key() == Qt::Key_Left )
   234     mCurrentFocusBox = std::max( mCurrentFocusBox - 1, 0 );
   236   else if ( event->key() == Qt::Key_Up )
   242     if ( currentRow >= 0 )
   249       focusPreviousChild();
   252   else if ( event->key() == Qt::Key_Down )
   259     if ( box < mColors.length() )
   261       mCurrentFocusBox = box;
   269   else if ( event->key() == Qt::Key_Enter || 
event->key() == Qt::Key_Space )
   272     emit 
colorChanged( mColors.at( mCurrentFocusBox ).first );
   277     QWidget::keyPressEvent( event );
   298 int QgsColorSwatchGrid::calculateHeight()
 const   301   return numberRows * ( mSwatchSize ) + ( numberRows - 1 ) * mSwatchSpacing + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin + mSwatchMargin;
   304 void QgsColorSwatchGrid::draw( QPainter &painter )
   306   QPalette 
pal = QPalette( qApp->palette() );
   307   QColor headerBgColor = pal.color( QPalette::Mid );
   308   QColor headerTextColor = pal.color( QPalette::BrightText );
   309   QColor highlight = pal.color( QPalette::Highlight );
   312   painter.setBrush( headerBgColor );
   313   painter.setPen( Qt::NoPen );
   314   painter.drawRect( QRect( 0, 0, width(), mLabelHeight + 0.5 * mLabelMargin ) );
   317   painter.setPen( headerTextColor );
   318   painter.drawText( QRect( mLabelMargin, 0.25 * mLabelMargin, width() - 2 * mLabelMargin, mLabelHeight ),
   319                     Qt::AlignLeft | Qt::AlignVCenter, mScheme->
schemeName() );
   322   QgsNamedColorList::const_iterator colorIt = mColors.constBegin();
   324   for ( ; colorIt != mColors.constEnd(); ++colorIt )
   329     QRect swatchRect = QRect( column * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin,
   330                               row * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin,
   331                               mSwatchSize, mSwatchSize );
   333     if ( mCurrentHoverBox == index )
   336       swatchRect.adjust( -1, -1, 1, 1 );
   340     if ( ( *colorIt ).first.alpha() != 255 )
   342       QBrush checkBrush = QBrush( transparentBackground() );
   343       painter.setPen( Qt::NoPen );
   344       painter.setBrush( checkBrush );
   345       painter.drawRect( swatchRect );
   348     if ( mCurrentHoverBox == index )
   350       if ( mDrawBoxDepressed )
   352         painter.setPen( QPen( QColor( 100, 100, 100 ), mSwatchOutlineSize ) );
   357         painter.setPen( QPen( QColor( 220, 220, 220 ), mSwatchOutlineSize ) );
   360     else if ( mFocused && index == mCurrentFocusBox )
   362       painter.setPen( highlight );
   364     else if ( ( *colorIt ).first.name() == mBaseColor.name() )
   367       painter.setPen( QPen( QColor( 75, 75, 75 ), mSwatchOutlineSize ) );
   371       painter.setPen( QPen( QColor( 197, 197, 197 ), mSwatchOutlineSize ) );
   374     painter.setBrush( ( *colorIt ).first );
   375     painter.drawRect( swatchRect );
   381 QPixmap QgsColorSwatchGrid::transparentBackground()
   383   static QPixmap sTranspBkgrd;
   385   if ( sTranspBkgrd.isNull() )
   391 int QgsColorSwatchGrid::swatchForPosition( QPoint position )
 const   395   int column = ( position.x() - mSwatchMargin ) / ( mSwatchSize + mSwatchSpacing );
   396   int xRem = ( position.x() - mSwatchMargin ) % ( mSwatchSize + mSwatchSpacing );
   397   int row = ( position.y() - mSwatchMargin - mLabelHeight ) / ( mSwatchSize + mSwatchSpacing );
   398   int yRem = ( position.y() - mSwatchMargin - mLabelHeight ) % ( mSwatchSize + mSwatchSpacing );
   415   : QWidgetAction( parent )
   417   , mSuppressRecurse( false )
   418   , mDismissOnColorSelection( true )
   422   setDefaultWidget( mColorSwatchGrid );
   425   connect( 
this, &QAction::hovered, 
this, &QgsColorSwatchGridAction::onHover );
   429   setVisible( !mColorSwatchGrid->
colors()->isEmpty() );
   444   return mColorSwatchGrid->
context();
   456   setVisible( !mColorSwatchGrid->
colors()->isEmpty() );
   459 void QgsColorSwatchGridAction::setColor( 
const QColor &color )
   463   if ( mMenu && mDismissOnColorSelection )
   469 void QgsColorSwatchGridAction::onHover()
   473   if ( mSuppressRecurse )
   480     mSuppressRecurse = 
true;
   481     mMenu->setActiveAction( 
this );
   482     mSuppressRecurse = 
false;
 void mouseReleaseEvent(QMouseEvent *event) override
 
void focusOutEvent(QFocusEvent *event) override
 
QgsColorSwatchGrid(QgsColorScheme *scheme, const QString &context=QString(), QWidget *parent=nullptr)
Construct a new color swatch grid. 
 
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget. 
 
static const double UI_SCALE_FACTOR
UI scaling factor. 
 
void refreshColors()
Reload colors from scheme and redraws the widget. 
 
Abstract base class for color schemes. 
 
void paintEvent(QPaintEvent *event) override
 
QString context() const
Gets the current context for the grid. 
 
QSize sizeHint() const override
 
QSize minimumSizeHint() const override
 
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget. 
 
A grid of color swatches, which allows for user selection. 
 
static QPixmap getThemePixmap(const QString &name)
Helper to get a theme icon as a pixmap. 
 
QColor baseColor() const
Gets the base color for the widget. 
 
QgsNamedColorList * colors()
Gets the list of colors shown in the grid. 
 
static QString encodeColor(const QColor &color)
 
#define NUMBER_COLORS_PER_ROW
 
QgsColorSwatchGridAction(QgsColorScheme *scheme, QMenu *menu=nullptr, const QString &context=QString(), QWidget *parent=nullptr)
Construct a new color swatch grid action. 
 
void hovered()
Emitted when mouse hovers over widget. 
 
QColor baseColor() const
Gets the base color for the color grid. 
 
void mousePressEvent(QMouseEvent *event) override
 
void mouseMoveEvent(QMouseEvent *event) override
 
void keyPressEvent(QKeyEvent *event) override
 
virtual QString schemeName() const =0
Gets the name for the color scheme. 
 
virtual QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor())=0
Gets a list of colors from the scheme. 
 
void setBaseColor(const QColor &baseColor)
Sets the base color for the widget. 
 
void refreshColors()
Reload colors from scheme and redraws the widget. 
 
void setContext(const QString &context)
Sets the current context for the grid. 
 
void setContext(const QString &context)
Sets the current context for the color grid. 
 
QString context() const
Gets the current context for the color grid. 
 
void setBaseColor(const QColor &baseColor)
Sets the base color for the color grid. 
 
void focusInEvent(QFocusEvent *event) override