Use QgsFilterLineEdit for Qgs(Double)SpinBox

Fixes issues with the current approach:
- poor appearance on certain environments (esp OSX)
- large area on spin boxes' right which "swallows" clicks
and blocks interactivity

Fix #12920
This commit is contained in:
Nyall Dawson 2016-09-08 21:15:06 +10:00
parent 228ff23d81
commit f16b3870fa
7 changed files with 183 additions and 96 deletions

View File

@ -1,3 +1,9 @@
/** \ingroup gui
* @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
* The clear value can be either the minimum or the maiximum value of the spin box or a custom value.
* This value can then be handled by a special value text.
*/
class QgsDoubleSpinBox : QDoubleSpinBox class QgsDoubleSpinBox : QDoubleSpinBox
{ {
%TypeHeaderCode %TypeHeaderCode
@ -5,18 +11,30 @@ class QgsDoubleSpinBox : QDoubleSpinBox
%End %End
public: public:
//! Behaviour when widget is cleared.
enum ClearValueMode enum ClearValueMode
{ {
MinimumValue, MinimumValue, //!< Reset value to minimum()
MaximumValue, MaximumValue, //!< Reset value to maximum()
CustomValue CustomValue, //!< Reset value to custom value (see setClearValue() )
}; };
/** Constructor for QgsDoubleSpinBox.
* @param parent parent widget
*/
explicit QgsDoubleSpinBox( QWidget *parent /TransferThis/ = 0 ); explicit QgsDoubleSpinBox( QWidget *parent /TransferThis/ = 0 );
//! determines if the widget will show a clear button /** Sets whether the widget will show a clear button. The clear button
//! @note the clear button will set the widget to its minimum value * allows users to reset the widget to a default or empty state.
* @param showClearButton set to true to show the clear button, or false to hide it
* @see showClearButton()
*/
void setShowClearButton( const bool showClearButton ); void setShowClearButton( const bool showClearButton );
/** Returns whether the widget is showing a clear button.
* @see setShowClearButton()
*/
bool showClearButton() const; bool showClearButton() const;
/** Sets if the widget will allow entry of simple expressions, which are /** Sets if the widget will allow entry of simple expressions, which are
@ -25,6 +43,7 @@ class QgsDoubleSpinBox : QDoubleSpinBox
* @note added in QGIS 2.7 * @note added in QGIS 2.7
*/ */
void setExpressionsEnabled( const bool enabled ); void setExpressionsEnabled( const bool enabled );
/** Returns whether the widget will allow entry of simple expressions, which are /** Returns whether the widget will allow entry of simple expressions, which are
* evaluated and then discarded. * evaluated and then discarded.
* @returns true if spin box allows expression entry * @returns true if spin box allows expression entry
@ -36,26 +55,29 @@ class QgsDoubleSpinBox : QDoubleSpinBox
virtual void clear(); virtual void clear();
/** /**
* @brief setClearValue defines the clear value as a custom value and will automatically set the clear value mode to CustomValue * Defines the clear value as a custom value and will automatically set the clear value mode to CustomValue.
* @param customValue defines the numerical value used as the clear value * @param customValue defines the numerical value used as the clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
* @see setClearValue()
*/ */
void setClearValue( double customValue, const QString& clearValueText = QString() ); void setClearValue( double customValue, const QString& clearValueText = QString() );
/** /**
* @brief setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or a custom value * Defines if the clear value should be the minimum or maximum values of the widget or a custom value.
* @param mode mode to user for clear value * @param mode mode to user for clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
*/ */
void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() ); void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() );
//! returns the value used when clear() is called. /** Returns the value used when clear() is called.
* @see setClearValue()
*/
double clearValue() const; double clearValue() const;
virtual double valueFromText( const QString & text ) const; virtual double valueFromText( const QString & text ) const;
virtual QValidator::State validate( QString & input, int & pos ) const; virtual QValidator::State validate( QString & input, int & pos ) const;
protected: protected:
virtual void resizeEvent( QResizeEvent* event );
virtual void changeEvent( QEvent* event ); virtual void changeEvent( QEvent* event );
virtual void paintEvent( QPaintEvent* event ); virtual void paintEvent( QPaintEvent* event );
}; };

