28#include "moc_qgscolorswatchgrid.cpp"
30using namespace Qt::StringLiterals;
32#define NUMBER_COLORS_PER_ROW 10
40 setMouseTracking(
true );
42 setFocusPolicy( Qt::StrongFocus );
43 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
48 mSwatchOutlineSize = std::max( fontMetrics().horizontalAdvance(
'.' ) * 0.4, 1.0 );
50 mSwatchSpacing = mSwatchSize * 0.3;
51 mSwatchMargin = mLabelMargin;
61 return QSize( mWidth, calculateHeight() );
66 return QSize( mWidth, calculateHeight() );
84 mColors = mScheme->fetchColors( mContext, mBaseColor );
94 QPainter painter(
this );
102 const int newBox = swatchForPosition( event->pos() );
104 mDrawBoxDepressed =
event->buttons() & Qt::LeftButton;
105 if ( newBox != mCurrentHoverBox )
108 mCurrentHoverBox = newBox;
111 updateTooltip( newBox );
117void QgsColorSwatchGrid::updateTooltip(
const int colorIdx )
119 if ( colorIdx >= 0 && colorIdx < mColors.length() )
121 const QColor color = mColors.at( colorIdx ).first;
124 const QString colorName = mColors.at( colorIdx ).second;
127 if ( !colorName.isEmpty() )
128 info += u
"<h3>%1</h3><p>"_s.arg( colorName );
137 setToolTip( QString() );
143 if ( !mDrawBoxDepressed && event->buttons() & Qt::LeftButton )
145 mCurrentHoverBox = swatchForPosition( event->pos() );
146 mDrawBoxDepressed =
true;
149 mPressedOnWidget =
true;
154 if ( !mPressedOnWidget )
159 const int box = swatchForPosition( event->pos() );
160 if ( mDrawBoxDepressed && event->button() == Qt::LeftButton )
162 mCurrentHoverBox = box;
163 mDrawBoxDepressed =
false;
167 if ( box >= 0 && box < mColors.length() && event->button() == Qt::LeftButton )
177 if ( event->key() == Qt::Key_Right )
179 mCurrentFocusBox = std::min<int>( mCurrentFocusBox + 1, mColors.length() - 1 );
181 else if ( event->key() == Qt::Key_Left )
183 mCurrentFocusBox = std::max<int>( mCurrentFocusBox - 1, 0 );
185 else if ( event->key() == Qt::Key_Up )
191 if ( currentRow >= 0 )
198 focusPreviousChild();
201 else if ( event->key() == Qt::Key_Down )
208 if ( box < mColors.length() )
210 mCurrentFocusBox = box;
218 else if ( event->key() == Qt::Key_Enter || event->key() == Qt::Key_Space )
221 emit
colorChanged( mColors.at( mCurrentFocusBox ).first );
226 QWidget::keyPressEvent( event );
247int QgsColorSwatchGrid::calculateHeight()
const
250 return numberRows * ( mSwatchSize ) + ( numberRows - 1 ) * mSwatchSpacing + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin + mSwatchMargin;
253void QgsColorSwatchGrid::draw( QPainter &painter )
255 const QPalette pal = QPalette( qApp->palette() );
256 const QColor headerBgColor = pal.color( QPalette::Mid );
257 const QColor headerTextColor = pal.color( QPalette::BrightText );
258 const QColor highlight = pal.color( QPalette::Highlight );
261 painter.setBrush( headerBgColor );
262 painter.setPen( Qt::NoPen );
263 painter.drawRect( QRect( 0, 0, width(), mLabelHeight + 0.5 * mLabelMargin ) );
266 painter.setPen( headerTextColor );
267 painter.drawText( QRect( mLabelMargin, 0.25 * mLabelMargin, width() - 2 * mLabelMargin, mLabelHeight ), Qt::AlignLeft | Qt::AlignVCenter, mScheme->schemeName() );
270 QgsNamedColorList::const_iterator colorIt = mColors.constBegin();
272 for ( ; colorIt != mColors.constEnd(); ++colorIt )
277 QRect swatchRect = QRect( column * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin, row * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin, mSwatchSize, mSwatchSize );
279 if ( mCurrentHoverBox == index )
282 swatchRect.adjust( -1, -1, 1, 1 );
286 if ( ( *colorIt ).first.alpha() != 255 )
288 const QBrush checkBrush = QBrush( transparentBackground() );
289 painter.setPen( Qt::NoPen );
290 painter.setBrush( checkBrush );
291 painter.drawRect( swatchRect );
294 if ( mCurrentHoverBox == index )
296 if ( mDrawBoxDepressed )
298 painter.setPen( QPen( QColor( 100, 100, 100 ), mSwatchOutlineSize ) );
303 painter.setPen( QPen( QColor( 220, 220, 220 ), mSwatchOutlineSize ) );
306 else if ( mFocused && index == mCurrentFocusBox )
308 painter.setPen( highlight );
310 else if ( ( *colorIt ).first.name() == mBaseColor.name() )
313 painter.setPen( QPen( QColor( 75, 75, 75 ), mSwatchOutlineSize ) );
317 painter.setPen( QPen( QColor( 197, 197, 197 ), mSwatchOutlineSize ) );
320 painter.setBrush( ( *colorIt ).first );
321 painter.drawRect( swatchRect );
327QPixmap QgsColorSwatchGrid::transparentBackground()
329 static QPixmap sTranspBkgrd;
331 if ( sTranspBkgrd.isNull() )
337int QgsColorSwatchGrid::swatchForPosition( QPoint position )
const
341 const int column = ( position.x() - mSwatchMargin ) / ( mSwatchSize + mSwatchSpacing );
342 const int xRem = ( position.x() - mSwatchMargin ) % ( mSwatchSize + mSwatchSpacing );
343 const int row = ( position.y() - mSwatchMargin - mLabelHeight ) / ( mSwatchSize + mSwatchSpacing );
344 const int yRem = ( position.y() - mSwatchMargin - mLabelHeight ) % ( mSwatchSize + mSwatchSpacing );
361 : QWidgetAction( parent )
366 setDefaultWidget( mColorSwatchGrid );
369 connect(
this, &QAction::hovered,
this, &QgsColorSwatchGridAction::onHover );
373 setVisible( !mColorSwatchGrid->colors()->isEmpty() );
378 mColorSwatchGrid->setBaseColor(
baseColor );
383 return mColorSwatchGrid->baseColor();
388 return mColorSwatchGrid->context();
393 mColorSwatchGrid->setContext(
context );
398 mColorSwatchGrid->refreshColors();
400 setVisible( !mColorSwatchGrid->colors()->isEmpty() );
403void QgsColorSwatchGridAction::setColor(
const QColor &color )
407 if ( mMenu && mDismissOnColorSelection )
413void QgsColorSwatchGridAction::onHover()
417 if ( mSuppressRecurse )
424 mSuppressRecurse =
true;
425 mMenu->setActiveAction(
this );
426 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.
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
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.
#define NUMBER_COLORS_PER_ROW