WebKit Bugzilla
Attachment 346226 Details for
Bug 175067
: [GTK] Spin buttons are drawn too large
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
WIP (text/plain), 13.30 KB, created by
Carlos Bentzen
on 2018-07-31 16:52:13 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Carlos Bentzen
Created:
2018-07-31 16:52:13 PDT
Size:
13.30 KB
patch
obsolete
>commit 3c2b496a564f83845d96a1fd8d71154a159336f6 >Author: Carlos Eduardo Ramalho <cadubentzen@gmail.com> >Date: Tue Jul 17 22:43:23 2018 -0300 > > WIP > >diff --git a/Source/WebCore/platform/gtk/RenderThemeGadget.cpp b/Source/WebCore/platform/gtk/RenderThemeGadget.cpp >index 6a2903b8751..18d0865c261 100644 >--- a/Source/WebCore/platform/gtk/RenderThemeGadget.cpp >+++ b/Source/WebCore/platform/gtk/RenderThemeGadget.cpp >@@ -49,6 +49,8 @@ std::unique_ptr<RenderThemeGadget> RenderThemeGadget::create(const RenderThemeGa > return std::make_unique<RenderThemeIconGadget>(info, parent, siblings, position); > case RenderThemeGadget::Type::Scrollbar: > return std::make_unique<RenderThemeScrollbarGadget>(info, parent, siblings, position); >+ case RenderThemeGadget::Type::SpinButton: >+ return std::make_unique<RenderThemeSpinButtonGadget>(info, parent, siblings, position); > } > > ASSERT_NOT_REACHED(); >@@ -386,6 +388,67 @@ void RenderThemeScrollbarGadget::renderStepper(cairo_t* cr, const FloatRect& pai > contentsRect.y() + (contentsRect.height() - stepperSize) / 2, stepperSize); > } > >+RenderThemeSpinButtonGadget::RenderThemeSpinButtonGadget(const RenderThemeGadget::Info& info, RenderThemeGadget* parent, const Vector<RenderThemeGadget::Info> siblings, unsigned position) >+ : RenderThemeGadget(info, parent, siblings, position) >+{ >+} >+ >+IntSize RenderThemeSpinButtonGadget::minimumSize() const >+{ >+ // We allow spin buttons smaller than the min size set on themes. >+ return IntSize(); >+} >+ >+bool RenderThemeSpinButtonGadget::render(cairo_t* cr, const FloatRect& paintRect, FloatRect*) >+{ >+ ASSERT(m_arrowType == GTK_ARROW_UP || m_arrowType == GTK_ARROW_DOWN); >+ >+ GtkTextDirection direction = gtk_style_context_get_direction(m_context.get()); >+ >+ // Paint button. >+ FloatRect buttonRect(paintRect); >+ guint junction = gtk_style_context_get_junction_sides(m_context.get()); >+ if (m_arrowType == GTK_ARROW_UP) >+ junction |= GTK_JUNCTION_BOTTOM; >+ else { >+ junction |= GTK_JUNCTION_TOP; >+ buttonRect.move(0, paintRect.height() / 2); >+ } >+ buttonRect.setHeight(paintRect.height() / 2); >+ gtk_style_context_set_junction_sides(m_context.get(), static_cast<GtkJunctionSides>(junction)); >+ >+ RenderThemeGadget::render(cr, buttonRect, nullptr); >+ >+ // Paint arrow centered inside button. >+ // This code is based on gtkspinbutton.c code. >+ FloatRect arrowRect; >+ gdouble angle; >+ if (m_arrowType == GTK_ARROW_UP) { >+ angle = 0; >+ arrowRect.setY(paintRect.y()); >+ arrowRect.setHeight(paintRect.height() / 2 - 2); >+ } else { >+ angle = G_PI; >+ arrowRect.setY(paintRect.y() + buttonRect.y()); >+ arrowRect.setHeight(paintRect.height() - arrowRect.y() - 2); >+ } >+ arrowRect.setWidth(paintRect.width() - 3); >+ if (direction == GTK_TEXT_DIR_LTR) >+ arrowRect.setX(paintRect.x() + 1); >+ else >+ arrowRect.setX(paintRect.x() + 2); >+ >+ gint width = arrowRect.width() / 2; >+ width -= width % 2 - 1; // Force odd. >+ gint height = (width + 1) / 2; >+ >+ arrowRect.move((arrowRect.width() - width) / 2, (arrowRect.height() - height) / 2); >+ >+ gtk_render_arrow(m_context.get(), cr, angle, arrowRect.x(), arrowRect.y(), width); >+ >+ return true; >+} >+ > } // namespace WebCore > > #endif // GTK_CHECK_VERSION(3, 20, 0) >diff --git a/Source/WebCore/platform/gtk/RenderThemeGadget.h b/Source/WebCore/platform/gtk/RenderThemeGadget.h >index c46f1560652..3bb3268d79f 100644 >--- a/Source/WebCore/platform/gtk/RenderThemeGadget.h >+++ b/Source/WebCore/platform/gtk/RenderThemeGadget.h >@@ -50,7 +50,8 @@ public: > Radio, > Arrow, > Icon, >- Scrollbar >+ Scrollbar, >+ SpinButton > }; > > struct Info { >@@ -169,6 +170,20 @@ private: > OptionSet<Steppers> m_steppers; > }; > >+class RenderThemeSpinButtonGadget final : public RenderThemeGadget { >+public: >+ RenderThemeSpinButtonGadget(const Info&, RenderThemeGadget* parent, const Vector<RenderThemeGadget::Info> siblings, unsigned position); >+ >+ IntSize minimumSize() const override; >+ >+ bool render(cairo_t*, const FloatRect&, FloatRect* = nullptr) override; >+ >+ void setArrowType(GtkArrowType arrowType) { m_arrowType = arrowType; } >+ >+private: >+ GtkArrowType m_arrowType { GTK_ARROW_UP }; >+}; >+ > } // namespace WebCore > > #endif // GTK_CHECK_VERSION(3, 20, 0) >diff --git a/Source/WebCore/platform/gtk/RenderThemeWidget.cpp b/Source/WebCore/platform/gtk/RenderThemeWidget.cpp >index 88f708e7f42..5890212e75f 100644 >--- a/Source/WebCore/platform/gtk/RenderThemeWidget.cpp >+++ b/Source/WebCore/platform/gtk/RenderThemeWidget.cpp >@@ -231,24 +231,11 @@ RenderThemeSearchEntry::RenderThemeSearchEntry() > > RenderThemeSpinButton::RenderThemeSpinButton() > { >- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "spinbutton", { "horizontal" } }; >- m_spinButton = RenderThemeGadget::create(info); >- info.type = RenderThemeGadget::Type::TextField; >- info.name = "entry"; >- info.classList.clear(); >- m_entry = RenderThemeGadget::create(info, m_spinButton.get()); >- info.type = RenderThemeGadget::Type::Icon; >- info.name = "button"; >- info.classList.append("up"); >- m_up = RenderThemeGadget::create(info, m_spinButton.get()); >- auto* upIcon = static_cast<RenderThemeIconGadget*>(m_up.get()); >- upIcon->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu); >- upIcon->setIconName("list-add-symbolic"); >- info.classList[0] = "down"; >- m_down = RenderThemeGadget::create(info, m_spinButton.get()); >- auto* downIcon = static_cast<RenderThemeIconGadget*>(m_down.get()); >- downIcon->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu); >- downIcon->setIconName("list-remove-symbolic"); >+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::SpinButton, "spinbutton", { "spinbutton", "button" } }; >+ m_up = RenderThemeGadget::create(info, m_entry.get()); >+ static_cast<RenderThemeSpinButtonGadget*>(m_up.get())->setArrowType(GTK_ARROW_UP); >+ m_down = RenderThemeGadget::create(info, m_entry.get()); >+ static_cast<RenderThemeSpinButtonGadget*>(m_down.get())->setArrowType(GTK_ARROW_DOWN); > } > > RenderThemeSlider::RenderThemeSlider(GtkOrientation orientation) >diff --git a/Source/WebCore/platform/gtk/RenderThemeWidget.h b/Source/WebCore/platform/gtk/RenderThemeWidget.h >index 5daab0d7840..74c25a04c31 100644 >--- a/Source/WebCore/platform/gtk/RenderThemeWidget.h >+++ b/Source/WebCore/platform/gtk/RenderThemeWidget.h >@@ -159,19 +159,15 @@ private: > std::unique_ptr<RenderThemeGadget> m_rightIcon; > }; > >-class RenderThemeSpinButton final : public RenderThemeWidget { >+class RenderThemeSpinButton final : public RenderThemeEntry { > public: > RenderThemeSpinButton(); > ~RenderThemeSpinButton() = default; > >- RenderThemeGadget& spinButton() const { return *m_spinButton; } >- RenderThemeGadget& entry() const { return *m_entry; } > RenderThemeGadget& up() const { return *m_up; } > RenderThemeGadget& down() const { return *m_down; } > > private: >- std::unique_ptr<RenderThemeGadget> m_spinButton; >- std::unique_ptr<RenderThemeGadget> m_entry; > std::unique_ptr<RenderThemeGadget> m_up; > std::unique_ptr<RenderThemeGadget> m_down; > }; >diff --git a/Source/WebCore/rendering/RenderThemeGtk.cpp b/Source/WebCore/rendering/RenderThemeGtk.cpp >index 8e8fe10f58e..f68b8ae0b30 100644 >--- a/Source/WebCore/rendering/RenderThemeGtk.cpp >+++ b/Source/WebCore/rendering/RenderThemeGtk.cpp >@@ -935,53 +935,15 @@ bool RenderThemeGtk::isControlStyled(const RenderStyle& style, const BorderData& > > #if GTK_CHECK_VERSION(3, 20, 0) > >-static IntSize spinButtonSize() >-{ >- auto& spinButtonWidget = static_cast<RenderThemeSpinButton&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::SpinButton)); >- spinButtonWidget.spinButton().setState(GTK_STATE_FLAG_NORMAL); >- spinButtonWidget.entry().setState(GTK_STATE_FLAG_NORMAL); >- spinButtonWidget.up().setState(GTK_STATE_FLAG_NORMAL); >- spinButtonWidget.down().setState(GTK_STATE_FLAG_NORMAL); >- >- IntSize preferredSize = spinButtonWidget.spinButton().preferredSize(); >- preferredSize = preferredSize.expandedTo(spinButtonWidget.entry().preferredSize()); >- IntSize upPreferredSize = preferredSize.expandedTo(spinButtonWidget.up().preferredSize()); >- IntSize downPreferredSize = preferredSize.expandedTo(spinButtonWidget.down().preferredSize()); >- >- return IntSize(upPreferredSize.width() + downPreferredSize.width(), std::max(upPreferredSize.height(), downPreferredSize.height())); >-} >- >- >-void RenderThemeGtk::adjustTextFieldStyle(StyleResolver&, RenderStyle& style, const Element* element) const >+void RenderThemeGtk::adjustTextFieldStyle(StyleResolver&, RenderStyle&, const Element*) const > { >- if (!is<HTMLInputElement>(element) || !shouldHaveSpinButton(downcast<HTMLInputElement>(*element))) >- return; >- >- style.setMinHeight(Length(spinButtonSize().height(), Fixed)); >- >- // The default theme for the GTK+ port uses very wide spin buttons (66px) compared to what other >- // browsers use (~13 px). And unfortunately, most of the web developers won't test how their site >- // renders on WebKitGTK+. To ensure that spin buttons don't end up covering the values of the input >- // field, we override the width of the input element and always increment it with the width needed >- // for the spinbutton (when drawing the spinbutton). >- int minimumWidth = style.width().intValue() + spinButtonSize().width(); >- style.setMinWidth(Length(minimumWidth, Fixed)); > } > > bool RenderThemeGtk::paintTextField(const RenderObject& renderObject, const PaintInfo& paintInfo, const FloatRect& rect) > { >- if (is<HTMLInputElement>(renderObject.node()) && shouldHaveSpinButton(downcast<HTMLInputElement>(*renderObject.node()))) { >- auto& spinButtonWidget = static_cast<RenderThemeSpinButton&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::SpinButton)); >- auto spinButtonState = themePartStateFlags(*this, Entry, renderObject); >- spinButtonWidget.spinButton().setState(spinButtonState); >- spinButtonWidget.entry().setState(spinButtonState); >- spinButtonWidget.spinButton().render(paintInfo.context().platformContext()->cr(), rect); >- spinButtonWidget.entry().render(paintInfo.context().platformContext()->cr(), rect); >- } else { >- auto& entryWidget = static_cast<RenderThemeEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::Entry)); >- entryWidget.entry().setState(themePartStateFlags(*this, Entry, renderObject)); >- entryWidget.entry().render(paintInfo.context().platformContext()->cr(), rect); >- } >+ auto& entryWidget = static_cast<RenderThemeEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::Entry)); >+ entryWidget.entry().setState(themePartStateFlags(*this, Entry, renderObject)); >+ entryWidget.entry().render(paintInfo.context().platformContext()->cr(), rect); > return false; > } > #else >@@ -1522,39 +1484,32 @@ bool RenderThemeGtk::paintProgressBar(const RenderObject& renderObject, const Pa > #endif // GTK_CHECK_VERSION(3, 20, 0) > > #if GTK_CHECK_VERSION(3, 20, 0) >-RenderTheme::InnerSpinButtonLayout RenderThemeGtk::innerSpinButtonLayout(const RenderObject& renderObject) const >+RenderTheme::InnerSpinButtonLayout RenderThemeGtk::innerSpinButtonLayout(const RenderObject&) const > { >- return renderObject.style().direction() == RTL ? InnerSpinButtonLayout::HorizontalUpLeft : InnerSpinButtonLayout::HorizontalUpRight; >+ return InnerSpinButtonLayout::Vertical; > } > >+static const int spinButtonArrowSize = 12; >+ > void RenderThemeGtk::adjustInnerSpinButtonStyle(StyleResolver&, RenderStyle& style, const Element*) const > { >- style.setWidth(Length(spinButtonSize().width(), Fixed)); >- style.setHeight(Length(spinButtonSize().height(), Fixed)); >+ style.setWidth(Length(spinButtonArrowSize, Fixed)); >+ style.setMinWidth(Length(spinButtonArrowSize, Fixed)); >+ >+ style.setMaxHeight(Length(2 * spinButtonArrowSize, Fixed)); > } > > bool RenderThemeGtk::paintInnerSpinButton(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect) > { > auto& spinButtonWidget = static_cast<RenderThemeSpinButton&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::SpinButton)); >- auto spinButtonState = themePartStateFlags(*this, SpinButton, renderObject); >- spinButtonWidget.spinButton().setState(spinButtonState); >- spinButtonWidget.entry().setState(spinButtonState); > auto& up = spinButtonWidget.up(); >- up.setState(themePartStateFlags(*this, SpinButtonUpButton, renderObject)); > auto& down = spinButtonWidget.down(); >+ >+ up.setState(themePartStateFlags(*this, SpinButtonUpButton, renderObject)); > down.setState(themePartStateFlags(*this, SpinButtonDownButton, renderObject)); > >- IntRect iconRect = rect; >- iconRect.setWidth(iconRect.width() / 2); >- if (renderObject.style().direction() == RTL) >- up.render(paintInfo.context().platformContext()->cr(), iconRect); >- else >- down.render(paintInfo.context().platformContext()->cr(), iconRect); >- iconRect.move(iconRect.width(), 0); >- if (renderObject.style().direction() == RTL) >- down.render(paintInfo.context().platformContext()->cr(), iconRect); >- else >- up.render(paintInfo.context().platformContext()->cr(), iconRect); >+ up.render(paintInfo.context().platformContext()->cr(), rect); >+ down.render(paintInfo.context().platformContext()->cr(), rect); > > return false; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 175067
:
346225
| 346226