Adding user button and reset button support to QxtLineEdit
This commit is contained in:
parent
4252dbbe35
commit
9583ac2c72
|
@ -23,9 +23,13 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
#include "qxtlineedit.h"
|
||||
#include "qxtmetaobject.h"
|
||||
#include <QStyleOptionFrameV2>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QToolButton>
|
||||
#include <QActionEvent>
|
||||
#include <QApplication>
|
||||
|
||||
// copied from qlineedit.cpp:
|
||||
#define vMargin 1
|
||||
|
@ -33,16 +37,182 @@
|
|||
|
||||
class QxtLineEditPrivate : public QxtPrivate<QxtLineEdit>
|
||||
{
|
||||
QXT_DECLARE_PUBLIC(QxtLineEdit);
|
||||
public:
|
||||
QxtLineEditPrivate() : userBtn(0), resetBtn(0), btnPosn(QxtLineEdit::NoButton), resetMode(QxtLineEdit::HideResetButton) {}
|
||||
|
||||
QString sampleText;
|
||||
QToolButton * userBtn; // Internal "user" button
|
||||
QToolButton * resetBtn; // Internal "reset" button
|
||||
QxtLineEdit::ButtonPosition btnPosn; // Current posn of user button
|
||||
QxtLineEdit::ResetButtonMode resetMode; // Current mode of reset button
|
||||
|
||||
/*! \internal
|
||||
* Constructs the user and reset buttons as well as setting the initial
|
||||
* defaults for each. Buttons are initially hidden.
|
||||
* This MUST be called by every QxtLineEdit constructor AFTER
|
||||
* the standard QXT_INIT_PRIVATE().
|
||||
*/
|
||||
void initButtons()
|
||||
{
|
||||
QXT_P(QxtLineEdit);
|
||||
// Construct the user button (hidden)
|
||||
userBtn = new QToolButton(&p);
|
||||
userBtn->setVisible(false);
|
||||
userBtn->setCursor(Qt::ArrowCursor);
|
||||
userBtn->setFocusPolicy(Qt::NoFocus);
|
||||
userBtn->setIcon(QIcon(":/icons/search.png"));
|
||||
QObject::connect(userBtn, SIGNAL(clicked(bool)), &p,
|
||||
SIGNAL(buttonClicked()));
|
||||
// Construct the reset button (also hidden)
|
||||
resetBtn = new QToolButton(&p);
|
||||
resetBtn->setVisible(false);
|
||||
// resetBtn->setBackgroundRole(QPalette::Base);
|
||||
resetBtn->setAutoRaise(true);
|
||||
resetBtn->setCursor(Qt::ArrowCursor);
|
||||
resetBtn->setFocusPolicy(Qt::NoFocus);
|
||||
// resetBtn->setForegroundRole(QPalette::Text);
|
||||
resetBtn->setIcon(QIcon(":/icons/reset.png"));
|
||||
QObject::connect(resetBtn, SIGNAL(clicked(bool)), &p, SLOT(clear()));
|
||||
// Connect a handler for adjusting the reset button visibilty
|
||||
p.connect(&p, SIGNAL(textChanged(const QString &)),
|
||||
SLOT(_qxt_textChanged(const QString &)));
|
||||
}
|
||||
/*! \internal
|
||||
* Updates the button's geometry according to the specified position. This
|
||||
* assures it is displayed in the proper location.
|
||||
*/
|
||||
void updateButtonGeom()
|
||||
{
|
||||
if(btnPosn == QxtLineEdit::NoButton &&
|
||||
resetMode == QxtLineEdit::HideResetButton)
|
||||
return;
|
||||
QXT_P(QxtLineEdit);
|
||||
// Compute the pixel-size (unadjusted) for button area
|
||||
int pixUser = std::min(std::max(userBtn->sizeHint().width(),
|
||||
resetBtn->sizeHint().width()),
|
||||
p.testAttribute(Qt::WA_Resized) ? p.height() :
|
||||
p.sizeHint().height());
|
||||
int pixReset = pixUser - 4; // Inside
|
||||
// Get the on-screen rectangle (physical geometry) and adjust if needed
|
||||
QRect rUser = p.rect();
|
||||
QRect rReset = rUser.adjusted(2, 2, -2, -2);
|
||||
if(!(btnPosn & QxtLineEdit::PositionOuter)){
|
||||
// Use inside voices
|
||||
rUser = rReset;
|
||||
pixUser = pixReset;
|
||||
}
|
||||
// Actually set the user button's geometry
|
||||
if(btnPosn != QxtLineEdit::NoButton){
|
||||
if(btnPosn & QxtLineEdit::PositionLeft){
|
||||
userBtn->setGeometry(rUser.left(), rUser.top(), pixUser,
|
||||
rUser.height());
|
||||
rReset.adjust(pixUser, 0, 0, 0);
|
||||
}
|
||||
else{
|
||||
userBtn->setGeometry(rUser.right()-pixUser+1, rUser.top(),
|
||||
pixUser, rUser.height());
|
||||
rReset.adjust(0, 0, -pixUser, 0);
|
||||
}
|
||||
}
|
||||
// And that of the reset button
|
||||
if(resetMode != QxtLineEdit::HideResetButton){
|
||||
if(QApplication::isRightToLeft())
|
||||
resetBtn->setGeometry(rReset.left(), rReset.top(), pixReset,
|
||||
rReset.height());
|
||||
else
|
||||
resetBtn->setGeometry(rReset.right()-pixReset+1, rReset.top(),
|
||||
pixReset, rReset.height());
|
||||
}
|
||||
}
|
||||
/*! \internal
|
||||
* Adjusts sizes & visibility for changes in button settings.
|
||||
* \param posn New user button position
|
||||
* \param mode New reset button mode
|
||||
*/
|
||||
void adjustButtons(QxtLineEdit::ButtonPosition posn,
|
||||
QxtLineEdit::ResetButtonMode mode)
|
||||
{
|
||||
QXT_P(QxtLineEdit);
|
||||
// Determine visibility
|
||||
bool showReset = (mode == QxtLineEdit::ShowResetAlways ||
|
||||
(mode == QxtLineEdit::ShowResetNotEmpty &&
|
||||
!qxt_p().text().isEmpty()));
|
||||
bool showUser = (posn != QxtLineEdit::NoButton);
|
||||
// Get pixels to reserve for button size
|
||||
int pix = std::min(std::max(userBtn->sizeHint().width(),
|
||||
resetBtn->sizeHint().width()),
|
||||
p.testAttribute(Qt::WA_Resized) ? p.height() :
|
||||
p.sizeHint().height());
|
||||
// Compute horizontal space needed for reset button
|
||||
int rbl = 0, rbr = 0;
|
||||
if((resetMode = mode) != QxtLineEdit::HideResetButton){
|
||||
if(QApplication::isRightToLeft())
|
||||
rbl = pix; // Reset is on the left
|
||||
else
|
||||
rbr = pix; // Reset is on the right
|
||||
}
|
||||
// Handle user button space requirements (and reset along the way)
|
||||
if((btnPosn = posn) == QxtLineEdit::NoButton){
|
||||
// Hide it and unreserve all space
|
||||
p.setContentsMargins(0, 0, 0, 0);
|
||||
p.setTextMargins(rbl, 0, rbr, 0);
|
||||
}
|
||||
else{
|
||||
// Handle automatic positioning according to locale/language
|
||||
if(posn & QxtLineEdit::PositionAuto){
|
||||
if(QApplication::isRightToLeft())
|
||||
btnPosn = static_cast<QxtLineEdit::ButtonPosition>(
|
||||
posn | QxtLineEdit::PositionLeft);
|
||||
else
|
||||
btnPosn = static_cast<QxtLineEdit::ButtonPosition>(
|
||||
posn & ~QxtLineEdit::PositionLeft);
|
||||
}
|
||||
// Reserve space appropriately
|
||||
if(btnPosn & QxtLineEdit::PositionOuter){
|
||||
// Outside -- text margins ziltch and contents set +2 for frame
|
||||
p.setTextMargins(rbl, 0, rbr, 0);
|
||||
if(btnPosn & QxtLineEdit::PositionLeft)
|
||||
p.setContentsMargins(pix+2, 0, 0, 0);
|
||||
else
|
||||
p.setContentsMargins(0, 0, pix+2, 0);
|
||||
}
|
||||
else{
|
||||
// Inside -- contents ziltch and text margins set
|
||||
p.setContentsMargins(0, 0, 0, 0);
|
||||
if(btnPosn & QxtLineEdit::PositionLeft)
|
||||
p.setTextMargins(pix+rbl, 0, rbr, 0);
|
||||
else
|
||||
p.setTextMargins(rbl, 0, pix+rbr, 0);
|
||||
}
|
||||
}
|
||||
// Update button geometry & redraw everything
|
||||
updateButtonGeom();
|
||||
if(showUser != userBtn->isVisible())
|
||||
userBtn->setVisible(showUser);
|
||||
if(showReset != resetBtn->isVisible())
|
||||
resetBtn->setVisible(showReset);
|
||||
}
|
||||
/*! \internal
|
||||
* Adjusts visibility for reset button when text changes.
|
||||
* \param text New text content
|
||||
*/
|
||||
void adjustResetButton(const QString &text)
|
||||
{
|
||||
if(resetMode == QxtLineEdit::ShowResetNotEmpty){
|
||||
if(resetBtn->isVisible() != !text.isEmpty())
|
||||
resetBtn->setVisible(!text.isEmpty());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
\class QxtLineEdit
|
||||
\inmodule QxtGui
|
||||
\brief The QxtLineEdit widget is a line edit that is able to show a sample text.
|
||||
\brief The QxtLineEdit widget is a line edit that is able to show a sample text and embedded buttons.
|
||||
|
||||
QxtLineEdit is a line edit that is able to show a sample text.
|
||||
QxtLineEdit is a line edit that is able to show a sample text, a user
|
||||
configurable button and/or a reset button.
|
||||
The sample text is shown when the line edit is empty and has
|
||||
no focus.
|
||||
|
||||
|
@ -54,6 +224,8 @@ public:
|
|||
*/
|
||||
QxtLineEdit::QxtLineEdit(QWidget* parent) : QLineEdit(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtLineEdit);
|
||||
qxt_d().initButtons();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -61,6 +233,8 @@ QxtLineEdit::QxtLineEdit(QWidget* parent) : QLineEdit(parent)
|
|||
*/
|
||||
QxtLineEdit::QxtLineEdit(const QString& text, QWidget* parent) : QLineEdit(text, parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtLineEdit);
|
||||
qxt_d().initButtons();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -72,7 +246,7 @@ QxtLineEdit::~QxtLineEdit()
|
|||
|
||||
/*!
|
||||
\property QxtLineEdit::sampleText
|
||||
\brief the sample text of the line edit
|
||||
\brief The sample text of the line edit
|
||||
|
||||
The sample text is shown when the line edit is empty and has
|
||||
no focus.
|
||||
|
@ -92,6 +266,100 @@ void QxtLineEdit::setSampleText(const QString& text)
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QxtLineEdit::buttonAutoRaise
|
||||
\brief The \a autoRaise property of the embedded user button
|
||||
|
||||
This property mirrors the property of the embedded QToolButton and
|
||||
causes the button to appear flat until the mouse hovers over it.
|
||||
*/
|
||||
bool QxtLineEdit::buttonAutoRaise() const
|
||||
{
|
||||
return qxt_d().userBtn->autoRaise();
|
||||
}
|
||||
|
||||
void QxtLineEdit::setButtonAutoRaise(bool f)
|
||||
{
|
||||
qxt_d().userBtn->setAutoRaise(f);
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QxtLineEdit::buttonIcon
|
||||
\brief The \a icon property of the embedded user button
|
||||
|
||||
This property mirrors the property of the embedded QToolButton. The
|
||||
default icon is a stock search pixmap which will be obtained from
|
||||
the system style when available.
|
||||
*/
|
||||
QIcon QxtLineEdit::buttonIcon() const
|
||||
{
|
||||
return qxt_d().userBtn->icon();
|
||||
}
|
||||
|
||||
void QxtLineEdit::setButtonIcon(const QIcon &icon)
|
||||
{
|
||||
qxt_d().userBtn->setIcon(icon);
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QxtLineEdit::buttonPosition
|
||||
\brief The \a position of the embedded user button
|
||||
|
||||
This property controls where the button is positioned within the
|
||||
line edit. The default is \a NoButton.
|
||||
|
||||
\sa QxtLineEdit::ButtonPosition
|
||||
*/
|
||||
QxtLineEdit::ButtonPosition QxtLineEdit::buttonPosition() const
|
||||
{
|
||||
ButtonPosition result = qxt_d().btnPosn;
|
||||
if(result & PositionAuto)
|
||||
// Hide real direction when auto
|
||||
result = static_cast<ButtonPosition>(result & ~PositionLeft);
|
||||
return result;
|
||||
}
|
||||
|
||||
void QxtLineEdit::setButtonPosition(ButtonPosition posn)
|
||||
{
|
||||
if(posn == qxt_d().btnPosn)
|
||||
return;
|
||||
qxt_d().adjustButtons(posn, qxt_d().resetMode);
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QxtLineEdit::resetButtonMode
|
||||
\brief The \a mode of the embedded reset button
|
||||
|
||||
This property controls when the reset button is visible.
|
||||
The default is \a HideResetButton.
|
||||
|
||||
\sa QxtLineEdit::ResetButtonMode
|
||||
*/
|
||||
QxtLineEdit::ResetButtonMode QxtLineEdit::resetButtonMode() const
|
||||
{
|
||||
return qxt_d().resetMode;
|
||||
}
|
||||
|
||||
void QxtLineEdit::setResetButtonMode(ResetButtonMode mode)
|
||||
{
|
||||
if(mode == qxt_d().resetMode)
|
||||
return;
|
||||
qxt_d().adjustButtons(qxt_d().btnPosn, mode);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Provides access to the embedded user button object
|
||||
|
||||
This method returns a pointer to the embedded user button. It
|
||||
is never NULL. The QToolButton is owned by the line edit and
|
||||
must not be deleted.
|
||||
*/
|
||||
QToolButton* QxtLineEdit::button() const
|
||||
{
|
||||
return qxt_d().userBtn;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
|
@ -119,3 +387,69 @@ void QxtLineEdit::paintEvent(QPaintEvent* event)
|
|||
style()->drawItemText(&painter, r, alignment(), pal, false, qxt_d().sampleText, QPalette::Text);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtLineEdit::actionEvent(QActionEvent *e)
|
||||
{
|
||||
// Transfer action events to the button since that's where they typically
|
||||
// belong. All others are passed on to the base class implementation.
|
||||
switch(e->type()){
|
||||
case QEvent::ActionAdded:
|
||||
qxt_d().userBtn->insertAction(e->before(), e->action());
|
||||
break;
|
||||
case QEvent::ActionRemoved:
|
||||
qxt_d().userBtn->removeAction(e->action());
|
||||
break;
|
||||
default:
|
||||
QLineEdit::actionEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtLineEdit::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
// Adjust the button's geometry when resizing events occur so it doesn't
|
||||
// end up out of place. The base implementation is always used as well.
|
||||
qxt_d().updateButtonGeom();
|
||||
QLineEdit::resizeEvent(e);
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
* Forwards signal to private class
|
||||
*/
|
||||
void QxtLineEdit::_qxt_textChanged(const QString &text)
|
||||
{
|
||||
qxt_d().adjustResetButton(text);
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QxtLineEdit::ButtonPosition
|
||||
\brief This enum controls the position of an embedded button.
|
||||
|
||||
\value NoButton The button is not displayed (default)
|
||||
\value InnerRight Button is shown inside the frame on the right-hand side
|
||||
\value InnerLeft Button is shown inside the frame on the left-hand side
|
||||
\value InnerAuto Button is shown inside the frame, side determined by locale
|
||||
\value OuterRight Button is shown outside the frame on the right-hand side
|
||||
\value OuterLeft Button is shown outside the frame on the left-hand side
|
||||
\value OuterAuto Button is shown outside the frame, side determined by locale
|
||||
*/
|
||||
/*!
|
||||
\enum QxtLineEdit::ResetButtonMode
|
||||
\brief This enum controls the display of a reset button.
|
||||
|
||||
\value HideResetButton The button is not displayed (default)
|
||||
\value ShowResetNotEmpty The reset button appears only when the line-edit is not empty
|
||||
\value ShowResetAlways The reset button is always visible
|
||||
*/
|
||||
/*!
|
||||
\fn buttonClicked()
|
||||
|
||||
This signal is emitted when the user button is clicked.
|
||||
|
||||
\sa QToolButton::clicked(bool)
|
||||
*/
|
||||
|
|
|
@ -26,27 +26,73 @@
|
|||
#define QXTLINEEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QIcon>
|
||||
#include <qxtglobal.h>
|
||||
|
||||
class QxtLineEditPrivate;
|
||||
class QActionEvent;
|
||||
class QResizeEvent;
|
||||
class QToolButton;
|
||||
|
||||
class QXT_GUI_EXPORT QxtLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(ButtonPosition)
|
||||
Q_ENUMS(ResetButtonMode)
|
||||
Q_PROPERTY(bool buttonAutoRaise READ buttonAutoRaise WRITE setButtonAutoRaise)
|
||||
Q_PROPERTY(QIcon buttonIcon READ buttonIcon WRITE setButtonIcon)
|
||||
Q_PROPERTY(ButtonPosition buttonPosition READ buttonPosition WRITE setButtonPosition)
|
||||
Q_PROPERTY(ResetButtonMode resetButtonMode READ resetButtonMode WRITE setResetButtonMode)
|
||||
Q_PROPERTY(QString sampleText READ sampleText WRITE setSampleText)
|
||||
|
||||
public:
|
||||
enum ButtonPosition
|
||||
{
|
||||
NoButton,
|
||||
PositionLeft = 0x1,
|
||||
PositionAuto = 0x2,
|
||||
PositionOuter = 0x4,
|
||||
InnerRight = 0x10,
|
||||
InnerLeft = 0x11,
|
||||
InnerAuto = 0x12,
|
||||
OuterRight = 0x14,
|
||||
OuterLeft = 0x15,
|
||||
OuterAuto = 0x16
|
||||
};
|
||||
enum ResetButtonMode
|
||||
{
|
||||
HideResetButton,
|
||||
ShowResetNotEmpty,
|
||||
ShowResetAlways,
|
||||
};
|
||||
explicit QxtLineEdit(QWidget* parent = 0);
|
||||
QxtLineEdit(const QString& text, QWidget* parent = 0);
|
||||
virtual ~QxtLineEdit();
|
||||
|
||||
QString sampleText() const;
|
||||
bool buttonAutoRaise() const;
|
||||
void setButtonAutoRaise(bool);
|
||||
QIcon buttonIcon() const;
|
||||
void setButtonIcon(const QIcon &);
|
||||
ButtonPosition buttonPosition() const;
|
||||
void setButtonPosition(ButtonPosition);
|
||||
ResetButtonMode resetButtonMode() const;
|
||||
void setResetButtonMode(ResetButtonMode);
|
||||
QToolButton *button() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setSampleText(const QString& text);
|
||||
|
||||
Q_SIGNALS:
|
||||
void buttonClicked();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event);
|
||||
virtual void actionEvent(QActionEvent *);
|
||||
virtual void resizeEvent(QResizeEvent *);
|
||||
|
||||
private Q_SLOTS:
|
||||
void _qxt_textChanged(const QString &text);
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtLineEdit)
|
||||
|
|
|
@ -247,5 +247,7 @@
|
|||
<file alias="flags/ZA.png">resources/flags/ZA.png</file>
|
||||
<file alias="flags/ZM.png">resources/flags/ZM.png</file>
|
||||
<file alias="flags/ZW.png">resources/flags/ZW.png</file>
|
||||
<file alias="icons/search.png">resources/icons/search.png</file>
|
||||
<file alias="icons/reset.png">resources/icons/reset.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
src/gui/resources/icons/reset.png
Normal file
BIN
src/gui/resources/icons/reset.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 347 B |
BIN
src/gui/resources/icons/search.png
Normal file
BIN
src/gui/resources/icons/search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Loading…
Reference in New Issue
Block a user