Skip to content

Commit

Permalink
Add QgsColorWidgetAction for easily inserting QgsColorWidgets in menus
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 9, 2015
1 parent a5d6702 commit 2377688
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 4 deletions.
64 changes: 64 additions & 0 deletions python/gui/qgscolorwidgets.sip
Expand Up @@ -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
Expand Down Expand Up @@ -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 );

};


Expand All @@ -163,6 +225,7 @@ class QgsColorWheel : QgsColorWidget

virtual ~QgsColorWheel();

virtual QSize sizeHint() const;
void paintEvent( QPaintEvent* event );

public slots:
Expand Down Expand Up @@ -394,6 +457,7 @@ class QgsColorPreviewWidget : QgsColorWidget

virtual ~QgsColorPreviewWidget();

virtual QSize sizeHint() const;
void paintEvent( QPaintEvent* event );

/** Returns the secondary color for the widget
Expand Down
91 changes: 87 additions & 4 deletions src/gui/qgscolorwidgets.cpp
Expand Up @@ -28,6 +28,7 @@
#include <QSettings>
#include <QDrag>
#include <cmath>
#include "qgslogger.h"


//
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -378,6 +398,11 @@ QgsColorWheel::~QgsColorWheel()
delete mWidgetImage;
}

QSize QgsColorWheel::sizeHint() const
{
return QSize( 200, 200 );
}

void QgsColorWheel::paintEvent( QPaintEvent *event )
{
Q_UNUSED( event );
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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 )
Expand All @@ -1587,15 +1620,15 @@ void QgsColorPreviewWidget::mousePressEvent( QMouseEvent *e )
{
mDragStartPosition = e->pos();
}
QWidget::mousePressEvent( e );
QgsColorWidget::mousePressEvent( e );
}

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;
}

Expand All @@ -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;
}

Expand All @@ -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();
}
}
82 changes: 82 additions & 0 deletions src/gui/qgscolorwidgets.h
Expand Up @@ -16,6 +16,7 @@
#ifndef QGSCOLORWIDGETS_H
#define QGSCOLORWIDGETS_H

#include <QWidgetAction>
#include <QWidget>

class QColor;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -193,6 +273,7 @@ class GUI_EXPORT QgsColorWheel : public QgsColorWidget

virtual ~QgsColorWheel();

virtual QSize sizeHint() const override;
void paintEvent( QPaintEvent* event ) override;

public slots:
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 2377688

Please sign in to comment.