29 #include <QMouseEvent> 33 #include <QDesktopWidget> 35 #include <QStyleOptionToolButton> 36 #include <QWidgetAction> 39 #include <QGridLayout> 40 #include <QPushButton> 43 : QToolButton( parent )
44 , mColorDialogTitle( cdt.isEmpty() ? tr(
"Select Color" ) : cdt )
45 , mNoColorString( tr(
"No color" ) )
50 setAcceptDrops(
true );
51 setMinimumSize( QSize( 24, 16 ) );
52 connect(
this, &QAbstractButton::clicked,
this, &QgsColorButton::buttonClicked );
55 mMenu =
new QMenu(
this );
56 connect( mMenu, &QMenu::aboutToShow,
this, &QgsColorButton::prepareMenu );
58 setPopupMode( QToolButton::MenuButtonPopup );
61 mMinimumSize = QSize( 120, 22 );
63 mMinimumSize = QSize( 120, 28 );
66 mMinimumSize.setHeight( std::max( static_cast<int>(
Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.1 ), mMinimumSize.height() ) );
90 static QPixmap sTranspBkgrd;
92 if ( sTranspBkgrd.isNull() )
98 void QgsColorButton::showColorDialog()
103 QColor currentColor =
color();
108 if ( currentColor.isValid() )
122 bool useNative = settings.
value( QStringLiteral(
"qgis/native_color_dialogs" ),
false ).toBool();
126 newColor = QColorDialog::getColor(
color(),
this, mColorDialogTitle, mAllowOpacity ? QColorDialog::ShowAlphaChannel : ( QColorDialog::ColorDialogOption )0 );
131 dialog.
setTitle( mColorDialogTitle );
136 newColor = dialog.
color();
140 if ( newColor.isValid() )
142 setValidColor( newColor );
151 if ( !mDefaultColor.isValid() )
172 if ( e->type() == QEvent::ToolTip )
174 QColor
c = linkedProjectColor();
175 bool isProjectColor = c.isValid();
176 if ( !isProjectColor )
179 QString name = c.name();
181 int value = c.value();
182 int saturation = c.saturation();
186 int height =
static_cast< int >( width / 1.61803398875 );
188 int margin =
static_cast< int >( height * 0.1 );
189 QImage icon = QImage( width + 2 * margin, height + 2 * margin, QImage::Format_ARGB32 );
190 icon.fill( Qt::transparent );
197 p.setPen( Qt::NoPen );
198 p.setBrush( checkBrush );
199 p.drawRect( margin, margin, width, height );
202 p.setBrush( QBrush( c ) );
205 p.setPen( QColor( 197, 197, 197 ) );
206 p.drawRect( margin, margin, width, height );
210 QBuffer buffer( &data );
211 icon.save( &buffer,
"PNG", 100 );
213 QString info = ( isProjectColor ? QStringLiteral(
"<p>%1: %2</p>" ).arg( tr(
"Linked color" ), mLinkedColorName ) : QString() )
214 + QStringLiteral(
"<b>HEX</b> %1<br>" 216 "<b>HSV</b> %3,%4,%5<p>" 217 "<img src='data:image/png;base64, %0'>" ).arg( QString( data.toBase64() ), name,
219 .arg( hue ).arg( saturation ).arg( value );
222 return QToolButton::event( e );
229 QColor noColor = QColor( mColor );
230 noColor.setAlpha( 0 );
244 if ( e->button() == Qt::RightButton )
246 QToolButton::showMenu();
249 else if ( e->button() == Qt::LeftButton )
251 mDragStartPosition = e->pos();
253 QToolButton::mousePressEvent( e );
256 bool QgsColorButton::colorFromMimeData(
const QMimeData *mimeData, QColor &resultColor )
258 bool hasAlpha =
false;
261 if ( mimeColor.isValid() )
263 if ( !mAllowOpacity )
266 mimeColor.setAlpha( 255 );
268 else if ( !hasAlpha )
271 mimeColor.setAlpha( mColor.alpha() );
273 resultColor = mimeColor;
291 QColor
c = linkedProjectColor();
295 if ( !( e->buttons() & Qt::LeftButton ) || !c.isValid() )
298 QToolButton::mouseMoveEvent( e );
302 if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
305 QToolButton::mouseMoveEvent( e );
310 QDrag *drag =
new QDrag(
this );
313 drag->exec( Qt::CopyAction );
322 stopPicking( e->globalPos() );
327 QToolButton::mouseReleaseEvent( e );
330 void QgsColorButton::stopPicking( QPoint eventPos,
bool samplingColor )
335 QgsApplication::restoreOverrideCursor();
336 setMouseTracking(
false );
337 mPickingColor =
false;
339 if ( !samplingColor )
346 setColor( sampleColor( eventPos ) );
347 addRecentColor( mColor );
350 QColor QgsColorButton::linkedProjectColor()
const 352 QList<QgsProjectColorScheme *> projectSchemes;
354 if ( projectSchemes.length() > 0 )
358 for (
const auto &
color : colors )
360 if (
color.second.isEmpty() )
363 if (
color.second == mLinkedColorName )
374 if ( !mPickingColor )
377 QToolButton::keyPressEvent( e );
382 stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
387 const bool isProjectColor = linkedProjectColor().isValid();
388 if ( isProjectColor )
393 if ( colorFromMimeData( e->mimeData(), mimeColor ) )
398 e->acceptProposedAction();
412 const bool isProjectColor = linkedProjectColor().isValid();
413 if ( isProjectColor )
418 if ( colorFromMimeData( e->mimeData(), mimeColor ) )
421 e->acceptProposedAction();
423 addRecentColor( mimeColor );
427 QColor QgsColorButton::sampleColor( QPoint point )
const 429 QScreen *screen = findScreenAt( point );
434 QPixmap snappedPixmap = screen->grabWindow( QApplication::desktop()->winId(), point.x(), point.y(), 1, 1 );
435 QImage snappedImage = snappedPixmap.toImage();
436 return snappedImage.pixel( 0, 0 );
439 QScreen *QgsColorButton::findScreenAt( QPoint pos )
441 for ( QScreen *screen : QGuiApplication::screens() )
443 if ( screen->geometry().contains( pos ) )
451 void QgsColorButton::setValidColor(
const QColor &newColor )
453 if ( newColor.isValid() )
456 addRecentColor( newColor );
460 void QgsColorButton::setValidTemporaryColor(
const QColor &newColor )
462 if ( newColor.isValid() )
473 QPixmap pixmap( iconSize, iconSize );
474 pixmap.fill( Qt::transparent );
483 p.setPen( Qt::NoPen );
484 p.setBrush( checkBrush );
485 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
489 p.setBrush( QBrush( color ) );
492 p.setPen( QColor( 197, 197, 197 ) );
493 p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
498 void QgsColorButton::buttonClicked()
500 if ( linkedProjectColor().isValid() )
502 QToolButton::showMenu();
518 void QgsColorButton::prepareMenu()
526 const bool isProjectColor = linkedProjectColor().isValid();
528 if ( !isProjectColor )
532 QAction *nullAction =
new QAction( tr(
"Clear Color" ),
this );
534 mMenu->addAction( nullAction );
539 if ( mDefaultColor.isValid() )
541 QAction *defaultColorAction =
new QAction( tr(
"Default Color" ),
this );
543 mMenu->addAction( defaultColorAction );
547 if ( mShowNoColorOption && mAllowOpacity )
549 QAction *noColorAction =
new QAction( mNoColorString,
this );
550 noColorAction->setIcon(
createMenuIcon( Qt::transparent,
false ) );
551 mMenu->addAction( noColorAction );
555 mMenu->addSeparator();
561 mMenu->addAction( colorAction );
573 mMenu->addAction( alphaAction );
576 if ( mColorSchemeRegistry )
580 QList< QgsColorScheme * >::iterator it = schemeList.begin();
581 for ( ; it != schemeList.end(); ++it )
585 mMenu->addAction( colorAction );
591 mMenu->addSeparator();
594 if ( isProjectColor )
596 QAction *unlinkAction =
new QAction( tr(
"Unlink Color" ), mMenu );
597 mMenu->addAction( unlinkAction );
601 QAction *copyColorAction =
new QAction( tr(
"Copy Color" ),
this );
602 mMenu->addAction( copyColorAction );
605 if ( !isProjectColor )
607 QAction *pasteColorAction =
new QAction( tr(
"Paste Color" ),
this );
611 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
617 pasteColorAction->setEnabled(
false );
619 mMenu->addAction( pasteColorAction );
622 QAction *pickColorAction =
new QAction( tr(
"Pick Color" ),
this );
623 mMenu->addAction( pickColorAction );
626 QAction *chooseColorAction =
new QAction( tr(
"Choose Color…" ),
this );
627 mMenu->addAction( chooseColorAction );
628 connect( chooseColorAction, &QAction::triggered,
this, &QgsColorButton::showColorDialog );
634 if ( e->type() == QEvent::EnabledChange )
638 QToolButton::changeEvent( e );
641 #if 0 // causes too many cyclical updates, but may be needed on some platforms 642 void QgsColorButton::paintEvent( QPaintEvent *e )
644 QToolButton::paintEvent( e );
646 if ( !mBackgroundSet )
656 QToolButton::showEvent( e );
661 QToolButton::resizeEvent( event );
669 QColor oldColor = mColor;
673 if ( oldColor != mColor || ( mColor == QColor( Qt::black ) && !mColorSet ) )
686 void QgsColorButton::addRecentColor(
const QColor &
color )
693 QColor backgroundColor =
color;
694 bool isProjectColor =
false;
695 if ( !backgroundColor.isValid() && !mLinkedColorName.isEmpty() )
697 backgroundColor = linkedProjectColor();
698 isProjectColor = backgroundColor.isValid();
699 if ( !isProjectColor )
701 mLinkedColorName.clear();
705 if ( !backgroundColor.isValid() )
707 backgroundColor = mColor;
710 QSize currentIconSize;
714 if ( !mIconSize.isValid() )
717 QStyleOptionToolButton opt;
718 initStyleOption( &opt );
719 QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
723 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
725 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
728 currentIconSize = mIconSize;
734 currentIconSize = QSize( width() - 10, height() - 6 );
736 currentIconSize = QSize( width() - 10, height() - 12 );
740 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
746 QPixmap pixmap( currentIconSize );
747 pixmap.fill( Qt::transparent );
749 if ( backgroundColor.isValid() )
751 QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
754 p.setRenderHint( QPainter::Antialiasing );
755 p.setPen( Qt::NoPen );
756 if ( mAllowOpacity && backgroundColor.alpha() < 255 )
760 p.setBrush( checkBrush );
761 p.drawRoundedRect( rect, 3, 3 );
765 p.setBrush( backgroundColor );
766 p.drawRoundedRect( rect, 3, 3 );
770 setIconSize( currentIconSize );
777 QColor
c = linkedProjectColor();
786 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
790 addRecentColor( clipColor );
798 mCurrentColor = mColor;
802 mPickingColor =
true;
803 setMouseTracking(
true );
808 QColor
c = linkedProjectColor();
816 mAllowOpacity = allow;
821 mColorDialogTitle = title;
826 return mColorDialogTitle;
832 setMenu( showMenu ? mMenu :
nullptr );
833 setPopupMode( showMenu ? QToolButton::MenuButtonPopup : QToolButton::DelayedPopup );
846 mDefaultColor =
color;
861 return !mColor.isValid();
866 mLinkedColorName = name;
A color swatch grid which can be embedded into a menu.
A color scheme which contains project specific colors set through project properties dialog...
Registry of color schemes.
static const double UI_SCALE_FACTOR
UI scaling factor.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly...
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
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)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QList< QgsColorScheme * > schemes() const
Returns all color schemes in the registry.
void setTitle(const QString &title)
Sets the title for the color dialog.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
void setColor(const QColor &color, bool emitSignals=false) override
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
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 QgsProject * instance()
Returns the QgsProject singleton instance.
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor()) override
Gets a list of colors from the scheme.
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.