View File

@ -1,3 +1,9 @@
/** \ingroup gui
* @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
* The clear value can be either the minimum or the maiximum value of the spin box or a custom value.
* This value can then be handled by a special value text.
*/
class QgsSpinBox : QSpinBox class QgsSpinBox : QSpinBox
{ {
%TypeHeaderCode %TypeHeaderCode
@ -5,18 +11,30 @@ class QgsSpinBox : QSpinBox
%End %End
public: public:
//! Behaviour when widget is cleared.
enum ClearValueMode enum ClearValueMode
{ {
MinimumValue, MinimumValue, //!< Reset value to minimum()
MaximumValue, MaximumValue, //!< Reset value to maximum()
CustomValue CustomValue, //!< Reset value to custom value (see setClearValue() )
}; };
/** Constructor for QgsSpinBox.
* @param parent parent widget
*/
explicit QgsSpinBox( QWidget *parent /TransferThis/ = 0 ); explicit QgsSpinBox( QWidget *parent /TransferThis/ = 0 );
//! determines if the widget will show a clear button /** Sets whether the widget will show a clear button. The clear button
//! @note the clear button will set the widget to its minimum value * allows users to reset the widget to a default or empty state.
* @param showClearButton set to true to show the clear button, or false to hide it
* @see showClearButton()
*/
void setShowClearButton( const bool showClearButton ); void setShowClearButton( const bool showClearButton );
/** Returns whether the widget is showing a clear button.
* @see setShowClearButton()
*/
bool showClearButton() const; bool showClearButton() const;
/** Sets if the widget will allow entry of simple expressions, which are /** Sets if the widget will allow entry of simple expressions, which are
@ -25,6 +43,7 @@ class QgsSpinBox : QSpinBox
* @note added in QGIS 2.7 * @note added in QGIS 2.7
*/ */
void setExpressionsEnabled( const bool enabled ); void setExpressionsEnabled( const bool enabled );
/** Returns whether the widget will allow entry of simple expressions, which are /** Returns whether the widget will allow entry of simple expressions, which are
* evaluated and then discarded. * evaluated and then discarded.
* @returns true if spin box allows expression entry * @returns true if spin box allows expression entry
@ -36,26 +55,30 @@ class QgsSpinBox : QSpinBox
virtual void clear(); virtual void clear();
/** /**
* @brief setClearValue defines the clear value for the widget and will automatically set the clear value mode to CustomValue * Defines the clear value as a custom value and will automatically set the clear value mode to CustomValue.
* @param customValue defines the numerical value used as the clear value * @param customValue defines the numerical value used as the clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
* @see setClearValue()
*/ */
void setClearValue( int customValue, const QString& clearValueText = QString() ); void setClearValue( int customValue, const QString& clearValueText = QString() );
/** /**
* @brief setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or a custom value * Defines if the clear value should be the minimum or maximum values of the widget or a custom value.
* @param mode mode to user for clear value * @param mode mode to user for clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
*/ */
void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() ); void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() );
//! returns the value used when clear() is called. /** Returns the value used when clear() is called.
* @see setClearValue()
*/
int clearValue() const; int clearValue() const;
virtual int valueFromText( const QString & text ) const; virtual int valueFromText( const QString & text ) const;
virtual QValidator::State validate( QString & input, int & pos ) const; virtual QValidator::State validate( QString & input, int & pos ) const;
protected: protected:
virtual void resizeEvent( QResizeEvent* event );
virtual void changeEvent( QEvent* event ); virtual void changeEvent( QEvent* event );
virtual void paintEvent( QPaintEvent* event ); virtual void paintEvent( QPaintEvent* event );
}; };

View File

