mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
[QgsFilterLineEdit] use QLineEdit::addAction instead of hacking paintEvent
this gets much more simple
This commit is contained in:
parent
d1a922b565
commit
9bf943a777
@ -257,16 +257,8 @@ Will select all text when this widget receives the focus.
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent( QMouseEvent *e );
|
||||
|
||||
virtual void mouseMoveEvent( QMouseEvent *e );
|
||||
|
||||
virtual void focusInEvent( QFocusEvent *e );
|
||||
|
||||
virtual void paintEvent( QPaintEvent *e );
|
||||
|
||||
virtual void leaveEvent( QEvent *e );
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsanimatedicon.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QToolButton>
|
||||
#include <QStyle>
|
||||
#include <QFocusEvent>
|
||||
@ -28,27 +29,22 @@ QgsFilterLineEdit::QgsFilterLineEdit( QWidget *parent, const QString &nullValue
|
||||
: QLineEdit( parent )
|
||||
, mNullValue( nullValue )
|
||||
{
|
||||
// need mouse tracking to handle cursor changes
|
||||
setMouseTracking( true );
|
||||
|
||||
QIcon clearIcon = QgsApplication::getThemeIcon( "/mIconClearText.svg" );
|
||||
|
||||
// icon size is about 2/3 height of text, but minimum size of 16
|
||||
int iconSize = std::floor( std::max( Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 0.75, 16.0 ) );
|
||||
|
||||
mClearIconSize = QSize( iconSize, iconSize );
|
||||
mClearIconPixmap = clearIcon.pixmap( mClearIconSize );
|
||||
QIcon hoverIcon = QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" );
|
||||
mClearHoverPixmap = hoverIcon.pixmap( mClearIconSize );
|
||||
QIcon clearIcon;
|
||||
clearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearText.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Normal, QIcon::On );
|
||||
clearIcon.addPixmap( QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" ).pixmap( QSize( iconSize, iconSize ) ), QIcon::Selected, QIcon::On );
|
||||
mClearAction = new QAction( clearIcon, this );
|
||||
mClearAction->setCheckable( false );
|
||||
addAction( mClearAction, QLineEdit::TrailingPosition );
|
||||
connect( mClearAction, &QAction::triggered, this, &QgsFilterLineEdit::clearValue );
|
||||
|
||||
QIcon searchIcon = QgsApplication::getThemeIcon( "/search.svg" );
|
||||
mSearchIconSize = QSize( iconSize, iconSize );
|
||||
mSearchIconPixmap = searchIcon.pixmap( mSearchIconSize );
|
||||
|
||||
// Make some space for the clear icon
|
||||
QMargins margins( textMargins( ) );
|
||||
margins.setRight( iconSize );
|
||||
setTextMargins( margins );
|
||||
mSearchAction = new QAction( searchIcon, this );
|
||||
mSearchAction->setCheckable( false );
|
||||
addAction( mSearchAction, QLineEdit::TrailingPosition );
|
||||
mSearchAction->setVisible( false );
|
||||
|
||||
connect( this, &QLineEdit::textChanged, this,
|
||||
&QgsFilterLineEdit::onTextChanged );
|
||||
@ -56,56 +52,19 @@ QgsFilterLineEdit::QgsFilterLineEdit( QWidget *parent, const QString &nullValue
|
||||
|
||||
void QgsFilterLineEdit::setShowClearButton( bool visible )
|
||||
{
|
||||
bool changed = mClearButtonVisible != visible;
|
||||
mClearButtonVisible = visible;
|
||||
if ( !visible )
|
||||
mClearHover = false;
|
||||
|
||||
if ( changed )
|
||||
update();
|
||||
updateClearIcon();
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::setShowSearchIcon( bool visible )
|
||||
{
|
||||
bool changed = mSearchIconVisible != visible;
|
||||
if ( changed )
|
||||
{
|
||||
mSearchIconVisible = visible;
|
||||
update();
|
||||
}
|
||||
mSearchAction->setVisible( visible );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::mousePressEvent( QMouseEvent *e )
|
||||
void QgsFilterLineEdit::updateClearIcon()
|
||||
{
|
||||
if ( !mFocusInEvent )
|
||||
QLineEdit::mousePressEvent( e );
|
||||
else
|
||||
mFocusInEvent = false;
|
||||
|
||||
if ( shouldShowClear() && clearRect().contains( e->pos() ) )
|
||||
{
|
||||
clearValue();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::mouseMoveEvent( QMouseEvent *e )
|
||||
{
|
||||
QLineEdit::mouseMoveEvent( e );
|
||||
if ( shouldShowClear() && clearRect().contains( e->pos() ) )
|
||||
{
|
||||
if ( !mClearHover )
|
||||
{
|
||||
setCursor( Qt::ArrowCursor );
|
||||
mClearHover = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
else if ( mClearHover )
|
||||
{
|
||||
setCursor( Qt::IBeamCursor );
|
||||
mClearHover = false;
|
||||
update();
|
||||
}
|
||||
mClearAction->setVisible( shouldShowClear() );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::focusInEvent( QFocusEvent *e )
|
||||
@ -132,57 +91,14 @@ void QgsFilterLineEdit::clearValue()
|
||||
break;
|
||||
}
|
||||
|
||||
if ( mClearHover )
|
||||
{
|
||||
setCursor( Qt::IBeamCursor );
|
||||
mClearHover = false;
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
emit cleared();
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::paintEvent( QPaintEvent *e )
|
||||
{
|
||||
QLineEdit::paintEvent( e );
|
||||
if ( shouldShowClear() )
|
||||
{
|
||||
QRect r = clearRect();
|
||||
QPainter p( this );
|
||||
if ( mClearHover )
|
||||
p.drawPixmap( r.left(), r.top(), mClearHoverPixmap );
|
||||
else
|
||||
p.drawPixmap( r.left(), r.top(), mClearIconPixmap );
|
||||
}
|
||||
|
||||
if ( mSearchIconVisible && !shouldShowClear() )
|
||||
{
|
||||
QRect r = searchRect();
|
||||
QPainter p( this );
|
||||
p.drawPixmap( r.left(), r.top(), mSearchIconPixmap );
|
||||
}
|
||||
|
||||
if ( mShowSpinner )
|
||||
{
|
||||
QRect r = busySpinnerRect();
|
||||
QPainter p( this );
|
||||
p.drawPixmap( r.left(), r.top(), mBusySpinner->icon().pixmap( r.size() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::leaveEvent( QEvent *e )
|
||||
{
|
||||
if ( mClearHover )
|
||||
{
|
||||
mClearHover = false;
|
||||
update();
|
||||
}
|
||||
|
||||
QLineEdit::leaveEvent( e );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::onTextChanged( const QString &text )
|
||||
{
|
||||
updateClearIcon();
|
||||
|
||||
if ( isNull() )
|
||||
{
|
||||
setStyleSheet( QStringLiteral( "QLineEdit { font: italic; color: gray; } %1" ).arg( mStyleSheet ) );
|
||||
@ -193,17 +109,15 @@ void QgsFilterLineEdit::onTextChanged( const QString &text )
|
||||
setStyleSheet( mStyleSheet );
|
||||
emit valueChanged( text );
|
||||
}
|
||||
|
||||
if ( mClearHover && !shouldShowClear() )
|
||||
{
|
||||
setCursor( Qt::IBeamCursor );
|
||||
mClearHover = false;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::updateBusySpinner()
|
||||
{
|
||||
update();
|
||||
if ( !mBusySpinnerAction )
|
||||
{
|
||||
mBusySpinnerAction = addAction( mBusySpinnerAnimatedIcon->icon(), QLineEdit::TrailingPosition );
|
||||
}
|
||||
mBusySpinnerAction->setIcon( mBusySpinnerAnimatedIcon->icon() );
|
||||
}
|
||||
|
||||
bool QgsFilterLineEdit::selectOnFocus() const
|
||||
@ -227,20 +141,22 @@ bool QgsFilterLineEdit::showSpinner() const
|
||||
|
||||
void QgsFilterLineEdit::setShowSpinner( bool showSpinner )
|
||||
{
|
||||
|
||||
if ( showSpinner == mShowSpinner )
|
||||
return;
|
||||
|
||||
if ( showSpinner )
|
||||
{
|
||||
if ( !mBusySpinner )
|
||||
mBusySpinner = new QgsAnimatedIcon( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), this );
|
||||
if ( !mBusySpinnerAnimatedIcon )
|
||||
mBusySpinnerAnimatedIcon = new QgsAnimatedIcon( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), this );
|
||||
|
||||
mBusySpinner->connectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
|
||||
mBusySpinnerAnimatedIcon->connectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
|
||||
}
|
||||
else
|
||||
{
|
||||
mBusySpinner->disconnectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
|
||||
update();
|
||||
mBusySpinnerAnimatedIcon->disconnectFrameChanged( this, &QgsFilterLineEdit::updateBusySpinner );
|
||||
removeAction( mBusySpinnerAction );
|
||||
mBusySpinnerAction = nullptr;
|
||||
}
|
||||
|
||||
mShowSpinner = showSpinner;
|
||||
@ -262,33 +178,3 @@ bool QgsFilterLineEdit::shouldShowClear() const
|
||||
}
|
||||
return false; //avoid warnings
|
||||
}
|
||||
|
||||
QRect QgsFilterLineEdit::clearRect() const
|
||||
{
|
||||
int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
|
||||
return QRect( rect().right() - frameWidth * 2 - mClearIconSize.width(),
|
||||
( rect().bottom() + 1 - mClearIconSize.height() ) / 2,
|
||||
mClearIconSize.width(),
|
||||
mClearIconSize.height() );
|
||||
}
|
||||
|
||||
QRect QgsFilterLineEdit::busySpinnerRect() const
|
||||
{
|
||||
int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
|
||||
|
||||
int offset = shouldShowClear() ? mClearIconSize.width() + frameWidth * 2 : frameWidth;
|
||||
|
||||
return QRect( rect().right() - offset - mClearIconSize.width(),
|
||||
( rect().bottom() + 1 - mClearIconSize.height() ) / 2,
|
||||
mClearIconSize.width(),
|
||||
mClearIconSize.height() );
|
||||
}
|
||||
|
||||
QRect QgsFilterLineEdit::searchRect() const
|
||||
{
|
||||
int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
|
||||
return QRect( rect().left() + frameWidth * 2,
|
||||
( rect().bottom() + 1 - mSearchIconSize.height() ) / 2,
|
||||
mSearchIconSize.width(),
|
||||
mSearchIconSize.height() );
|
||||
}
|
||||
|
@ -254,17 +254,17 @@ class GUI_EXPORT QgsFilterLineEdit : public QLineEdit
|
||||
void selectOnFocusChanged();
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent *e ) override;
|
||||
void mouseMoveEvent( QMouseEvent *e ) override;
|
||||
void focusInEvent( QFocusEvent *e ) override;
|
||||
void paintEvent( QPaintEvent *e ) override;
|
||||
void leaveEvent( QEvent *e ) override;
|
||||
|
||||
private slots:
|
||||
void onTextChanged( const QString &text );
|
||||
void updateBusySpinner();
|
||||
void updateClearIcon();
|
||||
|
||||
private:
|
||||
QAction *mClearAction;
|
||||
QAction *mSearchAction;
|
||||
QAction *mBusySpinnerAction = nullptr;
|
||||
|
||||
bool mClearButtonVisible = true;
|
||||
bool mSearchIconVisible = false;
|
||||
@ -276,23 +276,12 @@ class GUI_EXPORT QgsFilterLineEdit : public QLineEdit
|
||||
QString mDefaultValue;
|
||||
QString mStyleSheet;
|
||||
bool mFocusInEvent = false;
|
||||
bool mClearHover = false;
|
||||
bool mSelectOnFocus = false;
|
||||
|
||||
QSize mClearIconSize;
|
||||
QPixmap mClearIconPixmap;
|
||||
QPixmap mClearHoverPixmap;
|
||||
|
||||
QSize mSearchIconSize;
|
||||
QPixmap mSearchIconPixmap;
|
||||
QgsAnimatedIcon *mBusySpinner = nullptr;
|
||||
QgsAnimatedIcon *mBusySpinnerAnimatedIcon = nullptr;
|
||||
|
||||
//! Returns true if clear button should be shown
|
||||
bool shouldShowClear() const;
|
||||
|
||||
QRect clearRect() const;
|
||||
QRect searchRect() const;
|
||||
QRect busySpinnerRect() const;
|
||||
};
|
||||
|
||||
/// @cond PRIVATE
|
||||
|
Loading…
x
Reference in New Issue
Block a user