Skip to content

Commit d7401df

Browse files
committed
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 (cherry-picked from f16b387)
1 parent bc0f993 commit d7401df

File tree

7 files changed

+183
-96
lines changed

7 files changed

+183
-96
lines changed
Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
1+
/** \ingroup gui
2+
* @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
3+
* The clear value can be either the minimum or the maiximum value of the spin box or a custom value.
4+
* This value can then be handled by a special value text.
5+
*/
6+
17
class QgsDoubleSpinBox : QDoubleSpinBox
28
{
39
%TypeHeaderCode
410
#include <qgsdoublespinbox.h>
511
%End
612

713
public:
14+
15+
//! Behaviour when widget is cleared.
816
enum ClearValueMode
917
{
10-
MinimumValue,
11-
MaximumValue,
12-
CustomValue
18+
MinimumValue, //!< Reset value to minimum()
19+
MaximumValue, //!< Reset value to maximum()
20+
CustomValue, //!< Reset value to custom value (see setClearValue() )
1321
};
1422

23+
/** Constructor for QgsDoubleSpinBox.
24+
* @param parent parent widget
25+
*/
1526
explicit QgsDoubleSpinBox( QWidget *parent /TransferThis/ = 0 );
1627

17-
//! determines if the widget will show a clear button
18-
//! @note the clear button will set the widget to its minimum value
28+
/** Sets whether the widget will show a clear button. The clear button
29+
* allows users to reset the widget to a default or empty state.
30+
* @param showClearButton set to true to show the clear button, or false to hide it
31+
* @see showClearButton()
32+
*/
1933
void setShowClearButton( const bool showClearButton );
34+
35+
/** Returns whether the widget is showing a clear button.
36+
* @see setShowClearButton()
37+
*/
2038
bool showClearButton() const;
2139

2240
/** Sets if the widget will allow entry of simple expressions, which are
@@ -25,6 +43,7 @@ class QgsDoubleSpinBox : QDoubleSpinBox
2543
* @note added in QGIS 2.7
2644
*/
2745
void setExpressionsEnabled( const bool enabled );
46+
2847
/** Returns whether the widget will allow entry of simple expressions, which are
2948
* evaluated and then discarded.
3049
* @returns true if spin box allows expression entry
@@ -36,26 +55,29 @@ class QgsDoubleSpinBox : QDoubleSpinBox
3655
virtual void clear();
3756

3857
/**
39-
* @brief setClearValue defines the clear value as a custom value and will automatically set the clear value mode to CustomValue
58+
* Defines the clear value as a custom value and will automatically set the clear value mode to CustomValue.
4059
* @param customValue defines the numerical value used as the clear value
4160
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
61+
* @see setClearValue()
4262
*/
4363
void setClearValue( double customValue, const QString& clearValueText = QString() );
64+
4465
/**
45-
* @brief setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or a custom value
66+
* Defines if the clear value should be the minimum or maximum values of the widget or a custom value.
4667
* @param mode mode to user for clear value
4768
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
4869
*/
4970
void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() );
5071

51-
//! returns the value used when clear() is called.
72+
/** Returns the value used when clear() is called.
73+
* @see setClearValue()
74+
*/
5275
double clearValue() const;
5376

5477
virtual double valueFromText( const QString & text ) const;
5578
virtual QValidator::State validate( QString & input, int & pos ) const;
5679