@ -17,12 +17,14 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QSettings> #include <QSettings>
#include <QStyle> #include <QStyle>
#include <QToolButton>
#include "qgsdoublespinbox.h" #include "qgsdoublespinbox.h"
#include "qgsexpression.h" #include "qgsexpression.h"
#include "qgsapplication.h" #include "qgsapplication.h"
#include "qgslogger.h" #include "qgslogger.h"
#include "qgsfilterlineedit.h"
#define CLEAR_ICON_SIZE 16
QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent ) QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent )
: QDoubleSpinBox( parent ) : QDoubleSpinBox( parent )
@ -31,25 +33,22 @@ QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent )
, mCustomClearValue( 0.0 ) , mCustomClearValue( 0.0 )
, mExpressionsEnabled( true ) , mExpressionsEnabled( true )
{ {
mClearButton = new QToolButton( this ); mLineEdit = new QgsSpinBoxLineEdit();
mClearButton->setIcon( QgsApplication::getThemeIcon( "/mIconClear.svg" ) );
mClearButton->setCursor( Qt::ArrowCursor );
mClearButton->setStyleSheet( "position: absolute; border: none; padding: 0px;" );
connect( mClearButton, SIGNAL( clicked() ), this, SLOT( clear() ) );
setStyleSheet( QString( "padding-right: %1px;" ).arg( mClearButton->sizeHint().width() + 18 + frameWidth() + 1 ) ); setLineEdit( mLineEdit );
QSize msz = minimumSizeHint(); QSize msz = minimumSizeHint();
setMinimumSize( qMax( msz.width(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ), setMinimumSize( msz.width() + CLEAR_ICON_SIZE + 9 + frameWidth() * 2 + 2,
qMax( msz.height(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ) ); qMax( msz.height(), CLEAR_ICON_SIZE + frameWidth() * 2 + 2 ) );
connect( mLineEdit, SIGNAL( cleared() ), this, SLOT( clear() ) );
connect( this, SIGNAL( valueChanged( double ) ), this, SLOT( changed( double ) ) ); connect( this, SIGNAL( valueChanged( double ) ), this, SLOT( changed( double ) ) );
} }
void QgsDoubleSpinBox::setShowClearButton( const bool showClearButton ) void QgsDoubleSpinBox::setShowClearButton( const bool showClearButton )
{ {
mShowClearButton = showClearButton; mShowClearButton = showClearButton;
mClearButton->setVisible( shouldShowClearForValue( value() ) ); mLineEdit->setShowClearButton( showClearButton );
} }
void QgsDoubleSpinBox::setExpressionsEnabled( const bool enabled ) void QgsDoubleSpinBox::setExpressionsEnabled( const bool enabled )
@ -60,18 +59,18 @@ void QgsDoubleSpinBox::setExpressionsEnabled( const bool enabled )
void QgsDoubleSpinBox::changeEvent( QEvent *event ) void QgsDoubleSpinBox::changeEvent( QEvent *event )
{ {
QDoubleSpinBox::changeEvent( event ); QDoubleSpinBox::changeEvent( event );
mClearButton->setVisible( shouldShowClearForValue( value() ) ); mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
} }
void QgsDoubleSpinBox::paintEvent( QPaintEvent *event ) void QgsDoubleSpinBox::paintEvent( QPaintEvent *event )
{ {
mClearButton->setVisible( shouldShowClearForValue( value() ) ); mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
QDoubleSpinBox::paintEvent( event ); QDoubleSpinBox::paintEvent( event );
} }
void QgsDoubleSpinBox::changed( double value ) void QgsDoubleSpinBox::changed( double value )
{ {
mClearButton->setVisible( shouldShowClearForValue( value ) ); mLineEdit->setShowClearButton( shouldShowClearForValue( value ) );
} }
void QgsDoubleSpinBox::clear() void QgsDoubleSpinBox::clear()
@ -187,14 +186,3 @@ bool QgsDoubleSpinBox::shouldShowClearForValue( const double value ) const
} }
return value != clearValue(); return value != clearValue();
} }
void QgsDoubleSpinBox::resizeEvent( QResizeEvent * event )
{
QDoubleSpinBox::resizeEvent( event );
QSize sz = mClearButton->sizeHint();
mClearButton->move( rect().right() - frameWidth() - 18 - sz.width(),
( rect().bottom() + 1 - sz.height() ) / 2 );
}

