25#define NUMBER_COLORS_PER_ROW 10  
   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 );
 
   46  mSwatchOutlineSize = std::max( fontMetrics().horizontalAdvance( 
'.' ) * 0.4, 1.0 );
 
   48  mSwatchSpacing = mSwatchSize * 0.3;
 
   49  mSwatchMargin = mLabelMargin;
 
   59  return QSize( mWidth, calculateHeight() );
 
   64  return QSize( mWidth, calculateHeight() );
 
   82  mColors = mScheme->
fetchColors( mContext, mBaseColor );
 
   92  QPainter painter( 
this );
 
  100  const int newBox = swatchForPosition( event->pos() );
 
  102  mDrawBoxDepressed = 
event->buttons() & Qt::LeftButton;
 
  103  if ( newBox != mCurrentHoverBox )
 
  106    mCurrentHoverBox = newBox;
 
  109    updateTooltip( newBox );
 
  115void QgsColorSwatchGrid::updateTooltip( 
const int colorIdx )
 
  117  if ( colorIdx >= 0 && colorIdx < mColors.length() )
 
  119    const QColor color = mColors.at( colorIdx ).first;
 
  122    const QString colorName = mColors.at( colorIdx ).second;
 
  125    const int width = 
static_cast< int >( 
Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 
'X' ) * 23 );
 
  126    const int height = 
static_cast< int >( width / 1.61803398875 ); 
 
  127    const int margin = 
