QLineEdit: Fix icons being too small on a High DPI screen without scaling.

Remove the hardcoded size 16 from QLineEditIconButton. Replace
QLineEditPrivate::iconSize() by QLineEditPrivate::sideWidgetParameters()
returning a struct SideWidgetParameters containing icon size, widget size and
margins. The 32x32 icon will then be used on a High DPI screen without scaling.

Task-number: QTBUG-49374
Change-Id: I23c4a0cd078a58581c940aacfa65a3ad493c12dc
Reviewed-by: Alessandro Portale <alessandro.portale@theqtcompany.com>
This commit is contained in:
Friedemann Kleint 2016-03-30 13:57:22 +02:00 committed by Friedemann Kleint
parent 678e427948
commit 07dd6dbaee
3 changed files with 52 additions and 22 deletions

View File

@ -2176,7 +2176,6 @@ void QLineEdit::changeEvent(QEvent *ev)
d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
d->control->setPasswordMaskDelay(style()->styleHint(QStyle::SH_LineEdit_PasswordMaskDelay, &opt, this));
}
d->m_iconSize = QSize();
update();
break;
case QEvent::LayoutDirectionChange:

View File

@ -314,6 +314,12 @@ QLineEditIconButton::QLineEditIconButton(QWidget *parent)
setFocusPolicy(Qt::NoFocus);
}
QLineEditPrivate *QLineEditIconButton::lineEditPrivate() const
{
QLineEdit *le = qobject_cast<QLineEdit *>(parentWidget());
return le ? static_cast<QLineEditPrivate *>(qt_widget_private(le)) : Q_NULLPTR;
}
void QLineEditIconButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
@ -325,7 +331,9 @@ void QLineEditIconButton::paintEvent(QPaintEvent *)
QIcon::Mode state = QIcon::Disabled;
if (isEnabled())
state = isDown() ? QIcon::Selected : QIcon::Normal;
const QSize iconSize(IconButtonSize, IconButtonSize);
const QLineEditPrivate *lep = lineEditPrivate();
const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16;
const QSize iconSize(iconWidth, iconWidth);
const QPixmap iconPixmap = icon().pixmap(window, iconSize, state, QIcon::Off);
QRect pixmapRect = QRect(QPoint(0, 0), iconSize);
pixmapRect.moveCenter(rect().center());
@ -340,8 +348,8 @@ void QLineEditIconButton::actionEvent(QActionEvent *e)
const QAction *action = e->action();
if (isVisibleTo(parentWidget()) != action->isVisible()) {
setVisible(action->isVisible());
if (QLineEdit *le = qobject_cast<QLineEdit *>(parentWidget()))
static_cast<QLineEditPrivate *>(qt_widget_private(le))->positionSideWidgets();
if (QLineEditPrivate *lep = lineEditPrivate())
lep->positionSideWidgets();
}
}
break;
@ -407,11 +415,15 @@ void QLineEditPrivate::_q_clearButtonClicked()
}
}
QSize QLineEditPrivate::iconSize() const
QLineEditPrivate::SideWidgetParameters QLineEditPrivate::sideWidgetParameters() const
{
if (!m_iconSize.isValid()) // This might require style-specific handling (pixel metric).
m_iconSize = QSize(QLineEditIconButton::IconButtonSize + 6, QLineEditIconButton::IconButtonSize + 2);
return m_iconSize;
Q_Q(const QLineEdit);
SideWidgetParameters result;
result.iconSize = q->height() < 34 ? 16 : 32;
result.margin = result.iconSize / 4;
result.widgetWidth = result.iconSize + 6;
result.widgetHeight = result.iconSize + 2;
return result;
}
QIcon QLineEditPrivate::clearButtonIcon() const
@ -437,15 +449,16 @@ void QLineEditPrivate::positionSideWidgets()
Q_Q(QLineEdit);
if (hasSideWidgets()) {
const QRect contentRect = q->rect();
const QSize iconSize = QLineEditPrivate::iconSize();
const int delta = QLineEditIconButton::IconMargin + iconSize.width();
QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize);
const SideWidgetParameters p = sideWidgetParameters();
const int delta = p.margin + p.widgetWidth;
QRect widgetGeometry(QPoint(p.margin, (contentRect.height() - p.widgetHeight) / 2),
QSize(p.widgetWidth, p.widgetHeight));
foreach (const SideWidgetEntry &e, leftSideWidgetList()) {
e.widget->setGeometry(widgetGeometry);
if (e.action->isVisible())
widgetGeometry.moveLeft(widgetGeometry.left() + delta);
}
widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin);
widgetGeometry.moveLeft(contentRect.width() - p.widgetWidth - p.margin);
foreach (const SideWidgetEntry &e, rightSideWidgetList()) {
e.widget->setGeometry(widgetGeometry);
if (e.action->isVisible())

View File

@ -65,6 +65,8 @@
QT_BEGIN_NAMESPACE
class QLineEditPrivate;
// QLineEditIconButton: This is a simple helper class that represents clickable icons that fade in with text
class Q_AUTOTEST_EXPORT QLineEditIconButton : public QToolButton
@ -72,8 +74,6 @@ class Q_AUTOTEST_EXPORT QLineEditIconButton : public QToolButton
Q_OBJECT
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
public:
enum { IconMargin = 4, IconButtonSize = 16 };
explicit QLineEditIconButton(QWidget *parent = 0);
qreal opacity() const { return m_opacity; }
@ -93,6 +93,7 @@ private:
#ifndef QT_NO_ANIMATION
void startOpacityAnimation(qreal endValue);
#endif
QLineEditPrivate *lineEditPrivate() const;
qreal m_opacity;
};
@ -116,6 +117,13 @@ public:
};
typedef QVector<SideWidgetEntry> SideWidgetEntryList;
struct SideWidgetParameters {
int iconSize;
int widgetWidth;
int widgetHeight;
int margin;
};
QLineEditPrivate()
: control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
@ -206,7 +214,7 @@ public:
QWidget *addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition, int flags = 0);
void removeAction(QAction *action);
QSize iconSize() const;
SideWidgetParameters sideWidgetParameters() const;
QIcon clearButtonIcon() const;
void setClearButtonEnabled(bool enabled);
void positionSideWidgets();
@ -227,7 +235,6 @@ private:
SideWidgetEntryList leadingSideWidgets;
SideWidgetEntryList trailingSideWidgets;
int lastTextSize;
mutable QSize m_iconSize;
};
Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE);
@ -238,18 +245,29 @@ static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e)
inline int QLineEditPrivate::effectiveLeftTextMargin() const
{
return leftTextMargin + (QLineEditIconButton::IconMargin + iconSize().width())
* int(std::count_if(leftSideWidgetList().constBegin(), leftSideWidgetList().constEnd(),
isSideWidgetVisible));
int result = leftTextMargin;
if (!leftSideWidgetList().isEmpty()) {
const SideWidgetParameters p = sideWidgetParameters();
result += (p.margin + p.widgetWidth)
* int(std::count_if(leftSideWidgetList().constBegin(), leftSideWidgetList().constEnd(),
isSideWidgetVisible));
}
return result;
}
inline int QLineEditPrivate::effectiveRightTextMargin() const
{
return rightTextMargin + (QLineEditIconButton::IconMargin + iconSize().width())
* int(std::count_if(rightSideWidgetList().constBegin(), rightSideWidgetList().constEnd(),
isSideWidgetVisible));
int result = rightTextMargin;
if (!rightSideWidgetList().isEmpty()) {
const SideWidgetParameters p = sideWidgetParameters();
result += (p.margin + p.widgetWidth)
* int(std::count_if(rightSideWidgetList().constBegin(), rightSideWidgetList().constEnd(),
isSideWidgetVisible));
}
return result;
}
#endif // QT_NO_LINEEDIT
QT_END_NAMESPACE