5780
protected:
58-
virtual void resizeEvent( QResizeEvent* event );
5981
virtual void changeEvent( QEvent* event );
6082
virtual void paintEvent( QPaintEvent* event );
6183
};
Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
1+
/** \ingroup gui
2+
* @brief The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
3+
* The clear value can be either the minimum or the maiximum value of the spin box or a custom value.
4+
* This value can then be handled by a special value text.
5+
*/
6+
17
class QgsSpinBox : QSpinBox
28
{
39
%TypeHeaderCode
410
#include <qgsspinbox.h>
511
%End
612

713
public:
14+
15+
//! Behaviour when widget is cleared.
816
enum ClearValueMode
917
{
10-
MinimumValue,
11-
MaximumValue,
12-
CustomValue
18+
MinimumValue, //!< Reset value to minimum()
19+
MaximumValue, //!< Reset value to maximum()
20+
CustomValue, //!< Reset value to custom value (see setClearValue() )
1321
};
1422

23+
/** Constructor for QgsSpinBox.
24+
* @param parent parent widget
25+
*/
1526
explicit QgsSpinBox( QWidget *parent /TransferThis/ = 0 );
1627

17-
//! determines if the widget will show a clear button
18-
//! @note the clear button will set the widget to its minimum value
28+
/** Sets whether the widget will show a clear button. The clear button
29+
* allows users to reset the widget to a default or empty state.
30+
* @param showClearButton set to true to show the clear button, or false to hide it
31+
* @see showClearButton()
32+
*/
1933
void setShowClearButton( const bool showClearButton );
34+
35+
/** Returns whether the widget is showing a clear button.
36+
* @see setShowClearButton()
37+
*/
2038
bool showClearButton() const;
2139

2240
/** Sets if the widget will allow entry of simple expressions, which are
@@ -25,6 +43,7 @@ class QgsSpinBox : QSpinBox
2543
* @note added in QGIS 2.7
2644
*/
2745
void setExpressionsEnabled( const bool enabled );
46+
2847
/** Returns whether the widget will allow entry of simple expressions, which are
2948
* evaluated and then discarded.
3049
* @returns true if spin box allows expression entry
@@ -36,26 +55,30 @@ class QgsSpinBox : QSpinBox
3655
virtual void clear();
3756

3857
/**
39-
* @brief setClearValue defines the clear value for the widget and will automatically set the clear value mode to CustomValue
58+
* Defines the clear value as a custom value and will automatically set the clear value mode to CustomValue.
4059
* @param customValue defines the numerical value used as the clear value
4160
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
61+
* @see setClearValue()
4262
*/
4363
void setClearValue( int customValue, const QString& clearValueText = QString() );
64+
4465
/**
45-
* @brief setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or a custom value
66+
* Defines if the clear value should be the minimum or maximum values of the widget or a custom value.
4667
* @param mode mode to user for clear value
4768
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
4869
*/
4970
void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() );
5071

51-
//! returns the value used when clear() is called.
72+
/** Returns the value used when clear() is called.
73+
* @see setClearValue()
74+
*/
5275
int clearValue() const;
5376

5477
virtual int valueFromText( const QString & text ) const;
5578
virtual QValidator::State validate( QString & input, int & pos ) const;
5679

5780
protected:
58-
virtual void resizeEvent( QResizeEvent* event );
81+
5982
virtual void changeEvent( QEvent* event );
6083
virtual void paintEvent( QPaintEvent* event );
6184
};

src/gui/editorwidgets/qgsdoublespinbox.cpp

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
#include <QMouseEvent>
1818
#include <QSettings>
1919
#include <QStyle>
20-
#include <QToolButton>
2120

2221
#include "qgsdoublespinbox.h"
2322
#include "qgsexpression.h"
2423
#include "qgsapplication.h"
2524
#include "qgslogger.h"
25+
#include "qgsfilterlineedit.h"
26+
27+
#define CLEAR_ICON_SIZE 16
2628