View File

@ -13,11 +13,12 @@
* * * *
***************************************************************************/ ***************************************************************************/
#ifndef QGSDOUBLESPPINBOX_H #ifndef QGSDOUBLESPINBOX_H
#define QGSDOUBLESPPINBOX_H #define QGSDOUBLESPINBOX_H
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QToolButton>
class QgsSpinBoxLineEdit;
/** \ingroup gui /** \ingroup gui
* @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value. * @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
@ -28,21 +29,34 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY( bool showClearButton READ showClearButton WRITE setShowClearButton ) Q_PROPERTY( bool showClearButton READ showClearButton WRITE setShowClearButton )
Q_PROPERTY( bool clearValue READ clearValue WRITE setClearValue )
Q_PROPERTY( bool expressionsEnabled READ expressionsEnabled WRITE setExpressionsEnabled ) Q_PROPERTY( bool expressionsEnabled READ expressionsEnabled WRITE setExpressionsEnabled )
public: public:
//! Behaviour when widget is cleared.
enum ClearValueMode enum ClearValueMode
{ {
MinimumValue, MinimumValue, //!< Reset value to minimum()
MaximumValue, MaximumValue, //!< Reset value to maximum()
CustomValue CustomValue, //!< Reset value to custom value (see setClearValue() )
}; };
/** Constructor for QgsDoubleSpinBox.
* @param parent parent widget
*/
explicit QgsDoubleSpinBox( QWidget *parent = nullptr ); explicit QgsDoubleSpinBox( QWidget *parent = nullptr );
//! determines if the widget will show a clear button /** Sets whether the widget will show a clear button. The clear button
//! @note the clear button will set the widget to its minimum value * allows users to reset the widget to a default or empty state.
* @param showClearButton set to true to show the clear button, or false to hide it
* @see showClearButton()
*/
void setShowClearButton( const bool showClearButton ); void setShowClearButton( const bool showClearButton );
/** Returns whether the widget is showing a clear button.
* @see setShowClearButton()
*/
bool showClearButton() const {return mShowClearButton;} bool showClearButton() const {return mShowClearButton;}
/** Sets if the widget will allow entry of simple expressions, which are /** Sets if the widget will allow entry of simple expressions, which are
@ -51,6 +65,7 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
* @note added in QGIS 2.7 * @note added in QGIS 2.7
*/ */
void setExpressionsEnabled( const bool enabled ); void setExpressionsEnabled( const bool enabled );
/** Returns whether the widget will allow entry of simple expressions, which are /** Returns whether the widget will allow entry of simple expressions, which are
* evaluated and then discarded. * evaluated and then discarded.
* @returns true if spin box allows expression entry * @returns true if spin box allows expression entry
@ -62,28 +77,30 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
virtual void clear() override; virtual void clear() override;
/** /**
* @brief setClearValue defines the clear value as a custom value and will automatically set the clear value mode to CustomValue * Defines the clear value as a custom value and will automatically set the clear value mode to CustomValue.
* @param customValue defines the numerical value used as the clear value * @param customValue defines the numerical value used as the clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
* @see setClearValue()
*/ */
void setClearValue( double customValue, const QString& clearValueText = QString() ); void setClearValue( double customValue, const QString& clearValueText = QString() );
/** /**
* @brief setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or a custom value * Defines if the clear value should be the minimum or maximum values of the widget or a custom value.
* @param mode mode to user for clear value * @param mode mode to user for clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
*/ */
void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() ); void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() );
//! returns the value used when clear() is called. /** Returns the value used when clear() is called.
* @see setClearValue()
*/
double clearValue() const; double clearValue() const;
virtual double valueFromText( const QString & text ) const override; virtual double valueFromText( const QString & text ) const override;
virtual QValidator::State validate( QString & input, int & pos ) const override; virtual QValidator::State validate( QString & input, int & pos ) const override;
void paintEvent( QPaintEvent* e ) override; void paintEvent( QPaintEvent* e ) override;
protected: protected:
virtual void resizeEvent( QResizeEvent* event ) override;
virtual void changeEvent( QEvent* event ) override; virtual void changeEvent( QEvent* event ) override;
private slots: private slots:
@ -93,7 +110,7 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
int frameWidth() const; int frameWidth() const;
bool shouldShowClearForValue( const double value ) const; bool shouldShowClearForValue( const double value ) const;
void updateStyleSheet( const QColor& backgroundColor = QColor() ); QgsSpinBoxLineEdit* mLineEdit;
bool mShowClearButton; bool mShowClearButton;
ClearValueMode mClearValueMode; ClearValueMode mClearValueMode;
@ -101,8 +118,7 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
bool mExpressionsEnabled; bool mExpressionsEnabled;
QToolButton* mClearButton;
QString stripped( const QString &originalText ) const; QString stripped( const QString &originalText ) const;
}; };
#endif // QGSDOUBLESPPINBOX_H #endif // QGSDOUBLESPINBOX_H

