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;