2729
QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent )
2830
: QDoubleSpinBox( parent )
@@ -31,25 +33,22 @@ QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent )
3133
, mCustomClearValue( 0.0 )
3234
, mExpressionsEnabled( true )
3335
{
34-
mClearButton = new QToolButton( this );
35-
mClearButton->setIcon( QgsApplication::getThemeIcon( "/mIconClear.svg" ) );
36-
mClearButton->setCursor( Qt::ArrowCursor );
37-
mClearButton->setStyleSheet( "position: absolute; border: none; padding: 0px;" );
38-
connect( mClearButton, SIGNAL( clicked() ), this, SLOT( clear() ) );
36+
mLineEdit = new QgsSpinBoxLineEdit();
3937

40-
setStyleSheet( QString( "padding-right: %1px;" ).arg( mClearButton->sizeHint().width() + 18 + frameWidth() + 1 ) );
38+
setLineEdit( mLineEdit );
4139

4240
QSize msz = minimumSizeHint();
43-
setMinimumSize( qMax( msz.width(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ),
44-
qMax( msz.height(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ) );
41+
setMinimumSize( msz.width() + CLEAR_ICON_SIZE + 9 + frameWidth() * 2 + 2,
42+
qMax( msz.height(), CLEAR_ICON_SIZE + frameWidth() * 2 + 2 ) );
4543

44+
connect( mLineEdit, SIGNAL( cleared() ), this, SLOT( clear() ) );
4645
connect( this, SIGNAL( valueChanged( double ) ), this, SLOT( changed( double ) ) );
4746
}
4847

4948
void QgsDoubleSpinBox::setShowClearButton( const bool showClearButton )
5049
{
5150
mShowClearButton = showClearButton;
52-
mClearButton->setVisible( shouldShowClearForValue( value() ) );
51+
mLineEdit->setShowClearButton( showClearButton );
5352
}
5453

5554
void QgsDoubleSpinBox::setExpressionsEnabled( const bool enabled )
@@ -60,18 +59,18 @@ void QgsDoubleSpinBox::setExpressionsEnabled( const bool enabled )
6059
void QgsDoubleSpinBox::changeEvent( QEvent *event )
6160
{
6261
QDoubleSpinBox::changeEvent( event );
63-
mClearButton->setVisible( shouldShowClearForValue( value() ) );
62+
mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
6463
}
6564

6665
void QgsDoubleSpinBox::paintEvent( QPaintEvent *event )
6766
{
68-
mClearButton->setVisible( shouldShowClearForValue( value() ) );
67+
mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
6968
QDoubleSpinBox::paintEvent( event );
7069
}
7170

7271
void QgsDoubleSpinBox::changed( double value )
7372
{
74-
mClearButton->setVisible( shouldShowClearForValue( value ) );
73+
mLineEdit->setShowClearButton( shouldShowClearForValue( value ) );
7574
}
7675

7776
void QgsDoubleSpinBox::clear()
@@ -187,14 +186,3 @@ bool QgsDoubleSpinBox::shouldShowClearForValue( const double value ) const
187186
}
188187
return value != clearValue();
189188
}
190-
191-
void QgsDoubleSpinBox::resizeEvent( QResizeEvent * event )
192-
{
193-
QDoubleSpinBox::resizeEvent( event );
194-
195-
QSize sz = mClearButton->sizeHint();
196-
197-
mClearButton->move( rect().right() - frameWidth() - 18 - sz.width(),
198-
( rect().bottom() + 1 - sz.height() ) / 2 );
199-
200-
}

src/gui/editorwidgets/qgsdoublespinbox.h

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
* *
1414
***************************************************************************/
1515

16-
#ifndef QGSDOUBLESPPINBOX_H
17-
#define QGSDOUBLESPPINBOX_H
16+
#ifndef QGSDOUBLESPINBOX_H
17+
#define QGSDOUBLESPINBOX_H
1818

1919
#include <QDoubleSpinBox>
20-
#include <QToolButton>
20+
21+
class QgsSpinBoxLineEdit;
2122