View File

@ -17,12 +17,14 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QSettings> #include <QSettings>
#include <QStyle> #include <QStyle>
#include <QToolButton>
#include "qgsspinbox.h" #include "qgsspinbox.h"
#include "qgsexpression.h" #include "qgsexpression.h"
#include "qgsapplication.h" #include "qgsapplication.h"
#include "qgslogger.h" #include "qgslogger.h"
#include "qgsfilterlineedit.h"
#define CLEAR_ICON_SIZE 16
QgsSpinBox::QgsSpinBox( QWidget *parent ) QgsSpinBox::QgsSpinBox( QWidget *parent )
: QSpinBox( parent ) : QSpinBox( parent )
@ -31,25 +33,22 @@ QgsSpinBox::QgsSpinBox( QWidget *parent )
, mCustomClearValue( 0 ) , mCustomClearValue( 0 )
, mExpressionsEnabled( true ) , mExpressionsEnabled( true )
{ {
mClearButton = new QToolButton( this ); mLineEdit = new QgsSpinBoxLineEdit();
mClearButton->setIcon( QgsApplication::getThemeIcon( "/mIconClear.svg" ) );
mClearButton->setCursor( Qt::ArrowCursor );
mClearButton->setStyleSheet( "position: absolute; border: none; padding: 0px;" );
connect( mClearButton, SIGNAL( clicked() ), this, SLOT( clear() ) );
setStyleSheet( QString( "padding-right: %1px;" ).arg( mClearButton->sizeHint().width() + 18 + frameWidth() + 1 ) ); setLineEdit( mLineEdit );
QSize msz = minimumSizeHint(); QSize msz = minimumSizeHint();
setMinimumSize( qMax( msz.width(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ), setMinimumSize( msz.width() + CLEAR_ICON_SIZE + 9 + frameWidth() * 2 + 2,
qMax( msz.height(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ) ); qMax( msz.height(), CLEAR_ICON_SIZE + frameWidth() * 2 + 2 ) );
connect( mLineEdit, SIGNAL( cleared() ), this, SLOT( clear() ) );
connect( this, SIGNAL( valueChanged( int ) ), this, SLOT( changed( int ) ) ); connect( this, SIGNAL( valueChanged( int ) ), this, SLOT( changed( int ) ) );
} }
void QgsSpinBox::setShowClearButton( const bool showClearButton ) void QgsSpinBox::setShowClearButton( const bool showClearButton )
{ {
mShowClearButton = showClearButton; mShowClearButton = showClearButton;
mClearButton->setVisible( shouldShowClearForValue( value() ) ); mLineEdit->setShowClearButton( showClearButton );
} }
void QgsSpinBox::setExpressionsEnabled( const bool enabled ) void QgsSpinBox::setExpressionsEnabled( const bool enabled )
@ -60,18 +59,18 @@ void QgsSpinBox::setExpressionsEnabled( const bool enabled )
void QgsSpinBox::changeEvent( QEvent *event ) void QgsSpinBox::changeEvent( QEvent *event )
{ {
QSpinBox::changeEvent( event ); QSpinBox::changeEvent( event );
mClearButton->setVisible( shouldShowClearForValue( value() ) ); mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
} }
void QgsSpinBox::paintEvent( QPaintEvent *event ) void QgsSpinBox::paintEvent( QPaintEvent *event )
{ {
mClearButton->setVisible( shouldShowClearForValue( value() ) ); mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
QSpinBox::paintEvent( event ); QSpinBox::paintEvent( event );
} }
void QgsSpinBox::changed( int value ) void QgsSpinBox::changed( int value )
{ {
mClearButton->setVisible( shouldShowClearForValue( value ) ); mLineEdit->setShowClearButton( shouldShowClearForValue( value ) );
} }
void QgsSpinBox::clear() void QgsSpinBox::clear()
@ -187,14 +186,3 @@ QString QgsSpinBox::stripped( const QString &originalText ) const
return text; return text;
} }
void QgsSpinBox::resizeEvent( QResizeEvent * event )
{
QSpinBox::resizeEvent( event );
QSize sz = mClearButton->sizeHint();
mClearButton->move( rect().right() - frameWidth() - 18 - sz.width(),
( rect().bottom() + 1 - sz.height() ) / 2 );
}

