27 #include <QMouseEvent> 31 #include <QDesktopWidget> 33 #include <QStyleOptionToolButton> 34 #include <QWidgetAction> 37 #include <QGridLayout> 38 #include <QPushButton> 41 : QToolButton( parent )
42 , mColorDialogTitle( cdt.isEmpty() ? tr(
"Select Color" ) : cdt )
43 , mNoColorString( tr(
"No color" ) )
48 setAcceptDrops(
true );
49 setMinimumSize( QSize( 24, 16 ) );
50 connect(
this, &QAbstractButton::clicked,
this, &QgsColorButton::buttonClicked );
53 mMenu =
new QMenu(
this );
54 connect( mMenu, &QMenu::aboutToShow,
this, &QgsColorButton::prepareMenu );
56 setPopupMode( QToolButton::MenuButtonPopup );
59 mMinimumSize = QSize( 120, 22 );
61 mMinimumSize = QSize( 120, 28 );
64 mMinimumSize.setHeight( std::max( static_cast<int>(
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.1 ), mMinimumSize.height() ) );
81 static QPixmap sTranspBkgrd;
83 if ( sTranspBkgrd.isNull() )
89 void QgsColorButton::showColorDialog()
94 QColor currentColor =
color();
99 if ( currentColor.isValid() )
113 bool useNative = settings.
value( QStringLiteral(
"qgis/native_color_dialogs" ),
false ).toBool();
117 newColor = QColorDialog::getColor(
color(),
this, mColorDialogTitle, mAllowOpacity ? QColorDialog::ShowAlphaChannel : ( QColorDialog::ColorDialogOption )0 );
122 dialog.
setTitle( mColorDialogTitle );
127 newColor = dialog.
color();
131 if ( newColor.isValid() )
133 setValidColor( newColor );
142 if ( !mDefaultColor.isValid() )
157 if ( e->type() == QEvent::ToolTip )
159 QString name = mColor.name();
160 int hue = mColor.hue();
161 int value = mColor.value();
162 int saturation = mColor.saturation();
166 int height =
static_cast< int >( width / 1.61803398875 );
168 int margin =
static_cast< int >( height * 0.1 );
169 QImage icon = QImage( width + 2 * margin, height + 2 * margin, QImage::Format_ARGB32 );
170 icon.fill( Qt::transparent );
177 p.setPen( Qt::NoPen );
178 p.setBrush( checkBrush );
179 p.drawRect( margin, margin, width, height );
182 p.setBrush( QBrush( mColor ) );
185 p.setPen( QColor( 197, 197, 197 ) );
186 p.drawRect( margin, margin, width, height );
190 QBuffer buffer( &data );
191 icon.save( &buffer,
"PNG", 100 );
193 QString info = QStringLiteral(
"<b>HEX</b> %1<br>" 195 "<b>HSV</b> %3,%4,%5<p>" 196 "<img src='data:image/png;base64, %0'>" ).arg( QString( data.toBase64() ), name,
198 .arg( hue ).arg( saturation ).arg( value );
201 return QToolButton::event( e );
208 QColor noColor = QColor( mColor );
209 noColor.setAlpha( 0 );
223 if ( e->button() == Qt::RightButton )
225 QToolButton::showMenu();
228 else if ( e->button() == Qt::LeftButton )
230 mDragStartPosition = e->pos();
232 QToolButton::mousePressEvent( e );
235 bool QgsColorButton::colorFromMimeData(
const QMimeData *mimeData, QColor &resultColor )
237 bool hasAlpha =
false;
240 if ( mimeColor.isValid() )
242 if ( !mAllowOpacity )
245 mimeColor.setAlpha( 255 );
247 else if ( !hasAlpha )
250 mimeColor.setAlpha( mColor.alpha() );
252 resultColor = mimeColor;
271 if ( !( e->buttons() & Qt::LeftButton ) || !mColor.isValid() )
274 QToolButton::mouseMoveEvent( e );
278 if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
281 QToolButton::mouseMoveEvent( e );
286 QDrag *drag =
new QDrag(
this );
289 drag->exec( Qt::CopyAction );
298 stopPicking( e->globalPos() );
303 QToolButton::mouseReleaseEvent( e );
306 void QgsColorButton::stopPicking( QPoint eventPos,
bool samplingColor )
311 QgsApplication::restoreOverrideCursor();
312 setMouseTracking(
false );
313 mPickingColor =
false;
315 if ( !samplingColor )
322 setColor( sampleColor( eventPos ) );
323 addRecentColor( mColor );
328 if ( !mPickingColor )
331 QToolButton::keyPressEvent( e );
336 stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
343 if ( colorFromMimeData( e->mimeData(), mimeColor ) )
348 e->acceptProposedAction();
364 if ( colorFromMimeData( e->mimeData(), mimeColor ) )
367 e->acceptProposedAction();
369 addRecentColor( mimeColor );
373 QColor QgsColorButton::sampleColor( QPoint point )
const 376 QScreen *screen = findScreenAt( point );
381 QPixmap snappedPixmap = screen->grabWindow( QApplication::desktop()->winId(), point.x(), point.y(), 1, 1 );
382 QImage snappedImage = snappedPixmap.toImage();
383 return snappedImage.pixel( 0, 0 );
386 QScreen *QgsColorButton::findScreenAt( QPoint pos )
388 for ( QScreen *screen : QGuiApplication::screens() )
390 if ( screen->geometry().contains( pos ) )
398 void QgsColorButton::setValidColor(
const QColor &newColor )
400 if ( newColor.isValid() )
403 addRecentColor( newColor );
407 void QgsColorButton::setValidTemporaryColor(
const QColor &newColor )
409 if ( newColor.isValid() )
415 QPixmap QgsColorButton::createMenuIcon(
const QColor &
color,
const bool showChecks )
420 QPixmap pixmap( iconSize, iconSize );
421 pixmap.fill( Qt::transparent );
430 p.setPen( Qt::NoPen );
431 p.setBrush( checkBrush );
432 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
436 p.setBrush( QBrush(
color ) );
439 p.setPen( QColor( 197, 197, 197 ) );
440 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
445 void QgsColorButton::buttonClicked()
458 void QgsColorButton::prepareMenu()
468 QAction *nullAction =
new QAction( tr(
"Clear Color" ),
this );
469 nullAction->setIcon( createMenuIcon( Qt::transparent,
false ) );
470 mMenu->addAction( nullAction );
475 if ( mDefaultColor.isValid() )
477 QAction *defaultColorAction =
new QAction( tr(
"Default Color" ),
this );
478 defaultColorAction->setIcon( createMenuIcon( mDefaultColor ) );
479 mMenu->addAction( defaultColorAction );
483 if ( mShowNoColorOption && mAllowOpacity )
485 QAction *noColorAction =
new QAction( mNoColorString,
this );
486 noColorAction->setIcon( createMenuIcon( Qt::transparent,
false ) );
487 mMenu->addAction( noColorAction );
491 mMenu->addSeparator();
497 mMenu->addAction( colorAction );
509 mMenu->addAction( alphaAction );
512 if ( mColorSchemeRegistry )
516 QList< QgsColorScheme * >::iterator it = schemeList.begin();
517 for ( ; it != schemeList.end(); ++it )
521 mMenu->addAction( colorAction );
527 mMenu->addSeparator();
529 QAction *copyColorAction =
new QAction( tr(
"Copy Color" ),
this );
530 mMenu->addAction( copyColorAction );
533 QAction *pasteColorAction =
new QAction( tr(
"Paste Color" ),
this );
537 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
539 pasteColorAction->setIcon( createMenuIcon( clipColor ) );
543 pasteColorAction->setEnabled(
false );
545 mMenu->addAction( pasteColorAction );
551 QAction *pickColorAction =
new QAction( tr(
"Pick Color" ),
this );
552 mMenu->addAction( pickColorAction );
555 QAction *chooseColorAction =
new QAction( tr(
"Choose Color…" ),
this );
556 mMenu->addAction( chooseColorAction );
557 connect( chooseColorAction, &QAction::triggered,
this, &QgsColorButton::showColorDialog );
562 if ( e->type() == QEvent::EnabledChange )
566 QToolButton::changeEvent( e );
569 #if 0 // causes too many cyclical updates, but may be needed on some platforms 570 void QgsColorButton::paintEvent( QPaintEvent *e )
572 QToolButton::paintEvent( e );
574 if ( !mBackgroundSet )
584 QToolButton::showEvent( e );
589 QToolButton::resizeEvent( event );
597 QColor oldColor = mColor;
601 if ( oldColor != mColor || ( mColor == QColor( Qt::black ) && !mColorSet ) )
614 void QgsColorButton::addRecentColor(
const QColor &
color )
621 QColor backgroundColor =
color;
623 if ( !color.isValid() )
625 backgroundColor = mColor;
628 QSize currentIconSize;
632 if ( !mIconSize.isValid() )
635 QStyleOptionToolButton opt;
636 initStyleOption( &opt );
637 QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
641 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
643 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
646 currentIconSize = mIconSize;
652 currentIconSize = QSize( width() - 10, height() - 6 );
654 currentIconSize = QSize( width() - 10, height() - 12 );
658 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
664 QPixmap pixmap( currentIconSize );
665 pixmap.fill( Qt::transparent );
667 if ( backgroundColor.isValid() )
669 QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
672 p.setRenderHint( QPainter::Antialiasing );
673 p.setPen( Qt::NoPen );
674 if ( mAllowOpacity && backgroundColor.alpha() < 255 )
678 p.setBrush( checkBrush );
679 p.drawRoundedRect( rect, 3, 3 );
683 p.setBrush( backgroundColor );
684 p.drawRoundedRect( rect, 3, 3 );
688 setIconSize( currentIconSize );
701 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
705 addRecentColor( clipColor );
713 mCurrentColor = mColor;
717 mPickingColor =
true;
718 setMouseTracking(
true );
728 mAllowOpacity = allow;
733 mColorDialogTitle = title;
738 return mColorDialogTitle;
743 setMenu( showMenu ? mMenu :
nullptr );
744 setPopupMode( showMenu ? QToolButton::MenuButtonPopup : QToolButton::DelayedPopup );
757 mDefaultColor =
color;
772 return !mColor.isValid();
A color swatch grid which can be embedded into a menu.
Registry of color schemes.
static const double UI_SCALE_FACTOR
UI scaling factor.
This class is a composition of two QSettings instances:
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
Show scheme in color button drop-down menu.
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color dialog.
static QPixmap getThemePixmap(const QString &name)
Helper to get a theme icon as a pixmap.
static QString encodeColor(const QColor &color)
void setTitle(const QString &title)
Sets the title for the color dialog.
void setColor(const QColor &color, bool emitSignals=false) override
static void addRecentColor(const QColor &color)
Adds a color to the list of recent colors.
QColor color() const
Returns the current color for the dialog.
A custom QGIS dialog for selecting a color.
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes. ...
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
QList< QgsColorScheme * > schemes() const
Returns all color schemes in the registry.
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
void setBaseColor(const QColor &baseColor)
Sets the base color for the color grid.