static_cast< int >( height * 0.1 );
 
  128    QImage icon = QImage( width + 2 * margin, height + 2 * margin, QImage::Format_ARGB32 );
 
  129    icon.fill( Qt::transparent );
 
  135    const QBrush checkBrush = QBrush( transparentBackground() );
 
  136    p.setPen( Qt::NoPen );
 
  137    p.setBrush( checkBrush );
 
  138    p.drawRect( margin, margin, width, height );
 
  141    p.setBrush( QBrush( mColors.at( colorIdx ).first ) );
 
  144    p.setPen( QColor( 197, 197, 197 ) );
 
  145    p.drawRect( margin, margin, width, height );
 
  149    QBuffer buffer( &data );
 
  150    icon.save( &buffer, 
"PNG", 100 );
 
  153    if ( !colorName.isEmpty() )
 
  154      info += QStringLiteral( 
"<h3>%1</h3><p>" ).arg( colorName );
 
  156    info += QStringLiteral( 
"<b>HEX</b> %1<br>" 
  158                            "<b>HSV</b> %3,%4,%5<p>" ).arg( color.name(),
 
  160            .arg( color.hue() ).arg( color.saturation() ).arg( color.value() );
 
  161    info += QStringLiteral( 
"<img src='data:image/png;base64, %0'>" ).arg( QString( data.toBase64() ) );
 
  169    setToolTip( QString() );
 
  175  if ( !mDrawBoxDepressed && event->buttons() & Qt::LeftButton )
 
  177    mCurrentHoverBox = swatchForPosition( event->pos() );
 
  178    mDrawBoxDepressed = 
true;
 
  181  mPressedOnWidget = 
true;
 
  186  if ( ! mPressedOnWidget )
 
  191  const int box = swatchForPosition( event->pos() );
 
  192  if ( mDrawBoxDepressed && event->button() == Qt::LeftButton )
 
  194    mCurrentHoverBox = box;
 
  195    mDrawBoxDepressed = 
false;
 
  199  if ( box >= 0 && box < mColors.length() && event->button() == Qt::LeftButton )
 
  209  if ( event->key() == Qt::Key_Right )
 
  211    mCurrentFocusBox = std::min< int >( mCurrentFocusBox + 1, mColors.length() - 1 );
 
  213  else if ( event->key() == Qt::Key_Left )
 
  215    mCurrentFocusBox = std::max< int >( mCurrentFocusBox - 1, 0 );
 
  217  else if ( event->key() == Qt::Key_Up )
 
  223    if ( currentRow >= 0 )
 
  230      focusPreviousChild();
 
  233  else if ( event->key() == Qt::Key_Down )
 
  240    if ( box < mColors.length() )
 
  242      mCurrentFocusBox = box;
 
  250  else if ( event->key() == Qt::Key_Enter || event->key() == Qt::Key_Space )
 
  253    emit 
colorChanged( mColors.at( mCurrentFocusBox ).first );
 
  258    QWidget::keyPressEvent( event );
 
  279int QgsColorSwatchGrid::calculateHeight()
 const 
  282  return numberRows * ( mSwatchSize ) + ( numberRows - 1 ) * mSwatchSpacing + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin + mSwatchMargin;
 
  285void QgsColorSwatchGrid::draw( QPainter &painter )
 
  287  const QPalette 
pal = QPalette( qApp->palette() );
 
  288  const QColor headerBgColor = 
pal.color( QPalette::Mid );
 
  289  const QColor headerTextColor = 
pal.color( QPalette::BrightText );
 
  290  const QColor highlight = 
pal.color( QPalette::Highlight );
 
  293  painter.setBrush( headerBgColor );
 
  294  painter.setPen( Qt::NoPen );
 
  295  painter.drawRect( QRect( 0, 0, width(), mLabelHeight + 0.5 * mLabelMargin ) );
 
  298  painter.setPen( headerTextColor );
 
  299  painter.drawText( QRect( mLabelMargin, 0.25 * mLabelMargin, width() - 2 * mLabelMargin, mLabelHeight ),
 
  300                    Qt::AlignLeft | Qt::AlignVCenter, mScheme->
schemeName() );
 
  303  QgsNamedColorList::const_iterator colorIt = mColors.constBegin();
 
  305  for ( ; colorIt != mColors.constEnd(); ++colorIt )
 
  310    QRect swatchRect = QRect( column * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin,
 
  311                              row * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin,
 
  312                              mSwatchSize, mSwatchSize );
 
  314    if ( mCurrentHoverBox == index )
 
  317      swatchRect.adjust( -1, -1, 1, 1 );
 
  321    if ( ( *colorIt ).first.alpha() != 255 )
 
  323      const QBrush checkBrush = QBrush( transparentBackground() );
 
  324      painter.setPen( Qt::NoPen );
 
  325      painter.setBrush( checkBrush );
 
  326      painter.drawRect( swatchRect );
 
  329    if ( mCurrentHoverBox == index )
 
  331      if ( mDrawBoxDepressed )
 
  333        painter.setPen( QPen( QColor( 100, 100, 100 ), mSwatchOutlineSize ) );
 
  338        painter.setPen( QPen( QColor( 220, 220, 220 ), mSwatchOutlineSize ) );
 
  341    else if ( mFocused && index == mCurrentFocusBox )
 
  343      painter.setPen( highlight );
 
  345    else if ( ( *colorIt ).first.name() == mBaseColor.name() )
 
  348      painter.setPen( QPen( QColor( 75, 75, 75 ), mSwatchOutlineSize ) );
 
  352      painter.setPen( QPen( QColor( 197, 197, 197 ), mSwatchOutlineSize ) );
 
  355    painter.setBrush( ( *colorIt ).first );
 
  356    painter.drawRect( swatchRect );
 
  362QPixmap QgsColorSwatchGrid::transparentBackground()
 
  364  static QPixmap sTranspBkgrd;
 
  366  if ( sTranspBkgrd.isNull() )
 
  372int QgsColorSwatchGrid::swatchForPosition( QPoint position )
 const 
  376  const int column = ( position.x() - mSwatchMargin ) / ( mSwatchSize + mSwatchSpacing );
 
  377  const int xRem = ( position.x() - mSwatchMargin ) % ( mSwatchSize + mSwatchSpacing );
 
  378  const int row = ( position.y() - mSwatchMargin - mLabelHeight ) / ( mSwatchSize + mSwatchSpacing );
 
  379  const int yRem = ( position.y() - mSwatchMargin - mLabelHeight ) % ( mSwatchSize + mSwatchSpacing );
 
  396  : QWidgetAction( parent )
 
  398  , mSuppressRecurse( false )
 
  399  , mDismissOnColorSelection( true )
 
  403  setDefaultWidget( mColorSwatchGrid );
 
  406  connect( 
this, &QAction::hovered, 
this, &QgsColorSwatchGridAction::onHover );
 
  410  setVisible( !mColorSwatchGrid->
colors()->isEmpty() );
 
  425  return mColorSwatchGrid->
context();
 
  437  setVisible( !mColorSwatchGrid->
colors()->isEmpty() );
 
  440void QgsColorSwatchGridAction::setColor( 
const QColor &color )
 
  444  if ( mMenu && mDismissOnColorSelection )
 
  450void QgsColorSwatchGridAction::onHover()
 
  454  if ( mSuppressRecurse )
 
  461    mSuppressRecurse = 
true;
 
  462    mMenu->setActiveAction( 
this );
 
  463    mSuppressRecurse = 
false;
 
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.
 
Abstract base class for color schemes.
 
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 color grid.
 
QString context() const
Gets the current context for the color grid.
 
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
 
QgsColorSwatchGridAction(QgsColorScheme *scheme, QMenu *menu=nullptr, const QString &context=QString(), QWidget *parent=nullptr)
Construct a new color swatch grid action.
 
void refreshColors()
Reload colors from scheme and redraws the widget.
 
QColor baseColor() const
Gets the base color for the color grid.
 
void setContext(const QString &context)
Sets the current context for the color grid.
 
A grid of color swatches, which allows for user selection.
 
void mouseMoveEvent(QMouseEvent *event) override
 
void mousePressEvent(QMouseEvent *event) override
 
QColor baseColor() const
Gets the base color for the widget.
 
QgsColorSwatchGrid(QgsColorScheme *scheme, const QString &context=QString(), QWidget *parent=nullptr)
Construct a new color swatch grid.
 
void paintEvent(QPaintEvent *event) override
 
QgsNamedColorList * colors()
Gets the list of colors shown in the grid.
 
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
 
void setBaseColor(const QColor &baseColor)
Sets the base color for the widget.
 
QSize minimumSizeHint() const override
 
void mouseReleaseEvent(QMouseEvent *event) override
 
QSize sizeHint() const override
 
void refreshColors()
Reload colors from scheme and redraws the widget.
 
void focusInEvent(QFocusEvent *event) override
 
void keyPressEvent(QKeyEvent *event) override
 
void focusOutEvent(QFocusEvent *event) override
 
void hovered()
Emitted when mouse hovers over widget.
 
void setContext(const QString &context)
Sets the current context for the grid.
 
QString context() const
Gets the current context for the grid.
 
static QString encodeColor(const QColor &color)
 
#define NUMBER_COLORS_PER_ROW