Add QgsColorWidgetAction for easily inserting QgsColorWidgets in menus

This commit is contained in:
Nyall Dawson 2015-12-09 16:07:22 +11:00
parent a5d670233b
commit 2377688c6c
3 changed files with 233 additions and 4 deletions

View File

@ -94,6 +94,11 @@ class QgsColorWidget : QWidget
*/
void colorChanged( const QColor &color );
/** Emitted when mouse hovers over widget.
* @note added in QGIS 2.14
*/
void hovered();
protected:
/** Returns the range of valid values for the color widget's component
@ -138,6 +143,63 @@ class QgsColorWidget : QWidget
//Reimplemented to accept dropped colors
void dropEvent( QDropEvent *e );
void mouseMoveEvent( QMouseEvent* e );
void mousePressEvent( QMouseEvent* e );
void mouseReleaseEvent( QMouseEvent* e );
};
/** \ingroup gui
* \class QgsColorWidgetAction
* An action containing a color widget, which can be embedded into a menu.
* @see QgsColorWidget
* @note introduced in QGIS 2.14
*/
class QgsColorWidgetAction: QWidgetAction
{
%TypeHeaderCode
#include <qgscolorwidgets.h>
%End
public:
/** Construct a new color widget action.
* @param colorWidget QgsColorWidget to show in action
* @param menu parent menu
* @param parent parent widget
*/
QgsColorWidgetAction( QgsColorWidget* colorWidget, QMenu* menu = 0, QWidget *parent /TransferThis/ = 0 );
virtual ~QgsColorWidgetAction();
/** Returns the color widget contained in the widget action.
*/
QgsColorWidget* colorWidget();
/** Sets whether the parent menu should be dismissed and closed when a color is selected
* from the action's color widget.
* @param dismiss set to true (default) to immediately close the menu when a color is selected
* from the widget. If set to false, the colorChanged signal will be emitted but the menu will
* stay open.
* @see dismissOnColorSelection()
*/
void setDismissOnColorSelection( bool dismiss );
/** Returns whether the parent menu will be dismissed after a color is selected from the
* action's color widget.
* @see setDismissOnColorSelection
*/
bool dismissOnColorSelection() const;
signals:
/** Emitted when a color has been selected from the widget
* @param color selected color
*/
void colorChanged( const QColor &color );
};
@ -163,6 +225,7 @@ class QgsColorWheel : QgsColorWidget
virtual ~QgsColorWheel();
virtual QSize sizeHint() const;
void paintEvent( QPaintEvent* event );
public slots:
@ -394,6 +457,7 @@ class QgsColorPreviewWidget : QgsColorWidget
virtual ~QgsColorPreviewWidget();
virtual QSize sizeHint() const;
void paintEvent( QPaintEvent* event );
/** Returns the secondary color for the widget

View File

@ -28,6 +28,7 @@
#include <QSettings>
#include <QDrag>
#include <cmath>
#include "qgslogger.h"
//
@ -221,6 +222,25 @@ void QgsColorWidget::dropEvent( QDropEvent *e )
//could not get color from mime data
}
void QgsColorWidget::mouseMoveEvent( QMouseEvent *e )
{
emit hovered();
e->accept();
//don't pass to QWidget::mouseMoveEvent, causes issues with widget used in QWidgetAction
}
void QgsColorWidget::mousePressEvent( QMouseEvent *e )
{
e->accept();
//don't pass to QWidget::mousePressEvent, causes issues with widget used in QWidgetAction
}
void QgsColorWidget::mouseReleaseEvent( QMouseEvent *e )
{
e->accept();
//don't pass to QWidget::mouseReleaseEvent, causes issues with widget used in QWidgetAction
}
QColor QgsColorWidget::color() const
{
return mCurrentColor;
@ -378,6 +398,11 @@ QgsColorWheel::~QgsColorWheel()
delete mWidgetImage;
}
QSize QgsColorWheel::sizeHint() const
{
return QSize( 200, 200 );
}
void QgsColorWheel::paintEvent( QPaintEvent *event )
{
Q_UNUSED( event );
@ -585,6 +610,7 @@ void QgsColorWheel::setColorFromPos( const QPointF pos )
void QgsColorWheel::mouseMoveEvent( QMouseEvent *event )
{
setColorFromPos( event->posF() );
QgsColorWidget::mouseMoveEvent( event );
}
void QgsColorWheel::mousePressEvent( QMouseEvent *event )
@ -828,6 +854,7 @@ void QgsColorBox::resizeEvent( QResizeEvent *event )
void QgsColorBox::mouseMoveEvent( QMouseEvent *event )
{
setColorFromPoint( event->pos() );
QgsColorWidget::mouseMoveEvent( event );
}
void QgsColorBox::mousePressEvent( QMouseEvent *event )
@ -1148,6 +1175,7 @@ void QgsColorRampWidget::setMarkerSize( const int markerSize )
void QgsColorRampWidget::mouseMoveEvent( QMouseEvent *event )
{
setColorFromPoint( event->posF() );
QgsColorWidget::mouseMoveEvent( event );
}
void QgsColorRampWidget::mousePressEvent( QMouseEvent *event )
@ -1571,6 +1599,11 @@ void QgsColorPreviewWidget::paintEvent( QPaintEvent *event )
painter.end();
}
QSize QgsColorPreviewWidget::sizeHint() const
{
return QSize( 200, 150 );
}
void QgsColorPreviewWidget::setColor2( const QColor &color )
{
if ( color == mColor2 )
@ -1587,7 +1620,7 @@ void QgsColorPreviewWidget::mousePressEvent( QMouseEvent *e )
{
mDragStartPosition = e->pos();
}
QWidget::mousePressEvent( e );
QgsColorWidget::mousePressEvent( e );
}
void QgsColorPreviewWidget::mouseReleaseEvent( QMouseEvent *e )
@ -1595,7 +1628,7 @@ void QgsColorPreviewWidget::mouseReleaseEvent( QMouseEvent *e )
if (( e->pos() - mDragStartPosition ).manhattanLength() >= QApplication::startDragDistance() )
{
//mouse moved, so a drag. nothing to do here
QWidget::mouseReleaseEvent( e );
QgsColorWidget::mouseReleaseEvent( e );
return;
}
@ -1621,14 +1654,14 @@ void QgsColorPreviewWidget::mouseMoveEvent( QMouseEvent *e )
if ( !( e->buttons() & Qt::LeftButton ) )
{
//left button not depressed, so not a drag
QWidget::mouseMoveEvent( e );
QgsColorWidget::mouseMoveEvent( e );
return;
}
if (( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
{
//mouse not moved, so not a drag
QWidget::mouseMoveEvent( e );
QgsColorWidget::mouseMoveEvent( e );
return;
}
@ -1651,3 +1684,53 @@ void QgsColorPreviewWidget::mouseMoveEvent( QMouseEvent *e )
drag->setPixmap( createDragIcon( dragColor ) );
drag->exec( Qt::CopyAction );
}
//
// QgsColorWidgetAction
//
QgsColorWidgetAction::QgsColorWidgetAction( QgsColorWidget* colorWidget, QMenu* menu, QWidget* parent )
: QWidgetAction( parent )
, mMenu( menu )
, mColorWidget( colorWidget )
, mSuppressRecurse( false )
, mDismissOnColorSelection( true )
{
setDefaultWidget( mColorWidget );
connect( mColorWidget, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( this, SIGNAL( hovered() ), this, SLOT( onHover() ) );
connect( mColorWidget, SIGNAL( hovered() ), this, SLOT( onHover() ) );
}
QgsColorWidgetAction::~QgsColorWidgetAction()
{
}
void QgsColorWidgetAction::onHover()
{
//see https://bugreports.qt-project.org/browse/QTBUG-10427?focusedCommentId=185610&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-185610
if ( mSuppressRecurse )
{
return;
}
if ( mMenu )
{
mSuppressRecurse = true;
mMenu->setActiveAction( this );
mSuppressRecurse = false;
}
}
void QgsColorWidgetAction::setColor( const QColor& color )
{
emit colorChanged( color );
QAction::trigger();
if ( mMenu && mDismissOnColorSelection )
{
mMenu->hide();
}
}

View File

@ -16,6 +16,7 @@
#ifndef QGSCOLORWIDGETS_H
#define QGSCOLORWIDGETS_H
#include <QWidgetAction>
#include <QWidget>
class QColor;
@ -117,6 +118,11 @@ class GUI_EXPORT QgsColorWidget : public QWidget
*/
void colorChanged( const QColor &color );
/** Emitted when mouse hovers over widget.
* @note added in QGIS 2.14
*/
void hovered();
protected:
QColor mCurrentColor;
@ -170,9 +176,83 @@ class GUI_EXPORT QgsColorWidget : public QWidget
//Reimplemented to accept dropped colors
void dropEvent( QDropEvent *e ) override;
void mouseMoveEvent( QMouseEvent* e ) override;
void mousePressEvent( QMouseEvent* e ) override;
void mouseReleaseEvent( QMouseEvent* e ) override;
};
/** \ingroup gui
* \class QgsColorWidgetAction
* An action containing a color widget, which can be embedded into a menu.
* @see QgsColorWidget
* @note introduced in QGIS 2.14
*/
class GUI_EXPORT QgsColorWidgetAction: public QWidgetAction
{
Q_OBJECT
public:
/** Construct a new color widget action.
* @param colorWidget QgsColorWidget to show in action
* @param menu parent menu
* @param parent parent widget
*/
QgsColorWidgetAction( QgsColorWidget* colorWidget, QMenu* menu = 0, QWidget *parent = 0 );
virtual ~QgsColorWidgetAction();
/** Returns the color widget contained in the widget action.
*/
QgsColorWidget* colorWidget() { return mColorWidget; }
/** Sets whether the parent menu should be dismissed and closed when a color is selected
* from the action's color widget.
* @param dismiss set to true (default) to immediately close the menu when a color is selected
* from the widget. If set to false, the colorChanged signal will be emitted but the menu will
* stay open.
* @see dismissOnColorSelection()
*/
void setDismissOnColorSelection( bool dismiss ) { mDismissOnColorSelection = dismiss; }
/** Returns whether the parent menu will be dismissed after a color is selected from the
* action's color widget.
* @see setDismissOnColorSelection
*/
bool dismissOnColorSelection() const { return mDismissOnColorSelection; }
signals:
/** Emitted when a color has been selected from the widget
* @param color selected color
*/
void colorChanged( const QColor &color );
private:
QMenu* mMenu;
QgsColorWidget* mColorWidget;
//used to supress recursion with hover events
bool mSuppressRecurse;
bool mDismissOnColorSelection;
private slots:
/** Handles setting the active action for the menu when cursor hovers over color widget
*/
void onHover();
/** Emits color changed signal and closes parent menu
*/
void setColor( const QColor &color );
};
/** \ingroup gui
* \class QgsColorWheel
* A color wheel widget. This widget consists of an outer ring which allows for hue selection, and an
@ -193,6 +273,7 @@ class GUI_EXPORT QgsColorWheel : public QgsColorWidget
virtual ~QgsColorWheel();
virtual QSize sizeHint() const override;
void paintEvent( QPaintEvent* event ) override;
public slots:
@ -607,6 +688,7 @@ class GUI_EXPORT QgsColorPreviewWidget : public QgsColorWidget
virtual ~QgsColorPreviewWidget();
void paintEvent( QPaintEvent* event ) override;
virtual QSize sizeHint() const override;
/** Returns the secondary color for the widget
* @returns secondary widget color, or an invalid color if the widget