mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Now clicking color buttons inside the layer style panel causes the color picker dialog to be opened inside the style panel itself rather than as a separate dialog
733 lines
20 KiB
C++
733 lines
20 KiB
C++
/***************************************************************************
|
|
qgscolorbutton.cpp - Button which displays a color
|
|
--------------------------------------
|
|
Date : 12-Dec-2006
|
|
Copyright : (C) 2006 by Tom Elwertowski
|
|
Email : telwertowski at users dot sourceforge dot net
|
|
***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qgscolorbutton.h"
|
|
#include "qgscolordialog.h"
|
|
#include "qgsapplication.h"
|
|
#include "qgslogger.h"
|
|
#include "qgssymbollayerutils.h"
|
|
#include "qgscursors.h"
|
|
#include "qgscolorswatchgrid.h"
|
|
#include "qgscolorschemeregistry.h"
|
|
#include "qgscolorwidgets.h"
|
|
|
|
#include <QPainter>
|
|
#include <QSettings>
|
|
#include <QTemporaryFile>
|
|
#include <QMouseEvent>
|
|
#include <QMenu>
|
|
#include <QClipboard>
|
|
#include <QDrag>
|
|
#include <QDesktopWidget>
|
|
#include <QStyle>
|
|
#include <QStyleOptionToolButton>
|
|
#include <QWidgetAction>
|
|
#include <QLabel>
|
|
#include <QGridLayout>
|
|
#include <QPushButton>
|
|
|
|
QgsColorButton::QgsColorButton( QWidget *parent, const QString& cdt, QgsColorSchemeRegistry* registry )
|
|
: QToolButton( parent )
|
|
, mBehaviour( QgsColorButton::ShowDialog )
|
|
, mColorDialogTitle( cdt.isEmpty() ? tr( "Select Color" ) : cdt )
|
|
, mColor( QColor() )
|
|
, mDefaultColor( QColor() ) //default to invalid color
|
|
, mAllowAlpha( false )
|
|
, mAcceptLiveUpdates( true )
|
|
, mColorSet( false )
|
|
, mShowNoColorOption( false )
|
|
, mNoColorString( tr( "No color" ) )
|
|
, mShowNull( false )
|
|
, mPickingColor( false )
|
|
, mMenu( nullptr )
|
|
|
|
{
|
|
//if a color scheme registry was specified, use it, otherwise use the global instance
|
|
mColorSchemeRegistry = registry ? registry : QgsColorSchemeRegistry::instance();
|
|
|
|
setAcceptDrops( true );
|
|
setMinimumSize( QSize( 24, 16 ) );
|
|
connect( this, SIGNAL( clicked() ), this, SLOT( buttonClicked() ) );
|
|
|
|
//setup dropdown menu
|
|
mMenu = new QMenu( this );
|
|
connect( mMenu, SIGNAL( aboutToShow() ), this, SLOT( prepareMenu() ) );
|
|
setMenu( mMenu );
|
|
setPopupMode( QToolButton::MenuButtonPopup );
|
|
}
|
|
|
|
QgsColorButton::~QgsColorButton()
|
|
{
|
|
}
|
|
|
|
QSize QgsColorButton::sizeHint() const
|
|
{
|
|
//make sure height of button looks good under different platforms
|
|
#ifdef Q_OS_WIN
|
|
return QSize( 120, 22 );
|
|
#else
|
|
return QSize( 120, 28 );
|
|
#endif
|
|
}
|
|
|
|
const QPixmap& QgsColorButton::transparentBackground()
|
|
{
|
|
static QPixmap transpBkgrd;
|
|
|
|
if ( transpBkgrd.isNull() )
|
|
transpBkgrd = QgsApplication::getThemePixmap( "/transp-background_8x8.png" );
|
|
|
|
return transpBkgrd;
|
|
}
|
|
|
|
void QgsColorButton::showColorDialog()
|
|
{
|
|
if ( QgsPanelWidget* panel = QgsPanelWidget::findParentPanel( this ) )
|
|
{
|
|
QgsCompoundColorWidget* colorWidget = new QgsCompoundColorWidget( panel, color() );
|
|
colorWidget->setPanelTitle( mColorDialogTitle );
|
|
colorWidget->setAllowAlpha( mAllowAlpha );
|
|
connect( colorWidget, SIGNAL( currentColorChanged( QColor ) ), this, SLOT( setValidTemporaryColor( QColor ) ) );
|
|
connect( colorWidget, SIGNAL( panelAccepted( QgsPanelWidget* ) ), this, SLOT( panelAccepted( QgsPanelWidget* ) ) );
|
|
panel->openPanel( colorWidget );
|
|
return;
|
|
}
|
|
|
|
QColor newColor;
|
|
QSettings settings;
|
|
|
|
if ( mAcceptLiveUpdates && settings.value( "/qgis/live_color_dialogs", false ).toBool() )
|
|
{
|
|
// live updating dialog - QgsColorDialog will automatically use native dialog if option is set
|
|
newColor = QgsColorDialog::getLiveColor(
|
|
color(), this, SLOT( setValidColor( const QColor& ) ),
|
|
this, mColorDialogTitle, mAllowAlpha );
|
|
}
|
|
else
|
|
{
|
|
// not using live updating dialog - first check if we need to use the limited native dialogs
|
|
bool useNative = settings.value( "/qgis/native_color_dialogs", false ).toBool();
|
|
if ( useNative )
|
|
{
|
|
// why would anyone want this? who knows.... maybe the limited nature of native dialogs helps ease the transition for MapInfo users?
|
|
newColor = QColorDialog::getColor( color(), this, mColorDialogTitle, mAllowAlpha ? QColorDialog::ShowAlphaChannel : ( QColorDialog::ColorDialogOption )0 );
|
|
}
|
|
else
|
|
{
|
|
QgsColorDialog dialog( this, 0, color() );
|
|
dialog.setTitle( mColorDialogTitle );
|
|
dialog.setAllowAlpha( mAllowAlpha );
|
|
|
|
if ( dialog.exec() )
|
|
{
|
|
newColor = dialog.color();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( newColor.isValid() )
|
|
{
|
|
setValidColor( newColor );
|
|
addRecentColor( newColor );
|
|
}
|
|
|
|
// reactivate button's window
|
|
activateWindow();
|
|
}
|
|
|
|
void QgsColorButton::setToDefaultColor()
|
|
{
|
|
if ( !mDefaultColor.isValid() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
setColor( mDefaultColor );
|
|
}
|
|
|
|
void QgsColorButton::setToNull()
|
|
{
|
|
setColor( QColor() );
|
|
}
|
|
|
|
bool QgsColorButton::event( QEvent *e )
|
|
{
|
|
if ( e->type() == QEvent::ToolTip )
|
|
{
|
|
QString name = this->color().name();
|
|
int hue = this->color().hue();
|
|
int value = this->color().value();
|
|
int saturation = this->color().saturation();
|
|
QString info = QString( "HEX: %1 \n"
|
|
"RGB: %2 \n"
|
|
"HSV: %3,%4,%4" ).arg( name )
|
|
.arg( QgsSymbolLayerUtils::encodeColor( this->color() ) )
|
|
.arg( hue ).arg( value ).arg( saturation );
|
|
setToolTip( info );
|
|
}
|
|
return QToolButton::event( e );
|
|
}
|
|
|
|
void QgsColorButton::setToNoColor()
|
|
{
|
|
if ( mAllowAlpha )
|
|
{
|
|
QColor noColor = QColor( mColor );
|
|
noColor.setAlpha( 0 );
|
|
setColor( noColor );
|
|
}
|
|
}
|
|
|
|
void QgsColorButton::mousePressEvent( QMouseEvent *e )
|
|
{
|
|
if ( mPickingColor )
|
|
{
|
|
//don't show dialog if in color picker mode
|
|
e->accept();
|
|
return;
|
|
}
|
|
|
|
if ( e->button() == Qt::RightButton )
|
|
{
|
|
QToolButton::showMenu();
|
|
return;
|
|
}
|
|
else if ( e->button() == Qt::LeftButton )
|
|
{
|
|
mDragStartPosition = e->pos();
|
|
}
|
|
QToolButton::mousePressEvent( e );
|
|
}
|
|
|
|
bool QgsColorButton::colorFromMimeData( const QMimeData * mimeData, QColor& resultColor )
|
|
{
|
|
bool hasAlpha = false;
|
|
QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha );
|
|
|
|
if ( mimeColor.isValid() )
|
|
{
|
|
if ( !mAllowAlpha )
|
|
{
|
|
//remove alpha channel
|
|
mimeColor.setAlpha( 255 );
|
|
}
|
|
else if ( !hasAlpha )
|
|
{
|
|
//mime color has no explicit alpha component, so keep existing alpha
|
|
mimeColor.setAlpha( mColor.alpha() );
|
|
}
|
|
resultColor = mimeColor;
|
|
return true;
|
|
}
|
|
|
|
//could not get color from mime data
|
|
return false;
|
|
}
|
|
|
|
void QgsColorButton::mouseMoveEvent( QMouseEvent *e )
|
|
{
|
|
if ( mPickingColor )
|
|
{
|
|
//currently in color picker mode
|
|
if ( e->buttons() & Qt::LeftButton )
|
|
{
|
|
//if left button depressed, sample color under cursor and temporarily update button color
|
|
//to give feedback to user
|
|
QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), e->globalPos().x(), e->globalPos().y(), 1, 1 );
|
|
QImage snappedImage = snappedPixmap.toImage();
|
|
QColor hoverColor = snappedImage.pixel( 0, 0 );
|
|
setButtonBackground( hoverColor );
|
|
}
|
|
e->accept();
|
|
return;
|
|
}
|
|
|
|
//handle dragging colors from button
|
|
|
|
if ( !( e->buttons() & Qt::LeftButton ) || !mColor.isValid() )
|
|
{
|
|
//left button not depressed or no color set, so not a drag
|
|
QToolButton::mouseMoveEvent( e );
|
|
return;
|
|
}
|
|
|
|
if (( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
|
|
{
|
|
//mouse not moved, so not a drag
|
|
QToolButton::mouseMoveEvent( e );
|
|
return;
|
|
}
|
|
|
|
//user is dragging color
|
|
QDrag *drag = new QDrag( this );
|
|
drag->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mColor ) );
|
|
drag->setPixmap( QgsColorWidget::createDragIcon( mColor ) );
|
|
drag->exec( Qt::CopyAction );
|
|
setDown( false );
|
|
}
|
|
|
|
void QgsColorButton::mouseReleaseEvent( QMouseEvent *e )
|
|
{
|
|
if ( mPickingColor )
|
|
{
|
|
//end color picking operation by sampling the color under cursor
|
|
stopPicking( e->globalPos() );
|
|
e->accept();
|
|
return;
|
|
}
|
|
|
|
QToolButton::mouseReleaseEvent( e );
|
|
}
|
|
|
|
void QgsColorButton::stopPicking( QPointF eventPos, bool sampleColor )
|
|
{
|
|
//release mouse and keyboard, and reset cursor
|
|
releaseMouse();
|
|
releaseKeyboard();
|
|
unsetCursor();
|
|
mPickingColor = false;
|
|
|
|
if ( !sampleColor )
|
|
{
|
|
//not sampling color, nothing more to do
|
|
return;
|
|
}
|
|
|
|
//grab snapshot of pixel under mouse cursor
|
|
QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), eventPos.x(), eventPos.y(), 1, 1 );
|
|
QImage snappedImage = snappedPixmap.toImage();
|
|
//extract color from pixel and set color
|
|
setColor( snappedImage.pixel( 0, 0 ) );
|
|
addRecentColor( mColor );
|
|
}
|
|
|
|
void QgsColorButton::keyPressEvent( QKeyEvent *e )
|
|
{
|
|
if ( !mPickingColor )
|
|
{
|
|
//if not picking a color, use default tool button behaviour
|
|
QToolButton::keyPressEvent( e );
|
|
return;
|
|
}
|
|
|
|
//cancel picking, sampling the color if space was pressed
|
|
stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
|
|
}
|
|
|
|
void QgsColorButton::dragEnterEvent( QDragEnterEvent *e )
|
|
{
|
|
//is dragged data valid color data?
|
|
QColor mimeColor;
|
|
if ( colorFromMimeData( e->mimeData(), mimeColor ) )
|
|
{
|
|
//if so, we accept the drag, and temporarily change the button's color
|
|
//to match the dragged color. This gives immediate feedback to the user
|
|
//that colors can be dropped here
|
|
e->acceptProposedAction();
|
|
setButtonBackground( mimeColor );
|
|
}
|
|
}
|
|
|
|
void QgsColorButton::dragLeaveEvent( QDragLeaveEvent *e )
|
|
{
|
|
Q_UNUSED( e );
|
|
//reset button color
|
|
setButtonBackground( mColor );
|
|
}
|
|
|
|
void QgsColorButton::dropEvent( QDropEvent *e )
|
|
{
|
|
//is dropped data valid color data?
|
|
QColor mimeColor;
|
|
if ( colorFromMimeData( e->mimeData(), mimeColor ) )
|
|
{
|
|
//accept drop and set new color
|
|
e->acceptProposedAction();
|
|
setColor( mimeColor );
|
|
addRecentColor( mimeColor );
|
|
}
|
|
}
|
|
|
|
void QgsColorButton::setValidColor( const QColor& newColor )
|
|
{
|
|
if ( newColor.isValid() )
|
|
{
|
|
setColor( newColor );
|
|
addRecentColor( newColor );
|
|
}
|
|
}
|
|
|
|
void QgsColorButton::setValidTemporaryColor( const QColor& newColor )
|
|
{
|
|
if ( newColor.isValid() )
|
|
{
|
|
setColor( newColor );
|
|
}
|
|
}
|
|
|
|
void QgsColorButton::panelAccepted( QgsPanelWidget* widget )
|
|
{
|
|
if ( QgsCompoundColorWidget* colorWidget = qobject_cast< QgsCompoundColorWidget* >( widget ) )
|
|
{
|
|
addRecentColor( colorWidget->color() );
|
|
}
|
|
}
|
|
|
|
QPixmap QgsColorButton::createMenuIcon( const QColor &color, const bool showChecks )
|
|
{
|
|
//create an icon pixmap
|
|
QPixmap pixmap( 16, 16 );
|
|
pixmap.fill( Qt::transparent );
|
|
|
|
QPainter p;
|
|
p.begin( &pixmap );
|
|
|
|
//start with checkboard pattern
|
|
if ( showChecks )
|
|
{
|
|
QBrush checkBrush = QBrush( transparentBackground() );
|
|
p.setPen( Qt::NoPen );
|
|
p.setBrush( checkBrush );
|
|
p.drawRect( 0, 0, 15, 15 );
|
|
}
|
|
|
|
//draw color over pattern
|
|
p.setBrush( QBrush( color ) );
|
|
|
|
//draw border
|
|
p.setPen( QColor( 197, 197, 197 ) );
|
|
p.drawRect( 0, 0, 15, 15 );
|
|
p.end();
|
|
return pixmap;
|
|
}
|
|
|
|
void QgsColorButton::buttonClicked()
|
|
{
|
|
switch ( mBehaviour )
|
|
{
|
|
case ShowDialog:
|
|
showColorDialog();
|
|
return;
|
|
case SignalOnly:
|
|
emit colorClicked( mColor );
|
|
return;
|
|
}
|
|
}
|
|
|
|
void QgsColorButton::prepareMenu()
|
|
{
|
|
//we need to tear down and rebuild this menu every time it is shown. Otherwise the space allocated to any
|
|
//QgsColorSwatchGridAction is not recalculated by Qt and the swatch grid may not be the correct size
|
|
//for the number of colors shown in the grid. Note that we MUST refresh color swatch grids every time this
|
|
//menu is opened, otherwise color schemes like the recent color scheme grid are meaningless
|
|
mMenu->clear();
|
|
|
|
if ( mShowNull )
|
|
{
|
|
QAction* nullAction = new QAction( tr( "Clear color" ), this );
|
|
nullAction->setIcon( createMenuIcon( Qt::transparent, false ) );
|
|
mMenu->addAction( nullAction );
|
|
connect( nullAction, SIGNAL( triggered() ), this, SLOT( setToNull() ) );
|
|
}
|
|
|
|
//show default color option if set
|
|
if ( mDefaultColor.isValid() )
|
|
{
|
|
QAction* defaultColorAction = new QAction( tr( "Default color" ), this );
|
|
defaultColorAction->setIcon( createMenuIcon( mDefaultColor ) );
|
|
mMenu->addAction( defaultColorAction );
|
|
connect( defaultColorAction, SIGNAL( triggered() ), this, SLOT( setToDefaultColor() ) );
|
|
}
|
|
|
|
if ( mShowNoColorOption && mAllowAlpha )
|
|
{
|
|
QAction* noColorAction = new QAction( mNoColorString, this );
|
|
noColorAction->setIcon( createMenuIcon( Qt::transparent, false ) );
|
|
mMenu->addAction( noColorAction );
|
|
connect( noColorAction, SIGNAL( triggered() ), this, SLOT( setToNoColor() ) );
|
|
}
|
|
|
|
mMenu->addSeparator();
|
|
QgsColorWheel* colorWheel = new QgsColorWheel( mMenu );
|
|
colorWheel->setColor( color() );
|
|
QgsColorWidgetAction* colorAction = new QgsColorWidgetAction( colorWheel, mMenu, mMenu );
|
|
colorAction->setDismissOnColorSelection( false );
|
|
connect( colorAction, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setColor( const QColor& ) ) );
|
|
mMenu->addAction( colorAction );
|
|
|
|
|
|
if ( mColorSchemeRegistry )
|
|
{
|
|
//get schemes with ShowInColorButtonMenu flag set
|
|
QList< QgsColorScheme* > schemeList = mColorSchemeRegistry->schemes( QgsColorScheme::ShowInColorButtonMenu );
|
|
QList< QgsColorScheme* >::iterator it = schemeList.begin();
|
|
for ( ; it != schemeList.end(); ++it )
|
|
{
|
|
QgsColorSwatchGridAction* colorAction = new QgsColorSwatchGridAction( *it, mMenu, mContext, this );
|
|
colorAction->setBaseColor( mColor );
|
|
mMenu->addAction( colorAction );
|
|
connect( colorAction, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setValidColor( const QColor& ) ) );
|
|
connect( colorAction, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( addRecentColor( const QColor& ) ) );
|
|
}
|
|
}
|
|
|
|
mMenu->addSeparator();
|
|
|
|
QAction* copyColorAction = new QAction( tr( "Copy color" ), this );
|
|
mMenu->addAction( copyColorAction );
|
|
connect( copyColorAction, SIGNAL( triggered() ), this, SLOT( copyColor() ) );
|
|
|
|
QAction* pasteColorAction = new QAction( tr( "Paste color" ), this );
|
|
//enable or disable paste action based on current clipboard contents. We always show the paste
|
|
//action, even if it's disabled, to give hint to the user that pasting colors is possible
|
|
QColor clipColor;
|
|
if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
|
|
{
|
|
pasteColorAction->setIcon( createMenuIcon( clipColor ) );
|
|
}
|
|
else
|
|
{
|
|
pasteColorAction->setEnabled( false );
|
|
}
|
|
mMenu->addAction( pasteColorAction );
|
|
connect( pasteColorAction, SIGNAL( triggered() ), this, SLOT( pasteColor() ) );
|
|
|
|
#ifndef Q_OS_MAC
|
|
//disabled for OSX, as it is impossible to grab the mouse under OSX
|
|
//see note for QWidget::grabMouse() re OSX Cocoa
|
|
//http://qt-project.org/doc/qt-4.8/qwidget.html#grabMouse
|
|
QAction* pickColorAction = new QAction( tr( "Pick color" ), this );
|
|
mMenu->addAction( pickColorAction );
|
|
connect( pickColorAction, SIGNAL( triggered() ), this, SLOT( activatePicker() ) );
|
|
#endif
|
|
QAction* chooseColorAction = new QAction( tr( "Choose color..." ), this );
|
|
mMenu->addAction( chooseColorAction );
|
|
connect( chooseColorAction, SIGNAL( triggered() ), this, SLOT( showColorDialog() ) );
|
|
}
|
|
|
|
void QgsColorButton::changeEvent( QEvent* e )
|
|
{
|
|
if ( e->type() == QEvent::EnabledChange )
|
|
{
|
|
setButtonBackground();
|
|
}
|
|
QToolButton::changeEvent( e );
|
|
}
|
|
|
|
#if 0 // causes too many cyclical updates, but may be needed on some platforms
|
|
void QgsColorButton::paintEvent( QPaintEvent* e )
|
|
{
|
|
QToolButton::paintEvent( e );
|
|
|
|
if ( !mBackgroundSet )
|
|
{
|
|
setButtonBackground();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void QgsColorButton::showEvent( QShowEvent* e )
|
|
{
|
|
setButtonBackground();
|
|
QToolButton::showEvent( e );
|
|
}
|
|
|
|
void QgsColorButton::resizeEvent( QResizeEvent *event )
|
|
{
|
|
QToolButton::resizeEvent( event );
|
|
//recalculate icon size and redraw icon
|
|
mIconSize = QSize();
|
|
setButtonBackground( mColor );
|
|
}
|
|
|
|
void QgsColorButton::setColor( const QColor &color )
|
|
{
|
|
QColor oldColor = mColor;
|
|
mColor = color;
|
|
|
|
// handle when initially set color is same as default (Qt::black); consider it a color change
|
|
if ( oldColor != mColor || ( mColor == QColor( Qt::black ) && !mColorSet ) )
|
|
{
|
|
setButtonBackground();
|
|
if ( isEnabled() )
|
|
{
|
|
// TODO: May be beneficial to have the option to set color without emitting this signal.
|
|
// Now done by blockSignals( bool ) where button is used
|
|
emit colorChanged( mColor );
|
|
}
|
|
}
|
|
mColorSet = true;
|
|
}
|
|
|
|
void QgsColorButton::addRecentColor( const QColor& color )
|
|
{
|
|
QgsRecentColorScheme::addRecentColor( color );
|
|
}
|
|
|
|
void QgsColorButton::setButtonBackground( const QColor &color )
|
|
{
|
|
QColor backgroundColor = color;
|
|
|
|
if ( !color.isValid() )
|
|
{
|
|
backgroundColor = mColor;
|
|
}
|
|
|
|
QSize currentIconSize;
|
|
//icon size is button size with a small margin
|
|
if ( menu() )
|
|
{
|
|
if ( !mIconSize.isValid() )
|
|
{
|
|
//calculate size of push button part of widget (ie, without the menu dropdown button part)
|
|
QStyleOptionToolButton opt;
|
|
initStyleOption( &opt );
|
|
QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
|
|
this );
|
|
//make sure height of icon looks good under different platforms
|
|
#ifdef Q_OS_WIN
|
|
mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
|
|
#else
|
|
mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
|
|
#endif
|
|
}
|
|
currentIconSize = mIconSize;
|
|
}
|
|
else
|
|
{
|
|
//no menu
|
|
#ifdef Q_OS_WIN
|
|
currentIconSize = QSize( width() - 10, height() - 6 );
|
|
#else
|
|
currentIconSize = QSize( width() - 10, height() - 12 );
|
|
#endif
|
|
}
|
|
|
|
if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//create an icon pixmap
|
|
QPixmap pixmap( currentIconSize );
|
|
pixmap.fill( Qt::transparent );
|
|
|
|
if ( backgroundColor.isValid() )
|
|
{
|
|
QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
|
|
QPainter p;
|
|
p.begin( &pixmap );
|
|
p.setRenderHint( QPainter::Antialiasing );
|
|
p.setPen( Qt::NoPen );
|
|
if ( mAllowAlpha && backgroundColor.alpha() < 255 )
|
|
{
|
|
//start with checkboard pattern
|
|
QBrush checkBrush = QBrush( transparentBackground() );
|
|
p.setBrush( checkBrush );
|
|
p.drawRoundedRect( rect, 3, 3 );
|
|
}
|
|
|
|
//draw semi-transparent color on top
|
|
p.setBrush( backgroundColor );
|
|
p.drawRoundedRect( rect, 3, 3 );
|
|
p.end();
|
|
}
|
|
|
|
setIconSize( currentIconSize );
|
|
setIcon( pixmap );
|
|
}
|
|
|
|
void QgsColorButton::copyColor()
|
|
{
|
|
//copy color
|
|
QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mColor ) );
|
|
}
|
|
|
|
void QgsColorButton::pasteColor()
|
|
{
|
|
QColor clipColor;
|
|
if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
|
|
{
|
|
//paste color
|
|
setColor( clipColor );
|
|
addRecentColor( clipColor );
|
|
}
|
|
}
|
|
|
|
void QgsColorButton::activatePicker()
|
|
{
|
|
//pick color
|
|
QPixmap samplerPixmap = QPixmap(( const char ** ) sampler_cursor );
|
|
setCursor( QCursor( samplerPixmap, 0, 0 ) );
|
|
grabMouse();
|
|
grabKeyboard();
|
|
mPickingColor = true;
|
|
}
|
|
|
|
QColor QgsColorButton::color() const
|
|
{
|
|
return mColor;
|
|
}
|
|
|
|
void QgsColorButton::setAllowAlpha( const bool allowAlpha )
|
|
{
|
|
mAllowAlpha = allowAlpha;
|
|
}
|
|
|
|
void QgsColorButton::setColorDialogTitle( const QString& title )
|
|
{
|
|
mColorDialogTitle = title;
|
|
}
|
|
|
|
QString QgsColorButton::colorDialogTitle() const
|
|
{
|
|
return mColorDialogTitle;
|
|
}
|
|
|
|
void QgsColorButton::setShowMenu( const bool showMenu )
|
|
{
|
|
setMenu( showMenu ? mMenu : nullptr );
|
|
setPopupMode( showMenu ? QToolButton::MenuButtonPopup : QToolButton::DelayedPopup );
|
|
//force recalculation of icon size
|
|
mIconSize = QSize();
|
|
setButtonBackground( mColor );
|
|
}
|
|
|
|
void QgsColorButton::setBehaviour( const QgsColorButton::Behaviour behaviour )
|
|
{
|
|
mBehaviour = behaviour;
|
|
}
|
|
|
|
void QgsColorButton::setDefaultColor( const QColor& color )
|
|
{
|
|
mDefaultColor = color;
|
|
}
|
|
|
|
void QgsColorButton::setShowNull( bool showNull )
|
|
{
|
|
mShowNull = showNull;
|
|
}
|
|
|
|
bool QgsColorButton::showNull() const
|
|
{
|
|
return mShowNull;
|
|
}
|
|
|
|
bool QgsColorButton::isNull() const
|
|
{
|
|
return !mColor.isValid();
|
|
}
|
|
|