mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-19 00:02:48 -04:00
[FEATURE] Allow dragging and dropping colors from color buttons (also works with some other applications, eg dropping colors from GIMP or Gpick). Tweak color button context menu to remove extra options.
This commit is contained in:
parent
d6889a4e4c
commit
d83ef3fe3a
@ -116,4 +116,19 @@ class QgsColorButton: QPushButton
|
||||
* Reimplemented to detect right mouse button clicks on the color button.
|
||||
*/
|
||||
void mousePressEvent( QMouseEvent* e );
|
||||
|
||||
/**
|
||||
* Reimplemented to allow dragging colors from button
|
||||
*/
|
||||
void mouseMoveEvent( QMouseEvent *e );
|
||||
|
||||
/**
|
||||
* Reimplemented to accept dragged colors
|
||||
*/
|
||||
void dragEnterEvent( QDragEnterEvent * e ) ;
|
||||
|
||||
/**
|
||||
* Reimplemented to accept dropped colors
|
||||
*/
|
||||
void dropEvent( QDropEvent *e );
|
||||
};
|
||||
|
@ -51,6 +51,7 @@ QgsColorButton::QgsColorButton( QWidget *parent, QString cdt, QColorDialog::Colo
|
||||
, mTempPNG( NULL )
|
||||
, mColorSet( false )
|
||||
{
|
||||
setAcceptDrops( true );
|
||||
connect( this, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
|
||||
}
|
||||
|
||||
@ -96,10 +97,116 @@ void QgsColorButton::mousePressEvent( QMouseEvent *e )
|
||||
if ( e->button() == Qt::RightButton )
|
||||
{
|
||||
showContextMenu( e );
|
||||
return;
|
||||
}
|
||||
else
|
||||
else if ( e->button() == Qt::LeftButton )
|
||||
{
|
||||
QPushButton::mousePressEvent( e );
|
||||
mDragStartPosition = e->pos();
|
||||
}
|
||||
QPushButton::mousePressEvent( e );
|
||||
}
|
||||
|
||||
QMimeData * QgsColorButton::createColorMimeData() const
|
||||
{
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setColorData( QVariant( mColor ) );
|
||||
mimeData->setText( mColor.name() );
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
bool QgsColorButton::colorFromMimeData( const QMimeData * mimeData, QColor& resultColor )
|
||||
{
|
||||
//attempt to read color data directly from mime
|
||||
QColor mimeColor = qVariantValue<QColor>( mimeData->colorData() );
|
||||
if ( mimeColor.isValid() )
|
||||
{
|
||||
if ( !( mColorDialogOptions & QColorDialog::ShowAlphaChannel ) )
|
||||
{
|
||||
//remove alpha channel
|
||||
mimeColor.setAlpha( 255 );
|
||||
}
|
||||
resultColor = mimeColor;
|
||||
return true;
|
||||
}
|
||||
|
||||
//attempt to intrepret a color from mime text data
|
||||
bool hasAlpha = false;
|
||||
QColor textColor = QgsSymbolLayerV2Utils::parseColorWithAlpha( mimeData->text(), hasAlpha );
|
||||
if ( textColor.isValid() )
|
||||
{
|
||||
if ( !( mColorDialogOptions & QColorDialog::ShowAlphaChannel ) )
|
||||
{
|
||||
//remove alpha channel
|
||||
textColor.setAlpha( 255 );
|
||||
}
|
||||
else if ( !hasAlpha )
|
||||
{
|
||||
//mime color has no explicit alpha component, so keep existing alpha
|
||||
textColor.setAlpha( mColor.alpha() );
|
||||
}
|
||||
resultColor = textColor;
|
||||
return true;
|
||||
}
|
||||
|
||||
//could not get color from mime data
|
||||
return false;
|
||||
}
|
||||
|
||||
void QgsColorButton::mouseMoveEvent( QMouseEvent *e )
|
||||
{
|
||||
if ( !( e->buttons() & Qt::LeftButton ) )
|
||||
{
|
||||
QPushButton::mouseMoveEvent( e );
|
||||
return;
|
||||
}
|
||||
|
||||
if (( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
|
||||
{
|
||||
QPushButton::mouseMoveEvent( e );
|
||||
return;
|
||||
}
|
||||
|
||||
QDrag *drag = new QDrag( this );
|
||||
drag->setMimeData( createColorMimeData() );
|
||||
|
||||
//craft a pixmap for the drag icon
|
||||
QImage colorImage( 50, 50, QImage::Format_RGB32 );
|
||||
QPainter imagePainter;
|
||||
imagePainter.begin( &colorImage );
|
||||
//start with a light gray background
|
||||
imagePainter.fillRect( QRect( 0, 0, 50, 50 ), QBrush( QColor( 200, 200, 200 ) ) );
|
||||
//draw rect with white border, filled with current color
|
||||
QColor pixmapColor = mColor;
|
||||
pixmapColor.setAlpha( 255 );
|
||||
imagePainter.setBrush( QBrush( pixmapColor ) );
|
||||
imagePainter.setPen( QPen( Qt::white ) );
|
||||
imagePainter.drawRect( QRect( 1, 1, 47, 47 ) );
|
||||
imagePainter.end();
|
||||
//set as drag pixmap
|
||||
drag->setPixmap( QPixmap::fromImage( colorImage ) );
|
||||
|
||||
Qt::DropAction dropAction = drag->exec( Qt::CopyAction | Qt::MoveAction );
|
||||
setDown( false );
|
||||
}
|
||||
|
||||
void QgsColorButton::dragEnterEvent( QDragEnterEvent *e )
|
||||
{
|
||||
//is dragged data valid color data?
|
||||
QColor mimeColor;
|
||||
if ( colorFromMimeData( e->mimeData(), mimeColor ) )
|
||||
{
|
||||
e->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsColorButton::dropEvent( QDropEvent *e )
|
||||
{
|
||||
//is dropped data valid color data?
|
||||
QColor mimeColor;
|
||||
if ( colorFromMimeData( e->mimeData(), mimeColor ) )
|
||||
{
|
||||
e->acceptProposedAction();
|
||||
setColor( mimeColor );
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,57 +214,24 @@ void QgsColorButton::showContextMenu( QMouseEvent *event )
|
||||
{
|
||||
QMenu colorContextMenu;
|
||||
|
||||
QAction* copyAsHexAction = new QAction( tr( "Copy color" ), 0 );
|
||||
colorContextMenu.addAction( copyAsHexAction );
|
||||
QAction* copyAsRgbAction = new QAction( tr( "Copy as rgb" ), 0 );
|
||||
colorContextMenu.addAction( copyAsRgbAction );
|
||||
QAction* copyAsRgbaAction = new QAction( tr( "Copy as rgba" ), 0 );
|
||||
if ( mColorDialogOptions & QColorDialog::ShowAlphaChannel )
|
||||
{
|
||||
//alpha enabled, so add rgba action
|
||||
colorContextMenu.addAction( copyAsRgbaAction );
|
||||
}
|
||||
|
||||
QString clipboardText = QApplication::clipboard()->text();
|
||||
QAction* copyColorAction = new QAction( tr( "Copy color" ), 0 );
|
||||
colorContextMenu.addAction( copyColorAction );
|
||||
QAction* pasteColorAction = new QAction( tr( "Paste color" ), 0 );
|
||||
pasteColorAction->setEnabled( false );
|
||||
colorContextMenu.addSeparator();
|
||||
colorContextMenu.addAction( pasteColorAction );
|
||||
QColor clipColor;
|
||||
if ( !( clipboardText.isEmpty() ) )
|
||||
{
|
||||
bool hasAlpha = false;
|
||||
clipColor = QgsSymbolLayerV2Utils::parseColorWithAlpha( clipboardText, hasAlpha );
|
||||
|
||||
if ( clipColor.isValid() )
|
||||
{
|
||||
if ( !hasAlpha )
|
||||
{
|
||||
//clipboard color has no explicit alpha component, so keep existing alpha
|
||||
clipColor.setAlpha( mColor.alpha() );
|
||||
}
|
||||
pasteColorAction->setEnabled( true );
|
||||
}
|
||||
QColor clipColor;
|
||||
if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor ) )
|
||||
{
|
||||
pasteColorAction->setEnabled( true );
|
||||
}
|
||||
|
||||
QAction* selectedAction = colorContextMenu.exec( event->globalPos( ) );
|
||||
if ( selectedAction == copyAsHexAction )
|
||||
if ( selectedAction == copyColorAction )
|
||||
{
|
||||
//copy color as hex code
|
||||
QString colorString = mColor.name();
|
||||
QApplication::clipboard()->setText( colorString );
|
||||
}
|
||||
else if ( selectedAction == copyAsRgbAction )
|
||||
{
|
||||
//copy color as rgb
|
||||
QString colorString = QString( "rgb(%1,%2,%3)" ).arg( mColor.red() ). arg( mColor.green() ).arg( mColor.blue() );
|
||||
QApplication::clipboard()->setText( colorString );
|
||||
}
|
||||
else if ( selectedAction == copyAsRgbaAction )
|
||||
{
|
||||
//copy color as rgba
|
||||
QString colorString = QString( "rgba(%1,%2,%3,%4)" ).arg( mColor.red() ).arg( mColor.green() ).arg( mColor.blue() ).arg( QString::number( mColor.alphaF(), 'f', 2 ) );
|
||||
QApplication::clipboard()->setText( colorString );
|
||||
//copy color
|
||||
QApplication::clipboard()->setMimeData( createColorMimeData() );
|
||||
}
|
||||
else if ( selectedAction == pasteColorAction )
|
||||
{
|
||||
@ -165,9 +239,7 @@ void QgsColorButton::showContextMenu( QMouseEvent *event )
|
||||
setColor( clipColor );
|
||||
}
|
||||
|
||||
delete copyAsHexAction;
|
||||
delete copyAsRgbAction;
|
||||
delete copyAsRgbaAction;
|
||||
delete copyColorAction;
|
||||
delete pasteColorAction;
|
||||
}
|
||||
|
||||
|
40
src/gui/qgscolorbutton.h
Executable file → Normal file
40
src/gui/qgscolorbutton.h
Executable file → Normal file
@ -19,6 +19,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
class QMimeData;
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsColorButton
|
||||
@ -110,6 +111,7 @@ class GUI_EXPORT QgsColorButton: public QPushButton
|
||||
*/
|
||||
void setAcceptLiveUpdates( bool accept ) { mAcceptLiveUpdates = accept; }
|
||||
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Sets the background pixmap for the button based upon set color and transparency.
|
||||
@ -140,10 +142,25 @@ class GUI_EXPORT QgsColorButton: public QPushButton
|
||||
static const QPixmap& transpBkgrd();
|
||||
|
||||
/**
|
||||
* Reimplemented to detect right mouse button clicks on the color button.
|
||||
* Reimplemented to detect right mouse button clicks on the color button and allow dragging colors
|
||||
*/
|
||||
void mousePressEvent( QMouseEvent* e );
|
||||
|
||||
/**
|
||||
* Reimplemented to allow dragging colors from button
|
||||
*/
|
||||
void mouseMoveEvent( QMouseEvent *e );
|
||||
|
||||
/**
|
||||
* Reimplemented to accept dragged colors
|
||||
*/
|
||||
void dragEnterEvent( QDragEnterEvent * e ) ;
|
||||
|
||||
/**
|
||||
* Reimplemented to accept dropped colors
|
||||
*/
|
||||
void dropEvent( QDropEvent *e );
|
||||
|
||||
private:
|
||||
QString mColorDialogTitle;
|
||||
QColor mColor;
|
||||
@ -152,11 +169,32 @@ class GUI_EXPORT QgsColorButton: public QPushButton
|
||||
QTemporaryFile mTempPNG;
|
||||
bool mColorSet; // added in QGIS 2.1
|
||||
|
||||
QPoint mDragStartPosition;
|
||||
|
||||
/**
|
||||
* Shows the color button context menu and handles copying and pasting color values.
|
||||
*/
|
||||
void showContextMenu( QMouseEvent* event );
|
||||
|
||||
/**
|
||||
* Creates mime data from the current color. Sets both the mime data's color data, and the
|
||||
* mime data's text with the color's hex code.
|
||||
* @note added in 2.3
|
||||
* @see colorFromMimeData
|
||||
*/
|
||||
QMimeData* createColorMimeData() const;
|
||||
|
||||
/**
|
||||
* Attempts to parse mimeData as a color, either via the mime data's color data or by
|
||||
* parsing a textual representation of a color.
|
||||
* @returns true if mime data could be intrepreted as a color
|
||||
* @param mimeData mime data
|
||||
* @param resultColor QColor to store evaluated color
|
||||
* @note added in 2.3
|
||||
* @see createColorMimeData
|
||||
*/
|
||||
bool colorFromMimeData( const QMimeData *mimeData, QColor &resultColor );
|
||||
|
||||
private slots:
|
||||
void onButtonClicked();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user