goldendict-ng/extlineedit.cc
2022-02-03 17:50:47 +08:00

192 lines
4.7 KiB
C++

/* This file is (c) 2012 Tvangeste <i.4m.l33t@yandex.ru>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include "extlineedit.hh"
#include <QPainter>
#include <QPropertyAnimation>
ExtLineEdit::ExtLineEdit(QWidget *parent) :
QLineEdit(parent)
{
for (int i = 0; i < 2; ++i) {
iconButtons[i] = new IconButton(this);
iconButtons[i]->installEventFilter(this);
iconButtons[i]->hide();
iconButtons[i]->setAutoHide(false);
iconEnabled[i] = false;
}
ensurePolished();
updateMargins();
connect(iconButtons[Left], SIGNAL(clicked()), this, SLOT(iconClicked()));
connect(iconButtons[Right], SIGNAL(clicked()), this, SLOT(iconClicked()));
connect(this, SIGNAL( textChanged( QString ) ), this, SLOT( updateButtons( QString ) ) );
}
ExtLineEdit::~ExtLineEdit()
{
}
void ExtLineEdit::setButtonVisible(Side side, bool visible)
{
iconButtons[side]->setVisible(visible);
iconEnabled[side] = visible;
updateMargins();
}
bool ExtLineEdit::isButtonVisible(Side side) const
{
return iconEnabled[side];
}
void ExtLineEdit::setButtonAutoHide(Side side, bool autohide)
{
iconButtons[side]->setAutoHide(autohide);
if (autohide)
{
iconButtons[side]->setOpacity( text().isEmpty() ? 0.0 : 1.0 );
}
else
{
iconButtons[side]->setOpacity( 1.0 );
}
}
void ExtLineEdit::updateButtons(QString text)
{
if ( oldText.isEmpty() || text.isEmpty() ) {
for (int i = 0; i < 2; ++i) {
if ( iconButtons[i]->isAutoHide() )
{
iconButtons[i]->animate( !text.isEmpty() );
}
}
oldText = text;
}
}
void ExtLineEdit::iconClicked()
{
IconButton * button = qobject_cast<IconButton *>( sender() );
int index = -1;
for (int i = 0; i < 2; ++i)
if (iconButtons[i] == button)
index = i;
if (index == -1)
return;
if (index == Left)
emit leftButtonClicked();
else if (index == Right)
emit rightButtonClicked();
}
void ExtLineEdit::updateMargins()
{
bool leftToRight = (layoutDirection() == Qt::LeftToRight);
Side realLeft = (leftToRight ? Left : Right);
Side realRight = (leftToRight ? Right : Left);
int widgetHeight=height();
int leftMargin = widgetHeight + 8;
int rightMargin = widgetHeight + 8;
setTextMargins(
(iconEnabled[realLeft] ? leftMargin : 0), 1,
(iconEnabled[realRight] ? rightMargin : 0), 1);
}
void ExtLineEdit::updateButtonPositions()
{
QRect contentRect = rect();
for (int i = 0; i < 2; ++i) {
Side iconPos = (Side)i;
if (layoutDirection() == Qt::RightToLeft)
iconPos = (iconPos == Left ? Right : Left);
if (iconPos == ExtLineEdit::Right) {
QMargins qm=textMargins();
const int iconoffset = qm.right() + 4;
iconButtons[i]->setGeometry(contentRect.adjusted(width() - iconoffset, 0, 0, 0));
} else {
QMargins qm=textMargins();
const int iconoffset = qm.left() + 4;
iconButtons[i]->setGeometry(contentRect.adjusted(0, 0, -width() + iconoffset, 0));
}
}
}
void ExtLineEdit::resizeEvent(QResizeEvent *)
{
updateButtonPositions();
}
void ExtLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap)
{
iconButtons[side]->setPixmap(buttonPixmap);
updateMargins();
updateButtonPositions();
update();
}
QPixmap ExtLineEdit::buttonPixmap(Side side) const
{
return pixmaps[side];
}
void ExtLineEdit::setButtonToolTip(Side side, const QString &tip)
{
iconButtons[side]->setToolTip(tip);
}
void ExtLineEdit::setButtonFocusPolicy(Side side, Qt::FocusPolicy policy)
{
iconButtons[side]->setFocusPolicy(policy);
}
IconButton::IconButton(QWidget *parent)
: QAbstractButton(parent)
{
setCursor(Qt::ArrowCursor);
setFocusPolicy(Qt::NoFocus);
setFocusProxy(parent);
}
void IconButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
painter.setRenderHint(QPainter::RenderHint::TextAntialiasing);
painter.setRenderHint(QPainter::RenderHint::SmoothPixmapTransform);
painter.setRenderHint(QPainter::RenderHint::LosslessImageRendering);
QRect pixmapRect = QRect(0, 0, height(), height());
pixmapRect.moveCenter(rect().center());
if (m_autohide)
{
painter.setOpacity(m_opacity);
}
painter.drawPixmap(pixmapRect, m_pixmap);
}
void IconButton::animate(bool visible)
{
QPropertyAnimation *animation = new QPropertyAnimation(this, "opacity");
animation->setDuration(250);
if (visible)
{
animation->setEndValue(1.0);
}
else
{
animation->setEndValue(0.0);
}
animation->start(QAbstractAnimation::DeleteWhenStopped);
}