View File

@ -13,11 +13,12 @@
* * * *
***************************************************************************/ ***************************************************************************/
#ifndef QGSSPPINBOX_H #ifndef QGSSPINBOX_H
#define QGSSPPINBOX_H #define QGSSPINBOX_H
#include <QSpinBox> #include <QSpinBox>
#include <QToolButton>
class QgsSpinBoxLineEdit;
/** \ingroup gui /** \ingroup gui
* @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value. * @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
@ -28,20 +29,34 @@ class GUI_EXPORT QgsSpinBox : public QSpinBox
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY( bool showClearButton READ showClearButton WRITE setShowClearButton ) Q_PROPERTY( bool showClearButton READ showClearButton WRITE setShowClearButton )
Q_PROPERTY( bool clearValue READ clearValue WRITE setClearValue )
Q_PROPERTY( bool expressionsEnabled READ expressionsEnabled WRITE setExpressionsEnabled )
public: public:
//! Behaviour when widget is cleared.
enum ClearValueMode enum ClearValueMode
{ {
MinimumValue, MinimumValue, //!< Reset value to minimum()
MaximumValue, MaximumValue, //!< Reset value to maximum()
CustomValue CustomValue, //!< Reset value to custom value (see setClearValue() )
}; };
/** Constructor for QgsSpinBox.
* @param parent parent widget
*/
explicit QgsSpinBox( QWidget *parent = nullptr ); explicit QgsSpinBox( QWidget *parent = nullptr );
//! determines if the widget will show a clear button /** Sets whether the widget will show a clear button. The clear button
//! @note the clear button will set the widget to its minimum value * allows users to reset the widget to a default or empty state.
* @param showClearButton set to true to show the clear button, or false to hide it
* @see showClearButton()
*/
void setShowClearButton( const bool showClearButton ); void setShowClearButton( const bool showClearButton );
/** Returns whether the widget is showing a clear button.
* @see setShowClearButton()
*/
bool showClearButton() const {return mShowClearButton;} bool showClearButton() const {return mShowClearButton;}
/** Sets if the widget will allow entry of simple expressions, which are /** Sets if the widget will allow entry of simple expressions, which are
@ -50,6 +65,7 @@ class GUI_EXPORT QgsSpinBox : public QSpinBox
* @note added in QGIS 2.7 * @note added in QGIS 2.7
*/ */
void setExpressionsEnabled( const bool enabled ); void setExpressionsEnabled( const bool enabled );
/** Returns whether the widget will allow entry of simple expressions, which are /** Returns whether the widget will allow entry of simple expressions, which are
* evaluated and then discarded. * evaluated and then discarded.
* @returns true if spin box allows expression entry * @returns true if spin box allows expression entry
@ -61,26 +77,30 @@ class GUI_EXPORT QgsSpinBox : public QSpinBox
virtual void clear() override; virtual void clear() override;
/** /**
* @brief setClearValue defines the clear value for the widget and will automatically set the clear value mode to CustomValue * Defines the clear value as a custom value and will automatically set the clear value mode to CustomValue.
* @param customValue defines the numerical value used as the clear value * @param customValue defines the numerical value used as the clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
* @see setClearValue()
*/ */
void setClearValue( int customValue, const QString& clearValueText = QString() ); void setClearValue( int customValue, const QString& clearValueText = QString() );
/** /**
* @brief setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or a custom value * Defines if the clear value should be the minimum or maximum values of the widget or a custom value.
* @param mode mode to user for clear value * @param mode mode to user for clear value
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used. * @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
*/ */
void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() ); void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() );
//! returns the value used when clear() is called. /** Returns the value used when clear() is called.
* @see setClearValue()
*/
int clearValue() const; int clearValue() const;
virtual int valueFromText( const QString & text ) const override; virtual int valueFromText( const QString & text ) const override;
virtual QValidator::State validate( QString & input, int & pos ) const override; virtual QValidator::State validate( QString & input, int & pos ) const override;
protected: protected:
virtual void resizeEvent( QResizeEvent* event ) override;
virtual void changeEvent( QEvent* event ) override; virtual void changeEvent( QEvent* event ) override;
virtual void paintEvent( QPaintEvent* event ) override; virtual void paintEvent( QPaintEvent* event ) override;
@ -91,14 +111,15 @@ class GUI_EXPORT QgsSpinBox : public QSpinBox
int frameWidth() const; int frameWidth() const;
bool shouldShowClearForValue( const int value ) const; bool shouldShowClearForValue( const int value ) const;
QgsSpinBoxLineEdit* mLineEdit;
bool mShowClearButton; bool mShowClearButton;
ClearValueMode mClearValueMode; ClearValueMode mClearValueMode;
int mCustomClearValue; int mCustomClearValue;
bool mExpressionsEnabled; bool mExpressionsEnabled;
QToolButton* mClearButton;
QString stripped( const QString &originalText ) const; QString stripped( const QString &originalText ) const;
}; };
#endif // QGSSPPINBOX_H #endif // QGSSPINBOX_H

View File

@ -197,4 +197,33 @@ class GUI_EXPORT QgsFilterLineEdit : public QLineEdit
QRect clearRect() const; QRect clearRect() const;
}; };
/// @cond PRIVATE
/** Private QgsFilterLineEdit subclass for use as a line edit in QgsSpinBox/QgsDoubleSpinBox
* we let QgsFilterLineEdit handle display of the clear button and detection
* of clicks, but override clearValue() and let Qgs(Double)SpinBox handle the clearing
* themselves.
*/
class QgsSpinBoxLineEdit : public QgsFilterLineEdit
{
Q_OBJECT
public:
QgsSpinBoxLineEdit( QWidget* parent = nullptr )
: QgsFilterLineEdit( parent )
{}
public slots:
virtual void clearValue() override
{
// don't change the value - let spin boxes handle that by detecting cleared() signal
setCursor( Qt::IBeamCursor );
setModified( true );
emit cleared();
}
};
/// @endcond
#endif // QGSFILTERLINEEDIT_H #endif // QGSFILTERLINEEDIT_H