From 07dd6dbaee5bdcbeebc54f04dccc45ad4778eab4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 30 Mar 2016 13:57:22 +0200 Subject: [PATCH] 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 --- src/widgets/widgets/qlineedit.cpp | 1 - src/widgets/widgets/qlineedit_p.cpp | 35 +++++++++++++++++--------- src/widgets/widgets/qlineedit_p.h | 38 +++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 6b32665065..2cad5d325c 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -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: diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index ff80c45c9a..b90ddacb7e 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -314,6 +314,12 @@ QLineEditIconButton::QLineEditIconButton(QWidget *parent) setFocusPolicy(Qt::NoFocus); } +QLineEditPrivate *QLineEditIconButton::lineEditPrivate() const +{ + QLineEdit *le = qobject_cast(parentWidget()); + return le ? static_cast(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(parentWidget())) - static_cast(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()) diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 60372ab393..1d81090b0f 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -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 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