mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Rework QgsFilterLineEdit handling of clear button
Don't use a child button but instead paint the icon when required. Improves interaction with the widget/clear button.
This commit is contained in:
parent
e1f21b003c
commit
98f25f59e7
@ -666,6 +666,8 @@
|
||||
<file>themes/default/mIconFormSelect.svg</file>
|
||||
<file>themes/default/mActionMultiEdit.svg</file>
|
||||
<file>themes/default/dependencies.svg</file>
|
||||
<file>themes/default/mIconClearText.svg</file>
|
||||
<file>themes/default/mIconClearTextHover.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="/images/tips">
|
||||
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
|
||||
|
72
images/themes/default/mIconClearText.svg
Normal file
72
images/themes/default/mIconClearText.svg
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2"
|
||||
height="16"
|
||||
width="16"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mIconClearText.svg">
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1215"
|
||||
inkscape:window-height="776"
|
||||
id="namedview8"
|
||||
showgrid="true"
|
||||
inkscape:zoom="23.6"
|
||||
inkscape:cx="2.2245763"
|
||||
inkscape:cy="8.3898305"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4138" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#969696;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 4.6303139,3 1,8 4.6303139,13 14,13 14,3 13.824245,3 Z"
|
||||
id="path2999"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 5.9226862,10.69629 11.701082,5.2732861"
|
||||
id="path3775" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 5.9226862,5.2732861 11.701082,10.69629"
|
||||
id="path3777" />
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
72
images/themes/default/mIconClearTextHover.svg
Normal file
72
images/themes/default/mIconClearTextHover.svg
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2"
|
||||
height="16"
|
||||
width="16"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mIconClearTextHover.svg">
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1215"
|
||||
inkscape:window-height="776"
|
||||
id="namedview8"
|
||||
showgrid="true"
|
||||
inkscape:zoom="23.6"
|
||||
inkscape:cx="2.2245763"
|
||||
inkscape:cy="8.3898305"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4138" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 4.6303139,3 1,8 4.6303139,13 14,13 14,3 13.824245,3 Z"
|
||||
id="path2999"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 5.9226862,10.69629 11.701082,5.2732861"
|
||||
id="path3775" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 5.9226862,5.2732861 11.701082,10.69629"
|
||||
id="path3777" />
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
@ -46,8 +46,8 @@ class QgsFilterLineEdit : QLineEdit
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent* e );
|
||||
void mouseMoveEvent( QMouseEvent* e );
|
||||
void focusInEvent( QFocusEvent* e );
|
||||
void resizeEvent( QResizeEvent* e );
|
||||
void changeEvent( QEvent* e );
|
||||
void paintEvent( QPaintEvent* e );
|
||||
void leaveEvent( QEvent* e );
|
||||
};
|
||||
|
@ -21,31 +21,30 @@
|
||||
#include <QToolButton>
|
||||
#include <QStyle>
|
||||
#include <QFocusEvent>
|
||||
#include <QPainter>
|
||||
|
||||
QgsFilterLineEdit::QgsFilterLineEdit( QWidget* parent, const QString& nullValue )
|
||||
: QLineEdit( parent )
|
||||
, mNullValue( nullValue )
|
||||
, mFocusInEvent( false )
|
||||
, mClearHover( false )
|
||||
{
|
||||
btnClear = new QToolButton( this );
|
||||
btnClear->setIcon( QgsApplication::getThemeIcon( "/mIconClear.svg" ) );
|
||||
btnClear->setCursor( Qt::ArrowCursor );
|
||||
btnClear->setFocusPolicy( Qt::NoFocus );
|
||||
btnClear->setStyleSheet( "QToolButton { border: none; padding: 0px; }" );
|
||||
btnClear->hide();
|
||||
// need mouse tracking to handle cursor changes
|
||||
setMouseTracking( true );
|
||||
|
||||
QIcon clearIcon = QgsApplication::getThemeIcon( "/mIconClearText.svg" );
|
||||
mClearIconSize = QSize( 16, 16 );
|
||||
mClearIconPixmap = clearIcon.pixmap( mClearIconSize );
|
||||
QIcon hoverIcon = QgsApplication::getThemeIcon( "/mIconClearTextHover.svg" );
|
||||
mClearHoverPixmap = hoverIcon.pixmap( mClearIconSize );
|
||||
|
||||
connect( btnClear, SIGNAL( clicked() ), this, SLOT( clear() ) );
|
||||
connect( btnClear, SIGNAL( clicked() ), this, SIGNAL( cleared() ) );
|
||||
connect( this, SIGNAL( textChanged( const QString& ) ), this,
|
||||
SLOT( onTextChanged( const QString& ) ) );
|
||||
|
||||
int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
|
||||
mStyleSheet = QString( "QLineEdit { padding-right: %1px; } " )
|
||||
.arg( btnClear->sizeHint().width() + frameWidth + 1 );
|
||||
|
||||
QSize msz = minimumSizeHint();
|
||||
setMinimumSize( qMax( msz.width(), btnClear->sizeHint().height() + frameWidth * 2 + 2 ),
|
||||
qMax( msz.height(), btnClear->sizeHint().height() + frameWidth * 2 + 2 ) );
|
||||
setMinimumSize( qMax( msz.width(), mClearIconSize.width() + frameWidth * 2 + 2 ),
|
||||
qMax( msz.height(), mClearIconSize.height() + frameWidth * 2 + 2 ) );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::mousePressEvent( QMouseEvent* e )
|
||||
@ -54,6 +53,32 @@ void QgsFilterLineEdit::mousePressEvent( QMouseEvent* e )
|
||||
QLineEdit::mousePressEvent( e );
|
||||
else
|
||||
mFocusInEvent = false;
|
||||
|
||||
if ( shouldShowClear() && clearRect().contains( e->pos() ) )
|
||||
{
|
||||
clear();
|
||||
emit cleared();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::focusInEvent( QFocusEvent* e )
|
||||
@ -66,37 +91,39 @@ void QgsFilterLineEdit::focusInEvent( QFocusEvent* e )
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::resizeEvent( QResizeEvent * )
|
||||
{
|
||||
QSize sz = btnClear->sizeHint();
|
||||
int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
|
||||
btnClear->move( rect().right() - frameWidth - sz.width(),
|
||||
( rect().bottom() + 1 - sz.height() ) / 2 );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::clear()
|
||||
{
|
||||
setText( mNullValue );
|
||||
setModified( true );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::changeEvent( QEvent *e )
|
||||
{
|
||||
QLineEdit::changeEvent( e );
|
||||
btnClear->setVisible( isEnabled() && !isReadOnly() && !isNull() );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::paintEvent( QPaintEvent* e )
|
||||
{
|
||||
QLineEdit::paintEvent( e );
|
||||
btnClear->setVisible( isEnabled() && !isReadOnly() && !isNull() );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::leaveEvent( QEvent* e )
|
||||
{
|
||||
if ( mClearHover )
|
||||
{
|
||||
mClearHover = false;
|
||||
update();
|
||||
}
|
||||
|
||||
QLineEdit::leaveEvent( e );
|
||||
}
|
||||
|
||||
void QgsFilterLineEdit::onTextChanged( const QString &text )
|
||||
{
|
||||
btnClear->setVisible( isEnabled() && !isReadOnly() && !isNull() );
|
||||
|
||||
if ( isNull() )
|
||||
{
|
||||
setStyleSheet( QString( "QLineEdit { font: italic; color: gray; } %1" ).arg( mStyleSheet ) );
|
||||
@ -108,3 +135,17 @@ void QgsFilterLineEdit::onTextChanged( const QString &text )
|
||||
emit valueChanged( text );
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsFilterLineEdit::shouldShowClear() const
|
||||
{
|
||||
return isEnabled() && !isReadOnly() && !isNull();
|
||||
}
|
||||
|
||||
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() );
|
||||
}
|
||||
|
@ -70,10 +70,10 @@ class GUI_EXPORT QgsFilterLineEdit : public QLineEdit
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent* e ) override;
|
||||
void mouseMoveEvent( QMouseEvent* e ) override;
|
||||
void focusInEvent( QFocusEvent* e ) override;
|
||||
void resizeEvent( QResizeEvent* e ) override;
|
||||
void changeEvent( QEvent* e ) override;
|
||||
void paintEvent( QPaintEvent* e ) override;
|
||||
void leaveEvent( QEvent* e ) override;
|
||||
|
||||
private slots:
|
||||
void clear();
|
||||
@ -81,9 +81,18 @@ class GUI_EXPORT QgsFilterLineEdit : public QLineEdit
|
||||
|
||||
private:
|
||||
QString mNullValue;
|
||||
QToolButton *btnClear;
|
||||
QString mStyleSheet;
|
||||
bool mFocusInEvent;
|
||||
bool mClearHover;
|
||||
|
||||
QSize mClearIconSize;
|
||||
QPixmap mClearIconPixmap;
|
||||
QPixmap mClearHoverPixmap;
|
||||
|
||||
//! Returns true if clear button should be shown
|
||||
bool shouldShowClear() const;
|
||||
|
||||
QRect clearRect() const;
|
||||
};
|
||||
|
||||
#endif // QGSFILTERLINEEDIT_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user