2223
/** \ingroup gui
2324
* @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
2829
{
2930
Q_OBJECT
3031
Q_PROPERTY( bool showClearButton READ showClearButton WRITE setShowClearButton )
32+
Q_PROPERTY( bool clearValue READ clearValue WRITE setClearValue )
3133
Q_PROPERTY( bool expressionsEnabled READ expressionsEnabled WRITE setExpressionsEnabled )
3234

3335
public:
36+
37+
//! Behaviour when widget is cleared.
3438
enum ClearValueMode
3539
{
36-
MinimumValue,
37-
MaximumValue,
38-
CustomValue
40+
MinimumValue, //!< Reset value to minimum()
41+
MaximumValue, //!< Reset value to maximum()
42+
CustomValue, //!< Reset value to custom value (see setClearValue() )
3943
};
4044

45+
/** Constructor for QgsDoubleSpinBox.
46+
* @param parent parent widget
47+
*/
4148
explicit QgsDoubleSpinBox( QWidget *parent = nullptr );
4249

43-
//! determines if the widget will show a clear button
44-
//! @note the clear button will set the widget to its minimum value
50+
/** Sets whether the widget will show a clear button. The clear button
51+
* allows users to reset the widget to a default or empty state.
52+
* @param showClearButton set to true to show the clear button, or false to hide it
53+
* @see showClearButton()
54+
*/
4555
void setShowClearButton( const bool showClearButton );
56+
57+
/** Returns whether the widget is showing a clear button.
58+
* @see setShowClearButton()
59+
*/
4660
bool showClearButton() const {return mShowClearButton;}
4761

4862
/** Sets if the widget will allow entry of simple expressions, which are
@@ -51,6 +65,7 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
5165
* @note added in QGIS 2.7
5266
*/
5367
void setExpressionsEnabled( const bool enabled );
68+
5469
/** Returns whether the widget will allow entry of simple expressions, which are
5570
* evaluated and then discarded.
5671
* @returns true if spin box allows expression entry
@@ -62,28 +77,30 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
6277
virtual void clear() override;
6378

6479
/**
65-
* @brief setClearValue defines the clear value as a custom value and will automatically set the clear value mode to CustomValue
80+
* Defines the clear value as a custom value and will automatically set the clear value mode to CustomValue.
6681
* @param customValue defines the numerical value used as the clear value
6782
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
83+
* @see setClearValue()
6884
*/
6985
void setClearValue( double customValue, const QString& clearValueText = QString() );
86+
7087
/**
71-
* @brief setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or a custom value
88+
* Defines if the clear value should be the minimum or maximum values of the widget or a custom value.
7289
* @param mode mode to user for clear value
7390
* @param clearValueText is the text displayed when the spin box is at the clear value. If not specified, no special value text is used.
7491
*/
7592
void setClearValueMode( ClearValueMode mode, const QString& clearValueText = QString() );
7693

77-
//! returns the value used when clear() is called.
94+
/** Returns the value used when clear() is called.
95+
* @see setClearValue()
96+
*/
7897
double clearValue() const;
7998

8099
virtual double valueFromText( const QString & text ) const override;
81100
virtual QValidator::State validate( QString & input, int & pos ) const override;
82-
83101
void paintEvent( QPaintEvent* e ) override;
84102

85103
protected:
86-
virtual void resizeEvent( QResizeEvent* event ) override;
87104
virtual void changeEvent( QEvent* event ) override;
88105

89106
private slots:
@@ -93,16 +110,15 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
93110
int frameWidth() const;
94111
bool shouldShowClearForValue( const double value ) const;
95112

96-
void updateStyleSheet( const QColor& backgroundColor = QColor() );
113+
QgsSpinBoxLineEdit* mLineEdit;
97114

98115
bool mShowClearButton;
99116
ClearValueMode mClearValueMode;
100117
double mCustomClearValue;
101118

102119
bool mExpressionsEnabled;
103120

104-
QToolButton* mClearButton;
105121
QString stripped( const QString &originalText ) const;
106122
};
107123

108-
#endif // QGSDOUBLESPPINBOX_H
124+
#endif // QGSDOUBLESPINBOX_H

0 commit comments

Comments
 (0)