20 #include <QMouseEvent> 23 #define NUMBER_COLORS_PER_ROW 10 //number of color swatches per row 29 , mDrawBoxDepressed( false )
30 , mCurrentHoverBox( -1 )
32 , mCurrentFocusBox( 0 )
33 , mPressedOnWidget( false )
36 setMouseTracking(
true );
38 setFocusPolicy( Qt::StrongFocus );
39 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
45 mSwatchOutlineSize = std::max( fontMetrics().width( QStringLiteral(
"." ) ) * 0.4, 1.0 );
47 mSwatchSpacing = mSwatchSize * 0.3;
48 mSwatchMargin = mLabelMargin;
58 return QSize( mWidth, calculateHeight() );
63 return QSize( mWidth, calculateHeight() );
81 mColors = mScheme->
fetchColors( mContext, mBaseColor );
91 QPainter painter(
this );
99 int newBox = swatchForPosition( event->pos() );
101 mDrawBoxDepressed =
event->buttons() & Qt::LeftButton;
102 if ( newBox != mCurrentHoverBox )
105 mCurrentHoverBox = newBox;
108 updateTooltip( newBox );
114 void QgsColorSwatchGrid::updateTooltip(
const int colorIdx )
116 if ( colorIdx >= 0 && colorIdx < mColors.length() )
119 QString colorName = mColors.at( colorIdx ).second;
120 if ( colorName.isEmpty() )
123 QColor color = mColors.at( colorIdx ).first;
124 colorName = QString( tr(
"rgb(%1, %2, %3)" ) ).arg( color.red() ).arg( color.green() ).arg( color.blue() );
126 setToolTip( colorName );
131 setToolTip( QString() );
137 if ( !mDrawBoxDepressed && event->buttons() & Qt::LeftButton )
139 mCurrentHoverBox = swatchForPosition( event->pos() );
140 mDrawBoxDepressed =
true;
143 mPressedOnWidget =
true;
148 if ( ! mPressedOnWidget )
153 int box = swatchForPosition( event->pos() );
154 if ( mDrawBoxDepressed && event->button() == Qt::LeftButton )
156 mCurrentHoverBox = box;
157 mDrawBoxDepressed =
false;
161 if ( box >= 0 && box < mColors.length() &&
event->button() == Qt::LeftButton )
171 if ( event->key() == Qt::Key_Right )
173 mCurrentFocusBox = std::min( mCurrentFocusBox + 1, mColors.length() - 1 );
175 else if ( event->key() == Qt::Key_Left )
177 mCurrentFocusBox = std::max( mCurrentFocusBox - 1, 0 );
179 else if ( event->key() == Qt::Key_Up )
185 if ( currentRow >= 0 )
192 focusPreviousChild();
195 else if ( event->key() == Qt::Key_Down )
202 if ( box < mColors.length() )
204 mCurrentFocusBox = box;
212 else if ( event->key() == Qt::Key_Enter ||
event->key() == Qt::Key_Space )
215 emit
colorChanged( mColors.at( mCurrentFocusBox ).first );
220 QWidget::keyPressEvent( event );
241 int QgsColorSwatchGrid::calculateHeight()
const 244 return numberRows * ( mSwatchSize ) + ( numberRows - 1 ) * mSwatchSpacing + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin + mSwatchMargin;
247 void QgsColorSwatchGrid::draw( QPainter &painter )
249 QPalette
pal = QPalette( qApp->palette() );
250 QColor headerBgColor = pal.color( QPalette::Mid );
251 QColor headerTextColor = pal.color( QPalette::BrightText );
252 QColor highlight = pal.color( QPalette::Highlight );
255 painter.setBrush( headerBgColor );
256 painter.setPen( Qt::NoPen );
257 painter.drawRect( QRect( 0, 0, width(), mLabelHeight + 0.5 * mLabelMargin ) );
260 painter.setPen( headerTextColor );
261 painter.drawText( QRect( mLabelMargin, 0.25 * mLabelMargin, width() - 2 * mLabelMargin, mLabelHeight ),
262 Qt::AlignLeft | Qt::AlignVCenter, mScheme->
schemeName() );
265 QgsNamedColorList::const_iterator colorIt = mColors.constBegin();
267 for ( ; colorIt != mColors.constEnd(); ++colorIt )
272 QRect swatchRect = QRect( column * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin,
273 row * ( mSwatchSize + mSwatchSpacing ) + mSwatchMargin + mLabelHeight + 0.5 * mLabelMargin,
274 mSwatchSize, mSwatchSize );
276 if ( mCurrentHoverBox == index )
279 swatchRect.adjust( -1, -1, 1, 1 );
283 if ( ( *colorIt ).first.alpha() != 255 )
285 QBrush checkBrush = QBrush( transparentBackground() );
286 painter.setPen( Qt::NoPen );
287 painter.setBrush( checkBrush );
288 painter.drawRect( swatchRect );
291 if ( mCurrentHoverBox == index )
293 if ( mDrawBoxDepressed )
295 painter.setPen( QPen( QColor( 100, 100, 100 ), mSwatchOutlineSize ) );
300 painter.setPen( QPen( QColor( 220, 220, 220 ), mSwatchOutlineSize ) );
303 else if ( mFocused && index == mCurrentFocusBox )
305 painter.setPen( highlight );
307 else if ( ( *colorIt ).first.name() == mBaseColor.name() )
310 painter.setPen( QPen( QColor( 75, 75, 75 ), mSwatchOutlineSize ) );
314 painter.setPen( QPen( QColor( 197, 197, 197 ), mSwatchOutlineSize ) );
317 painter.setBrush( ( *colorIt ).first );
318 painter.drawRect( swatchRect );
324 QPixmap QgsColorSwatchGrid::transparentBackground()
326 static QPixmap sTranspBkgrd;
328 if ( sTranspBkgrd.isNull() )
334 int QgsColorSwatchGrid::swatchForPosition( QPoint position )
const 338 int column = ( position.x() - mSwatchMargin ) / ( mSwatchSize + mSwatchSpacing );
339 int xRem = ( position.x() - mSwatchMargin ) % ( mSwatchSize + mSwatchSpacing );
340 int row = ( position.y() - mSwatchMargin - mLabelHeight ) / ( mSwatchSize + mSwatchSpacing );
341 int yRem = ( position.y() - mSwatchMargin - mLabelHeight ) % ( mSwatchSize + mSwatchSpacing );
358 : QWidgetAction( parent )
360 , mSuppressRecurse( false )
361 , mDismissOnColorSelection( true )
365 setDefaultWidget( mColorSwatchGrid );
368 connect(
this, &QAction::hovered,
this, &QgsColorSwatchGridAction::onHover );
372 setVisible( !mColorSwatchGrid->
colors()->isEmpty() );
387 return mColorSwatchGrid->
context();
399 setVisible( !mColorSwatchGrid->
colors()->isEmpty() );
402 void QgsColorSwatchGridAction::setColor(
const QColor &color )
406 if ( mMenu && mDismissOnColorSelection )
412 void QgsColorSwatchGridAction::onHover()
416 if ( mSuppressRecurse )
423 mSuppressRecurse =
true;
424 mMenu->setActiveAction(
this );
425 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
Get 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
Get the base color for the widget.
QgsNamedColorList * colors()
Gets the list of colors shown in the grid.
#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
Get 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
Get 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