From dbc4556842aa6541b9c8ce48fe34a36811709e64 Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Fri, 30 Sep 2016 18:02:56 +0300 Subject: Fixed checkbox and radiobutton indicators When layout rect is smaller than indicator its edges may not be repainted properly. Now we center indicator repsectively to layout rect and inflate repaint rect to cover edges. Also, when layout rect is larger than indicator, QStyle code paints it at the top-left corner of given rect. Now indicator is centered, like other browser engines do. Note that when layout has auto size for checkbox or radiobutton, their sizes are adjust beforehand in RenderThemeQStyle::computeSizeBasedOnStyle(). This code path is require only when layout forces checkbox or radiobutton to be smaller than optimal indicator size. Task-number: QTBUG-56302 Change-Id: Idaefffc5775055514a430216ea265af2b3a039b4 Reviewed-by: Allan Sandfeld Jensen --- Source/WebCore/platform/qt/QStyleFacade.h | 2 + Source/WebCore/platform/qt/RenderThemeQStyle.cpp | 49 +++++++++++++++++++++- Source/WebCore/platform/qt/RenderThemeQStyle.h | 5 ++- Source/WebCore/platform/qt/RenderThemeQt.cpp | 10 +++++ Source/WebCore/platform/qt/RenderThemeQt.h | 3 ++ Source/WebKit/qt/WidgetSupport/QStyleFacadeImp.cpp | 2 + 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/platform/qt/QStyleFacade.h b/Source/WebCore/platform/qt/QStyleFacade.h index fe7ead1d0..25d3a7dce 100644 --- a/Source/WebCore/platform/qt/QStyleFacade.h +++ b/Source/WebCore/platform/qt/QStyleFacade.h @@ -38,6 +38,8 @@ class QStyleFacadeOption; class QStyleFacade { public: enum ButtonSubElement { + CheckBoxIndicator, + RadioButtonIndicator, PushButtonLayoutItem, PushButtonContents }; diff --git a/Source/WebCore/platform/qt/RenderThemeQStyle.cpp b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp index 999c670c4..9f3d50a2d 100644 --- a/Source/WebCore/platform/qt/RenderThemeQStyle.cpp +++ b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp @@ -62,6 +62,20 @@ namespace WebCore { using namespace HTMLNames; +static QStyleFacade::ButtonSubElement indicatorSubElement(QStyleFacade::ButtonType part) +{ + switch (part) { + case QStyleFacade::CheckBox: + return QStyleFacade::CheckBoxIndicator; + case QStyleFacade::RadioButton: + return QStyleFacade::RadioButtonIndicator; + default: + break; + } + ASSERT_NOT_REACHED(); + return QStyleFacade::CheckBoxIndicator; +} + QSharedPointer RenderThemeQStyle::getStylePainter(const PaintInfo& paintInfo) { return QSharedPointer(new StylePainterQStyle(this, paintInfo, /*RenderObject*/0)); @@ -139,6 +153,11 @@ void RenderThemeQStyle::setPaletteFromPageClientIfExists(QPalette& palette) cons palette = pageClient->palette(); } +QRect RenderThemeQStyle::indicatorRect(QStyleFacade::ButtonType part, const QRect& originalRect) const +{ + return m_qStyle->buttonSubElementRect(indicatorSubElement(part), QStyleFacade::State_Small, originalRect); +} + QRect RenderThemeQStyle::inflateButtonRect(const QRect& originalRect) const { QRect layoutRect = m_qStyle->buttonSubElementRect(QStyleFacade::PushButtonLayoutItem, QStyleFacade::State_Small, originalRect); @@ -153,6 +172,29 @@ QRect RenderThemeQStyle::inflateButtonRect(const QRect& originalRect) const return originalRect; } +template +static void inflateCheckBoxRectImpl(T& originalRect, const QRect& rect) +{ + if (!rect.isNull()) { + int dx = static_cast((rect.width() - originalRect.width()) / 2); + originalRect.setX(originalRect.x() - dx); + originalRect.setWidth(rect.width()); + int dy = static_cast((rect.height() - originalRect.height()) / 2); + originalRect.setY(originalRect.y() - dy); + originalRect.setHeight(rect.height()); + } +} + +void RenderThemeQStyle::computeControlRect(QStyleFacade::ButtonType part, QRect& originalRect) const +{ + inflateCheckBoxRectImpl(originalRect, indicatorRect(part, originalRect)); +} + +void RenderThemeQStyle::computeControlRect(QStyleFacade::ButtonType part, IntRect& originalRect) const +{ + inflateCheckBoxRectImpl(originalRect, indicatorRect(part, originalRect)); +} + int extendFixedPadding(Length oldPadding, int padding) { if (oldPadding.isFixed()) { return std::max(oldPadding.intValue(), padding); @@ -306,10 +348,13 @@ bool RenderThemeQStyle::paintButton(RenderObject* o, const PaintInfo& i, const I if (p.appearance == PushButtonPart || p.appearance == ButtonPart) { p.styleOption.rect = inflateButtonRect(p.styleOption.rect); p.paintButton(QStyleFacade::PushButton); - } else if (p.appearance == RadioPart) + } else if (p.appearance == RadioPart) { + computeControlRect(QStyleFacade::RadioButton, p.styleOption.rect); p.paintButton(QStyleFacade::RadioButton); - else if (p.appearance == CheckboxPart) + } else if (p.appearance == CheckboxPart) { + computeControlRect(QStyleFacade::CheckBox, p.styleOption.rect); p.paintButton(QStyleFacade::CheckBox); + } return false; } diff --git a/Source/WebCore/platform/qt/RenderThemeQStyle.h b/Source/WebCore/platform/qt/RenderThemeQStyle.h index 6027f16e5..781e066ae 100644 --- a/Source/WebCore/platform/qt/RenderThemeQStyle.h +++ b/Source/WebCore/platform/qt/RenderThemeQStyle.h @@ -22,7 +22,6 @@ #ifndef RenderThemeQStyle_h #define RenderThemeQStyle_h -#include "QStyleFacade.h" #include "RenderThemeQt.h" namespace WebCore { @@ -96,6 +95,8 @@ protected: virtual QSharedPointer getStylePainter(const PaintInfo&); virtual QRect inflateButtonRect(const QRect& originalRect) const; + void computeControlRect(QStyleFacade::ButtonType, QRect& originalRect) const OVERRIDE; + void computeControlRect(QStyleFacade::ButtonType, IntRect& originalRect) const OVERRIDE; virtual void setPopupPadding(RenderStyle*) const; @@ -108,6 +109,8 @@ private: void setPaletteFromPageClientIfExists(QPalette&) const; + QRect indicatorRect(QStyleFacade::ButtonType part, const QRect& originalRect) const; + #ifdef Q_OS_MAC int m_buttonFontPixelSize; #endif diff --git a/Source/WebCore/platform/qt/RenderThemeQt.cpp b/Source/WebCore/platform/qt/RenderThemeQt.cpp index 8a6232ea9..9bb1b5139 100644 --- a/Source/WebCore/platform/qt/RenderThemeQt.cpp +++ b/Source/WebCore/platform/qt/RenderThemeQt.cpp @@ -211,12 +211,22 @@ QRect RenderThemeQt::inflateButtonRect(const QRect& originalRect) const return originalRect; } +void RenderThemeQt::computeControlRect(QStyleFacade::ButtonType, QRect&) const +{ +} + +void RenderThemeQt::computeControlRect(QStyleFacade::ButtonType, IntRect&) const +{ +} + void RenderThemeQt::adjustRepaintRect(const RenderObject* o, IntRect& rect) { switch (o->style()->appearance()) { case CheckboxPart: + computeControlRect(QStyleFacade::CheckBox, rect); break; case RadioPart: + computeControlRect(QStyleFacade::RadioButton, rect); break; case PushButtonPart: case ButtonPart: { diff --git a/Source/WebCore/platform/qt/RenderThemeQt.h b/Source/WebCore/platform/qt/RenderThemeQt.h index 7d464d7ec..fb021f3d0 100644 --- a/Source/WebCore/platform/qt/RenderThemeQt.h +++ b/Source/WebCore/platform/qt/RenderThemeQt.h @@ -22,6 +22,7 @@ #ifndef RenderThemeQt_h #define RenderThemeQt_h +#include "QStyleFacade.h" #include "RenderTheme.h" #include @@ -168,6 +169,8 @@ protected: virtual String fileListNameForWidth(const FileList*, const Font&, int width, bool multipleFilesAllowed) const OVERRIDE; virtual QRect inflateButtonRect(const QRect& originalRect) const; + virtual void computeControlRect(QStyleFacade::ButtonType, QRect& originalRect) const; + virtual void computeControlRect(QStyleFacade::ButtonType, IntRect& originalRect) const; virtual void setPopupPadding(RenderStyle*) const = 0; diff --git a/Source/WebKit/qt/WidgetSupport/QStyleFacadeImp.cpp b/Source/WebKit/qt/WidgetSupport/QStyleFacadeImp.cpp index 6881d9d74..e36b5bd20 100644 --- a/Source/WebKit/qt/WidgetSupport/QStyleFacadeImp.cpp +++ b/Source/WebKit/qt/WidgetSupport/QStyleFacadeImp.cpp @@ -163,6 +163,8 @@ QRect QStyleFacadeImp::buttonSubElementRect(QStyleFacade::ButtonSubElement butto QStyle::SubElement subElement = QStyle::SE_CustomBase; switch (buttonElement) { + case CheckBoxIndicator: subElement = QStyle::SE_CheckBoxIndicator; break; + case RadioButtonIndicator: subElement = QStyle::SE_RadioButtonIndicator; break; case PushButtonLayoutItem: subElement = QStyle::SE_PushButtonLayoutItem; break; case PushButtonContents: subElement = QStyle::SE_PushButtonContents; break; default: ASSERT_NOT_REACHED(); -- cgit v1.2.1