Diff
Modified: trunk/Source/WebCore/ChangeLog (217701 => 217702)
--- trunk/Source/WebCore/ChangeLog 2017-06-02 05:55:28 UTC (rev 217701)
+++ trunk/Source/WebCore/ChangeLog 2017-06-02 06:40:36 UTC (rev 217702)
@@ -1,3 +1,89 @@
+2017-06-01 Carlos Garcia Campos <[email protected]>
+
+ [GTK] Cache RenderThemeGadget hierarchies for rendering themed elements with GTK+ 3.20+
+ https://bugs.webkit.org/show_bug.cgi?id=162673
+
+ Reviewed by Michael Catanzaro.
+
+ Because of the way the new theming system works in GTK+ >= 3.20 we are currently creating a gadget hierarchy
+ every time we need to render a styled element or get layout information about it. That's happening on every
+ repaint, and it's specially problematic for overlay scrollbar indicators that fade in/out when shown/hidden. We
+ need to cache the gadgets and simply apply the state before every paint or layout query. When using GtkWidgetPath,
+ calling gtk_style_context_save() breaks the gadget hierarchy, and style classes need to be set when building the
+ GtkWidgetPath. That means we can't cache RenderThemeGadgets, call save, apply style classes and state, and then
+ call restore. We need to cache gadget hierarchies with fixed style classes. Fortunately, setting the state does
+ work, so we don't need to also cache a different hierarchy for every possible state. For example, for the
+ particular case of scrollbars we would cache VerticalScrollbarRight, VerticalScrollbarLeft, HorizontalScrollbar,
+ VerticalScrollIndicatorRight, VerticalScrollIndicatorLeft and HorizontalScrollIndicator. In practice, we will
+ only have 4 of those at the same time in the cache.
+ This patch adds RenderThemeWidget to represent a hierarchy of gadgets with fixed style classes that can be
+ cached and reused to render or query style of those "widgets". It also simplifies the RenderThemeGtk and
+ ScrollbarThemeGtk code by removing a lot of duplicated code to build the gadget hierarchies.
+
+ * PlatformGTK.cmake:
+ * platform/gtk/RenderThemeGadget.cpp:
+ (WebCore::createStyleContext):
+ (WebCore::appendElementToPath):
+ (WebCore::RenderThemeGadget::state):
+ (WebCore::RenderThemeGadget::setState):
+ * platform/gtk/RenderThemeGadget.h:
+ * platform/gtk/RenderThemeWidget.cpp: Added.
+ (WebCore::widgetMap):
+ (WebCore::RenderThemeWidget::getOrCreate):
+ (WebCore::RenderThemeWidget::clearCache):
+ (WebCore::RenderThemeWidget::~RenderThemeWidget):
+ (WebCore::RenderThemeScrollbar::RenderThemeScrollbar):
+ (WebCore::RenderThemeScrollbar::stepper):
+ (WebCore::RenderThemeToggleButton::RenderThemeToggleButton):
+ (WebCore::RenderThemeButton::RenderThemeButton):
+ (WebCore::RenderThemeComboBox::RenderThemeComboBox):
+ (WebCore::RenderThemeEntry::RenderThemeEntry):
+ (WebCore::RenderThemeSearchEntry::RenderThemeSearchEntry):
+ (WebCore::RenderThemeSpinButton::RenderThemeSpinButton):
+ (WebCore::RenderThemeSlider::RenderThemeSlider):
+ (WebCore::RenderThemeProgressBar::RenderThemeProgressBar):
+ (WebCore::RenderThemeListView::RenderThemeListView):
+ (WebCore::RenderThemeIcon::RenderThemeIcon):
+ * platform/gtk/RenderThemeWidget.h: Added.
+ (WebCore::RenderThemeEntry::entry):
+ (WebCore::RenderThemeEntry::selection):
+ * platform/gtk/ScrollbarThemeGtk.cpp:
+ (WebCore::ScrollbarThemeGtk::themeChanged):
+ (WebCore::ScrollbarThemeGtk::updateThemeProperties):
+ (WebCore::widgetTypeForScrollbar):
+ (WebCore::contentsRectangle):
+ (WebCore::ScrollbarThemeGtk::trackRect):
+ (WebCore::ScrollbarThemeGtk::backButtonRect):
+ (WebCore::ScrollbarThemeGtk::forwardButtonRect):
+ (WebCore::ScrollbarThemeGtk::paint):
+ (WebCore::ScrollbarThemeGtk::scrollbarThickness):
+ (WebCore::ScrollbarThemeGtk::minimumThumbLength):
+ * rendering/RenderThemeGtk.cpp:
+ (WebCore::createStyleContext):
+ (WebCore::setToggleSize):
+ (WebCore::paintToggle):
+ (WebCore::RenderThemeGtk::paintButton):
+ (WebCore::menuListColor):
+ (WebCore::RenderThemeGtk::popupInternalPaddingBox):
+ (WebCore::RenderThemeGtk::paintMenuList):
+ (WebCore::RenderThemeGtk::adjustTextFieldStyle):
+ (WebCore::RenderThemeGtk::paintTextField):
+ (WebCore::adjustSearchFieldIconStyle):
+ (WebCore::paintSearchFieldIcon):
+ (WebCore::RenderThemeGtk::paintSliderTrack):
+ (WebCore::RenderThemeGtk::adjustSliderThumbSize):
+ (WebCore::RenderThemeGtk::paintSliderThumb):
+ (WebCore::RenderThemeGtk::progressBarRectForBounds):
+ (WebCore::RenderThemeGtk::paintProgressBar):
+ (WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
+ (WebCore::RenderThemeGtk::paintInnerSpinButton):
+ (WebCore::styleColor):
+ (WebCore::RenderThemeGtk::platformActiveSelectionBackgroundColor):
+ (WebCore::RenderThemeGtk::platformInactiveSelectionBackgroundColor):
+ (WebCore::RenderThemeGtk::platformActiveSelectionForegroundColor):
+ (WebCore::RenderThemeGtk::platformInactiveSelectionForegroundColor):
+ (WebCore::RenderThemeGtk::paintMediaButton):
+
2017-06-01 Andreas Kling <[email protected]>
[Mac] Remove backing store for layers that are outside the viewport
Modified: trunk/Source/WebCore/PlatformGTK.cmake (217701 => 217702)
--- trunk/Source/WebCore/PlatformGTK.cmake 2017-06-02 05:55:28 UTC (rev 217701)
+++ trunk/Source/WebCore/PlatformGTK.cmake 2017-06-02 06:40:36 UTC (rev 217702)
@@ -173,6 +173,7 @@
platform/gtk/PlatformScreenGtk.cpp
platform/gtk/PlatformWheelEventGtk.cpp
platform/gtk/RenderThemeGadget.cpp
+ platform/gtk/RenderThemeWidget.cpp
platform/gtk/ScrollbarThemeGtk.cpp
platform/gtk/SoundGtk.cpp
platform/gtk/WidgetGtk.cpp
Modified: trunk/Source/WebCore/platform/gtk/RenderThemeGadget.cpp (217701 => 217702)
--- trunk/Source/WebCore/platform/gtk/RenderThemeGadget.cpp 2017-06-02 05:55:28 UTC (rev 217701)
+++ trunk/Source/WebCore/platform/gtk/RenderThemeGadget.cpp 2017-06-02 06:40:36 UTC (rev 217702)
@@ -60,8 +60,6 @@
GRefPtr<GtkStyleContext> context = adoptGRef(gtk_style_context_new());
gtk_style_context_set_path(context.get(), path);
gtk_style_context_set_parent(context.get(), parent);
- // Unfortunately, we have to explicitly set the state again here for it to take effect.
- gtk_style_context_set_state(context.get(), gtk_widget_path_iter_get_state(path, -1));
return context;
}
@@ -72,7 +70,6 @@
gtk_widget_path_iter_set_object_name(path, -1, info.name);
for (const auto* className : info.classList)
gtk_widget_path_iter_add_class(path, -1, className);
- gtk_widget_path_iter_set_state(path, -1, static_cast<GtkStateFlags>(gtk_widget_path_iter_get_state(path, -1) | info.state));
}
RenderThemeGadget::RenderThemeGadget(const RenderThemeGadget::Info& info, RenderThemeGadget* parent, const Vector<RenderThemeGadget::Info> siblings, unsigned position)
@@ -146,6 +143,16 @@
return returnValue;
}
+GtkStateFlags RenderThemeGadget::state() const
+{
+ return gtk_style_context_get_state(m_context.get());
+}
+
+void RenderThemeGadget::setState(GtkStateFlags state)
+{
+ gtk_style_context_set_state(m_context.get(), state);
+}
+
IntSize RenderThemeGadget::minimumSize() const
{
int width, height;
Modified: trunk/Source/WebCore/platform/gtk/RenderThemeGadget.h (217701 => 217702)
--- trunk/Source/WebCore/platform/gtk/RenderThemeGadget.h 2017-06-02 05:55:28 UTC (rev 217701)
+++ trunk/Source/WebCore/platform/gtk/RenderThemeGadget.h 2017-06-02 06:40:36 UTC (rev 217702)
@@ -56,7 +56,6 @@
struct Info {
Type type;
const char* name;
- GtkStateFlags state;
Vector<const char*> classList;
};
@@ -77,6 +76,9 @@
GtkStyleContext* context() const { return m_context.get(); }
+ GtkStateFlags state() const;
+ void setState(GtkStateFlags);
+
protected:
GtkBorder marginBox() const;
GtkBorder borderBox() const;
Added: trunk/Source/WebCore/platform/gtk/RenderThemeWidget.cpp (0 => 217702)
--- trunk/Source/WebCore/platform/gtk/RenderThemeWidget.cpp (rev 0)
+++ trunk/Source/WebCore/platform/gtk/RenderThemeWidget.cpp 2017-06-02 06:40:36 UTC (rev 217702)
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderThemeWidget.h"
+
+#if GTK_CHECK_VERSION(3, 20, 0)
+
+#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+static HashMap<unsigned, std::unique_ptr<RenderThemeWidget>>& widgetMap()
+{
+ static NeverDestroyed<HashMap<unsigned, std::unique_ptr<RenderThemeWidget>>> map;
+ return map;
+}
+
+RenderThemeWidget& RenderThemeWidget::getOrCreate(Type widgetType)
+{
+ auto addResult = widgetMap().ensure(static_cast<unsigned>(widgetType), [widgetType]() -> std::unique_ptr<RenderThemeWidget> {
+ switch (widgetType) {
+ case RenderThemeWidget::Type::VerticalScrollbarRight:
+ return std::make_unique<RenderThemeScrollbar>(GTK_ORIENTATION_VERTICAL, RenderThemeScrollbar::Mode::Full);
+ case RenderThemeWidget::Type::VerticalScrollbarLeft:
+ return std::make_unique<RenderThemeScrollbar>(GTK_ORIENTATION_VERTICAL, RenderThemeScrollbar::Mode::Full, RenderThemeScrollbar::VerticalPosition::Left);
+ case RenderThemeWidget::Type::HorizontalScrollbar:
+ return std::make_unique<RenderThemeScrollbar>(GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbar::Mode::Full);
+ case RenderThemeWidget::Type::VerticalScrollIndicatorRight:
+ return std::make_unique<RenderThemeScrollbar>(GTK_ORIENTATION_VERTICAL, RenderThemeScrollbar::Mode::Indicator);
+ case RenderThemeWidget::Type::VerticalScrollIndicatorLeft:
+ return std::make_unique<RenderThemeScrollbar>(GTK_ORIENTATION_VERTICAL, RenderThemeScrollbar::Mode::Indicator, RenderThemeScrollbar::VerticalPosition::Left);
+ case RenderThemeWidget::Type::HorizontalScrollIndicator:
+ return std::make_unique<RenderThemeScrollbar>(GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbar::Mode::Indicator);
+ case RenderThemeWidget::Type::CheckButton:
+ return std::make_unique<RenderThemeToggleButton>(RenderThemeToggleButton::Type::Check);
+ case RenderThemeWidget::Type::RadioButton:
+ return std::make_unique<RenderThemeToggleButton>(RenderThemeToggleButton::Type::Radio);
+ case RenderThemeWidget::Type::Button:
+ return std::make_unique<RenderThemeButton>(RenderThemeButton::Default::No);
+ case RenderThemeWidget::Type::ButtonDefault:
+ return std::make_unique<RenderThemeButton>(RenderThemeButton::Default::Yes);
+ case RenderThemeWidget::Type::ComboBox:
+ return std::make_unique<RenderThemeComboBox>();
+ case RenderThemeWidget::Type::Entry:
+ return std::make_unique<RenderThemeEntry>();
+ case RenderThemeWidget::Type::SelectedEntry:
+ return std::make_unique<RenderThemeEntry>(RenderThemeEntry::Selected::Yes);
+ case RenderThemeWidget::Type::SearchEntry:
+ return std::make_unique<RenderThemeSearchEntry>();
+ case RenderThemeWidget::Type::SpinButton:
+ return std::make_unique<RenderThemeSpinButton>();
+ case RenderThemeWidget::Type::VerticalSlider:
+ return std::make_unique<RenderThemeSlider>(GTK_ORIENTATION_VERTICAL);
+ case RenderThemeWidget::Type::HorizontalSlider:
+ return std::make_unique<RenderThemeSlider>(GTK_ORIENTATION_HORIZONTAL);
+ case RenderThemeWidget::Type::ProgressBar:
+ return std::make_unique<RenderThemeProgressBar>(RenderThemeProgressBar::Mode::Determinate);
+ case RenderThemeWidget::Type::IndeterminateProgressBar:
+ return std::make_unique<RenderThemeProgressBar>(RenderThemeProgressBar::Mode::Indeterminate);
+ case RenderThemeWidget::Type::ListView:
+ return std::make_unique<RenderThemeListView>();
+ case RenderThemeWidget::Type::Icon:
+ return std::make_unique<RenderThemeIcon>();
+ }
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ });
+ return *addResult.iterator->value;
+}
+
+void RenderThemeWidget::clearCache()
+{
+ widgetMap().clear();
+}
+
+RenderThemeWidget::~RenderThemeWidget()
+{
+}
+
+RenderThemeScrollbar::RenderThemeScrollbar(GtkOrientation orientation, Mode mode, VerticalPosition verticalPosition)
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::Scrollbar, "scrollbar", { } };
+ if (orientation == GTK_ORIENTATION_VERTICAL) {
+ info.classList.append("vertical");
+ info.classList.append(verticalPosition == VerticalPosition::Right ? "right" : "left");
+ } else {
+ info.classList.append("horizontal");
+ info.classList.append("bottom");
+ }
+ static bool usesOverlayScrollbars = g_strcmp0(g_getenv("GTK_OVERLAY_SCROLLING"), "0");
+ if (usesOverlayScrollbars)
+ info.classList.append("overlay-indicator");
+ if (mode == Mode::Full)
+ info.classList.append("hovering");
+ m_scrollbar = RenderThemeGadget::create(info);
+
+ Vector<RenderThemeGadget::Info> children;
+ auto steppers = static_cast<RenderThemeScrollbarGadget*>(m_scrollbar.get())->steppers();
+ if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Backward)) {
+ m_steppersPosition[0] = children.size();
+ children.append({ RenderThemeGadget::Type::Generic, "button", { "up" } });
+ }
+ if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
+ m_steppersPosition[1] = children.size();
+ children.append({ RenderThemeGadget::Type::Generic, "button", { "down" } });
+ }
+ m_troughPosition = children.size();
+ children.append({ RenderThemeGadget::Type::Generic, "trough", { } });
+ if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryBackward)) {
+ m_steppersPosition[2] = children.size();
+ children.append({ RenderThemeGadget::Type::Generic, "button", { "up" } });
+ }
+ if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward)) {
+ m_steppersPosition[3] = children.size();
+ children.append({ RenderThemeGadget::Type::Generic, "button", { "down" } });
+ }
+ info.type = RenderThemeGadget::Type::Generic;
+ info.name = "contents";
+ info.classList.clear();
+ m_contents = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_VERTICAL, children, m_scrollbar.get());
+ info.name = "slider";
+ m_slider = RenderThemeGadget::create(info, m_contents->child(m_troughPosition));
+}
+
+RenderThemeGadget* RenderThemeScrollbar::stepper(RenderThemeScrollbarGadget::Steppers scrollbarStepper)
+{
+ if (!static_cast<RenderThemeScrollbarGadget*>(m_scrollbar.get())->steppers().contains(scrollbarStepper))
+ return nullptr;
+
+ switch (scrollbarStepper) {
+ case RenderThemeScrollbarGadget::Steppers::Backward:
+ return m_contents->child(m_steppersPosition[0]);
+ case RenderThemeScrollbarGadget::Steppers::SecondaryForward:
+ return m_contents->child(m_steppersPosition[1]);
+ case RenderThemeScrollbarGadget::Steppers::SecondaryBackward:
+ return m_contents->child(m_steppersPosition[2]);
+ case RenderThemeScrollbarGadget::Steppers::Forward:
+ return m_contents->child(m_steppersPosition[3]);
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+RenderThemeToggleButton::RenderThemeToggleButton(Type toggleType)
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, toggleType == Type::Check ? "checkbutton" : "radiobutton", { "text-button" } };
+ m_button = RenderThemeGadget::create(info);
+ if (toggleType == Type::Check) {
+ info.type = RenderThemeGadget::Type::Check;
+ info.name = "check";
+ } else {
+ info.type = RenderThemeGadget::Type::Radio;
+ info.name = "radio";
+ }
+ info.classList.clear();
+ m_toggle = RenderThemeGadget::create(info, m_button.get());
+}
+
+RenderThemeButton::RenderThemeButton(Default isDefault)
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "button", { "text-button" } };
+ if (isDefault == Default::Yes)
+ info.classList.append("default");
+ m_button = RenderThemeGadget::create(info);
+}
+
+RenderThemeComboBox::RenderThemeComboBox()
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "combobox", { } };
+ m_comboBox = RenderThemeGadget::create(info);
+ Vector<RenderThemeGadget::Info> children = {
+ { RenderThemeGadget::Type::Generic, "button", { "combo" } }
+ };
+ info.name = "box";
+ info.classList = { "horizontal", "linked" };
+ m_box = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_HORIZONTAL, children, m_comboBox.get());
+ RenderThemeGadget* button = m_box->child(0);
+ info.classList.removeLast();
+ m_buttonBox = RenderThemeGadget::create(info, button);
+ info.type = RenderThemeGadget::Type::Arrow;
+ info.name = "arrow";
+ info.classList = { };
+ m_arrow = RenderThemeGadget::create(info, m_buttonBox.get());
+}
+
+RenderThemeEntry::RenderThemeEntry(Selected isSelected)
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::TextField, "entry", { } };
+ m_entry = RenderThemeGadget::create(info);
+ if (isSelected == Selected::Yes) {
+ info.type = RenderThemeGadget::Type::Generic;
+ info.name = "selection";
+ m_selection = RenderThemeGadget::create(info, m_entry.get());
+ }
+}
+
+RenderThemeSearchEntry::RenderThemeSearchEntry()
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::Icon, "image", { "left" } };
+ m_leftIcon = RenderThemeGadget::create(info, m_entry.get());
+ static_cast<RenderThemeIconGadget*>(m_leftIcon.get())->setIconName("edit-find-symbolic");
+ info.classList.clear();
+ info.classList.append("right");
+ m_rightIcon = RenderThemeGadget::create(info, m_entry.get());
+ static_cast<RenderThemeIconGadget*>(m_rightIcon.get())->setIconName("edit-clear-symbolic");
+}
+
+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");
+}
+
+RenderThemeSlider::RenderThemeSlider(GtkOrientation orientation)
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "scale", { } };
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ info.classList.append("vertical");
+ else
+ info.classList.append("horizontal");
+ m_scale = RenderThemeGadget::create(info);
+ info.name = "contents";
+ info.classList.clear();
+ m_contents = RenderThemeGadget::create(info, m_scale.get());
+ info.name = "trough";
+ m_trough = RenderThemeGadget::create(info, m_contents.get());
+ info.name = "slider";
+ m_slider = RenderThemeGadget::create(info, m_trough.get());
+ info.name = "highlight";
+ m_highlight = RenderThemeGadget::create(info, m_trough.get());
+}
+
+RenderThemeProgressBar::RenderThemeProgressBar(Mode mode)
+{
+ RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "progressbar", { "horizontal" } };
+ m_progressBar = RenderThemeGadget::create(info);
+ info.name = "trough";
+ info.classList.clear();
+ m_trough = RenderThemeGadget::create(info, m_progressBar.get());
+ info.name = "progress";
+ if (mode == Mode::Determinate)
+ info.classList.append("pulse");
+ m_progress = RenderThemeGadget::create(info, m_trough.get());
+}
+
+RenderThemeListView::RenderThemeListView()
+ : m_treeview(RenderThemeGadget::create({ RenderThemeGadget::Type::Generic, "treeview", { "view" } }))
+{
+}
+
+RenderThemeIcon::RenderThemeIcon()
+ : m_icon(RenderThemeGadget::create({ RenderThemeGadget::Type::Icon, "image", { } }))
+{
+}
+
+} // namepsace WebCore
+
+#endif // GTK_CHECK_VERSION(3, 20, 0)
Added: trunk/Source/WebCore/platform/gtk/RenderThemeWidget.h (0 => 217702)
--- trunk/Source/WebCore/platform/gtk/RenderThemeWidget.h (rev 0)
+++ trunk/Source/WebCore/platform/gtk/RenderThemeWidget.h 2017-06-02 06:40:36 UTC (rev 217702)
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#if GTK_CHECK_VERSION(3, 20, 0)
+
+#include "RenderThemeGadget.h"
+
+namespace WebCore {
+
+class RenderThemeWidget {
+ WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(RenderThemeWidget);
+public:
+ enum class Type {
+ VerticalScrollbarRight = 1,
+ VerticalScrollbarLeft,
+ HorizontalScrollbar,
+ VerticalScrollIndicatorRight,
+ VerticalScrollIndicatorLeft,
+ HorizontalScrollIndicator,
+ CheckButton,
+ RadioButton,
+ Button,
+ ButtonDefault,
+ ComboBox,
+ Entry,
+ SelectedEntry,
+ SearchEntry,
+ SpinButton,
+ VerticalSlider,
+ HorizontalSlider,
+ ProgressBar,
+ IndeterminateProgressBar,
+ ListView,
+ Icon,
+ };
+ static RenderThemeWidget& getOrCreate(Type);
+ static void clearCache();
+
+ RenderThemeWidget() = default;
+ virtual ~RenderThemeWidget();
+};
+
+class RenderThemeScrollbar final : public RenderThemeWidget {
+public:
+ enum class Mode { Full, Indicator };
+ enum class VerticalPosition { Right, Left };
+ RenderThemeScrollbar(GtkOrientation, Mode, VerticalPosition = VerticalPosition::Right);
+ ~RenderThemeScrollbar() = default;
+
+ RenderThemeGadget& scrollbar() const { return *m_scrollbar; }
+ RenderThemeGadget& contents() const { return *m_contents; }
+ RenderThemeGadget& slider() const { return *m_slider; }
+ RenderThemeGadget& trough() const { return *m_contents->child(m_troughPosition); }
+ RenderThemeGadget* stepper(RenderThemeScrollbarGadget::Steppers);
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_scrollbar;
+ std::unique_ptr<RenderThemeBoxGadget> m_contents;
+ std::unique_ptr<RenderThemeGadget> m_slider;
+ unsigned m_troughPosition;
+ unsigned m_steppersPosition[4];
+};
+
+class RenderThemeToggleButton final : public RenderThemeWidget {
+public:
+ enum class Type { Check, Radio };
+ explicit RenderThemeToggleButton(Type);
+ ~RenderThemeToggleButton() = default;
+
+ RenderThemeGadget& button() const { return *m_button; }
+ RenderThemeGadget& toggle() const { return *m_toggle; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_button;
+ std::unique_ptr<RenderThemeGadget> m_toggle;
+};
+
+class RenderThemeButton final : public RenderThemeWidget {
+public:
+ enum class Default { No, Yes };
+ explicit RenderThemeButton(Default);
+ ~RenderThemeButton() = default;
+
+ RenderThemeGadget& button() const { return *m_button; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_button;
+};
+
+class RenderThemeComboBox final : public RenderThemeWidget {
+public:
+ RenderThemeComboBox();
+ ~RenderThemeComboBox() = default;
+
+ RenderThemeGadget& comboBox() const { return *m_comboBox; }
+ RenderThemeGadget& box() const { return *m_box; }
+ RenderThemeGadget& button() const { return *m_box->child(0); }
+ RenderThemeGadget& buttonBox() const { return *m_buttonBox; }
+ RenderThemeGadget& arrow() const { return *m_arrow; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_comboBox;
+ std::unique_ptr<RenderThemeBoxGadget> m_box;
+ std::unique_ptr<RenderThemeGadget> m_buttonBox;
+ std::unique_ptr<RenderThemeGadget> m_arrow;
+};
+
+class RenderThemeEntry : public RenderThemeWidget {
+public:
+ enum class Selected { No, Yes };
+ explicit RenderThemeEntry(Selected = Selected::No);
+ ~RenderThemeEntry() = default;
+
+ RenderThemeGadget& entry() const { return *m_entry; }
+ RenderThemeGadget* selection() const { return m_selection.get(); }
+
+protected:
+ std::unique_ptr<RenderThemeGadget> m_entry;
+ std::unique_ptr<RenderThemeGadget> m_selection;
+};
+
+class RenderThemeSearchEntry final : public RenderThemeEntry {
+public:
+ RenderThemeSearchEntry();
+ ~RenderThemeSearchEntry() = default;
+
+ RenderThemeGadget& leftIcon() const { return *m_leftIcon; }
+ RenderThemeGadget& rightIcon() const { return *m_rightIcon; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_leftIcon;
+ std::unique_ptr<RenderThemeGadget> m_rightIcon;
+};
+
+class RenderThemeSpinButton final : public RenderThemeWidget {
+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;
+};
+
+class RenderThemeSlider final : public RenderThemeWidget {
+public:
+ explicit RenderThemeSlider(GtkOrientation);
+ ~RenderThemeSlider() = default;
+
+ RenderThemeGadget& scale() const { return *m_scale; }
+ RenderThemeGadget& contents() const { return *m_contents; }
+ RenderThemeGadget& trough() const { return *m_trough; }
+ RenderThemeGadget& slider() const { return *m_slider; }
+ RenderThemeGadget& highlight() const { return *m_highlight; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_scale;
+ std::unique_ptr<RenderThemeGadget> m_contents;
+ std::unique_ptr<RenderThemeGadget> m_trough;
+ std::unique_ptr<RenderThemeGadget> m_slider;
+ std::unique_ptr<RenderThemeGadget> m_highlight;
+};
+
+class RenderThemeProgressBar final : public RenderThemeWidget {
+public:
+ enum class Mode { Determinate, Indeterminate };
+ explicit RenderThemeProgressBar(Mode);
+ ~RenderThemeProgressBar() = default;
+
+ RenderThemeGadget& progressBar() const { return *m_progressBar; }
+ RenderThemeGadget& trough() const { return *m_trough; }
+ RenderThemeGadget& progress() const { return *m_progress; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_progressBar;
+ std::unique_ptr<RenderThemeGadget> m_trough;
+ std::unique_ptr<RenderThemeGadget> m_progress;
+};
+
+class RenderThemeListView final : public RenderThemeWidget {
+public:
+ RenderThemeListView();
+ ~RenderThemeListView() = default;
+
+ RenderThemeGadget& treeview() const { return *m_treeview; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_treeview;
+};
+
+class RenderThemeIcon final : public RenderThemeWidget {
+public:
+ RenderThemeIcon();
+ ~RenderThemeIcon() = default;
+
+ RenderThemeGadget& icon() const { return *m_icon; }
+
+private:
+ std::unique_ptr<RenderThemeGadget> m_icon;
+};
+
+} // namespace WebCore
+
+#endif // GTK_CHECK_VERSION(3, 20, 0)
Modified: trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp (217701 => 217702)
--- trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp 2017-06-02 05:55:28 UTC (rev 217701)
+++ trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp 2017-06-02 06:40:36 UTC (rev 217702)
@@ -30,7 +30,7 @@
#include "GRefPtrGtk.h"
#include "PlatformContextCairo.h"
#include "PlatformMouseEvent.h"
-#include "RenderThemeGadget.h"
+#include "RenderThemeWidget.h"
#include "ScrollView.h"
#include "Scrollbar.h"
#include <cstdlib>
@@ -96,6 +96,9 @@
void ScrollbarThemeGtk::themeChanged()
{
+#if GTK_CHECK_VERSION(3, 20, 0)
+ RenderThemeWidget::clearCache();
+#endif
updateThemeProperties();
}
@@ -102,11 +105,11 @@
#if GTK_CHECK_VERSION(3, 20, 0)
void ScrollbarThemeGtk::updateThemeProperties()
{
- auto steppers = static_cast<RenderThemeScrollbarGadget*>(RenderThemeGadget::create({ RenderThemeGadget::Type::Scrollbar, "scrollbar", GTK_STATE_FLAG_NORMAL, { } }).get())->steppers();
- m_hasBackButtonStartPart = steppers.contains(RenderThemeScrollbarGadget::Steppers::Backward);
- m_hasForwardButtonEndPart = steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward);
- m_hasBackButtonEndPart = steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryBackward);
- m_hasForwardButtonStartPart = steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryForward);
+ auto& scrollbar = static_cast<RenderThemeScrollbar&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::VerticalScrollbarRight));
+ m_hasBackButtonStartPart = scrollbar.stepper(RenderThemeScrollbarGadget::Steppers::Backward);
+ m_hasForwardButtonEndPart = scrollbar.stepper(RenderThemeScrollbarGadget::Steppers::Forward);
+ m_hasBackButtonEndPart = scrollbar.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryBackward);
+ m_hasForwardButtonStartPart = scrollbar.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryForward);
}
#else
void ScrollbarThemeGtk::updateThemeProperties()
@@ -168,71 +171,41 @@
return static_cast<GtkStateFlags>(stateFlags);
}
-static std::unique_ptr<RenderThemeGadget> scrollbarGadgetForLayout(Scrollbar& scrollbar)
+static RenderThemeWidget::Type widgetTypeForScrollbar(Scrollbar& scrollbar, GtkStateFlags scrollbarState)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Scrollbar, "scrollbar", scrollbarPartStateFlags(scrollbar, AllParts), { } };
if (scrollbar.orientation() == VerticalScrollbar) {
- info.classList.append("vertical");
- info.classList.append("right");
- } else {
- info.classList.append("horizontal");
- info.classList.append("bottom");
+ if (scrollbar.scrollableArea().shouldPlaceBlockDirectionScrollbarOnLeft())
+ return scrollbarState & GTK_STATE_FLAG_PRELIGHT ? RenderThemeWidget::Type::VerticalScrollbarLeft : RenderThemeWidget::Type::VerticalScrollIndicatorLeft;
+ return scrollbarState & GTK_STATE_FLAG_PRELIGHT ? RenderThemeWidget::Type::VerticalScrollbarRight : RenderThemeWidget::Type::VerticalScrollIndicatorRight;
}
- if (scrollbar.isOverlayScrollbar())
- info.classList.append("overlay-indicator");
- if (info.state & GTK_STATE_FLAG_PRELIGHT)
- info.classList.append("hovering");
-
- return RenderThemeGadget::create(info);
+ return scrollbarState & GTK_STATE_FLAG_PRELIGHT ? RenderThemeWidget::Type::HorizontalScrollbar : RenderThemeWidget::Type::HorizontalScrollIndicator;
}
-static std::unique_ptr<RenderThemeBoxGadget> contentsGadgetForLayout(Scrollbar& scrollbar, RenderThemeGadget* parent, IntRect& contentsRect, Vector<int, 4>& steppersPosition)
+static IntRect contentsRectangle(Scrollbar& scrollbar, RenderThemeScrollbar& scrollbarWidget)
{
- Vector<RenderThemeGadget::Info> children;
- auto steppers = static_cast<RenderThemeScrollbarGadget*>(parent)->steppers();
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Backward)) {
- steppersPosition[0] = 0;
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, BackButtonStartPart), { "up" } });
- }
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
- steppersPosition[1] = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, ForwardButtonStartPart), { "down" } });
- }
- children.append({ RenderThemeGadget::Type::Generic, "trough", scrollbarPartStateFlags(scrollbar, BackTrackPart), { } });
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryBackward)) {
- steppersPosition[2] = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, BackButtonEndPart), { "up" } });
- }
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward)) {
- steppersPosition[3] = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart), { "down" } });
- }
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "contents", GTK_STATE_FLAG_NORMAL, { } };
- auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL,
- children, parent);
-
- GtkBorder scrollbarContentsBox = parent->contentsBox();
- GtkBorder contentsContentsBox = contentsGadget->contentsBox();
+ GtkBorder scrollbarContentsBox = scrollbarWidget.scrollbar().contentsBox();
+ GtkBorder contentsContentsBox = scrollbarWidget.contents().contentsBox();
GtkBorder padding;
padding.left = scrollbarContentsBox.left + contentsContentsBox.left;
padding.right = scrollbarContentsBox.right + contentsContentsBox.right;
padding.top = scrollbarContentsBox.top + contentsContentsBox.top;
padding.bottom = scrollbarContentsBox.bottom + contentsContentsBox.bottom;
- contentsRect = scrollbar.frameRect();
+ IntRect contentsRect = scrollbar.frameRect();
contentsRect.move(padding.left, padding.top);
contentsRect.contract(padding.left + padding.right, padding.top + padding.bottom);
- return contentsGadget;
+ return contentsRect;
}
IntRect ScrollbarThemeGtk::trackRect(Scrollbar& scrollbar, bool /*painting*/)
{
- auto scrollbarGadget = scrollbarGadgetForLayout(scrollbar);
- IntRect rect;
- Vector<int, 4> steppersPosition(4, -1);
- auto contentsGadget = contentsGadgetForLayout(scrollbar, scrollbarGadget.get(), rect, steppersPosition);
+ auto scrollbarState = scrollbarPartStateFlags(scrollbar, AllParts);
+ auto& scrollbarWidget = static_cast<RenderThemeScrollbar&>(RenderThemeWidget::getOrCreate(widgetTypeForScrollbar(scrollbar, scrollbarState)));
+ scrollbarWidget.scrollbar().setState(scrollbarState);
- if (steppersPosition[0] != -1) {
- IntSize stepperSize = contentsGadget->child(steppersPosition[0])->preferredSize();
+ IntRect rect = contentsRectangle(scrollbar, scrollbarWidget);
+ if (auto* backwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Backward)) {
+ backwardStepper->setState(scrollbarPartStateFlags(scrollbar, BackButtonStartPart));
+ IntSize stepperSize = backwardStepper->preferredSize();
if (scrollbar.orientation() == VerticalScrollbar) {
rect.move(0, stepperSize.height());
rect.contract(0, stepperSize.height());
@@ -241,8 +214,9 @@
rect.contract(stepperSize.width(), 0);
}
}
- if (steppersPosition[1] != -1) {
- IntSize stepperSize = contentsGadget->child(steppersPosition[1])->preferredSize();
+ if (auto* secondaryForwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
+ secondaryForwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonStartPart));
+ IntSize stepperSize = secondaryForwardStepper->preferredSize();
if (scrollbar.orientation() == VerticalScrollbar) {
rect.move(0, stepperSize.height());
rect.contract(0, stepperSize.height());
@@ -251,17 +225,19 @@
rect.contract(stepperSize.width(), 0);
}
}
- if (steppersPosition[2] != -1) {
+ if (auto* secondaryBackwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryBackward)) {
+ secondaryBackwardStepper->setState(scrollbarPartStateFlags(scrollbar, BackButtonEndPart));
if (scrollbar.orientation() == VerticalScrollbar)
- rect.contract(0, contentsGadget->child(steppersPosition[2])->preferredSize().height());
+ rect.contract(0, secondaryBackwardStepper->preferredSize().height());
else
- rect.contract(contentsGadget->child(steppersPosition[2])->preferredSize().width(), 0);
+ rect.contract(secondaryBackwardStepper->preferredSize().width(), 0);
}
- if (steppersPosition[3] != -1) {
+ if (auto* forwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Forward)) {
+ forwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart));
if (scrollbar.orientation() == VerticalScrollbar)
- rect.contract(0, contentsGadget->child(steppersPosition[3])->preferredSize().height());
+ rect.contract(0, forwardStepper->preferredSize().height());
else
- rect.contract(contentsGadget->child(steppersPosition[3])->preferredSize().width(), 0);
+ rect.contract(forwardStepper->preferredSize().width(), 0);
}
if (scrollbar.orientation() == VerticalScrollbar)
@@ -327,17 +303,21 @@
if ((part == BackButtonEndPart && !m_hasBackButtonEndPart) || (part == BackButtonStartPart && !m_hasBackButtonStartPart))
return IntRect();
- auto scrollbarGadget = scrollbarGadgetForLayout(scrollbar);
- IntRect rect;
- Vector<int, 4> steppersPosition(4, -1);
- auto contentsGadget = contentsGadgetForLayout(scrollbar, scrollbarGadget.get(), rect, steppersPosition);
+ auto scrollbarState = scrollbarPartStateFlags(scrollbar, AllParts);
+ auto& scrollbarWidget = static_cast<RenderThemeScrollbar&>(RenderThemeWidget::getOrCreate(widgetTypeForScrollbar(scrollbar, scrollbarState)));
+ scrollbarWidget.scrollbar().setState(scrollbarState);
- if (part == BackButtonStartPart)
- return IntRect(rect.location(), contentsGadget->child(0)->preferredSize());
+ IntRect rect = contentsRectangle(scrollbar, scrollbarWidget);
+ if (part == BackButtonStartPart) {
+ auto* backwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Backward);
+ ASSERT(backwardStepper);
+ backwardStepper->setState(scrollbarPartStateFlags(scrollbar, BackButtonStartPart));
+ return IntRect(rect.location(), backwardStepper->preferredSize());
+ }
- // Secondary back.
- if (steppersPosition[1] != -1) {
- IntSize preferredSize = contentsGadget->child(steppersPosition[1])->preferredSize();
+ if (auto* secondaryForwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
+ secondaryForwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonStartPart));
+ IntSize preferredSize = secondaryForwardStepper->preferredSize();
if (scrollbar.orientation() == VerticalScrollbar) {
rect.move(0, preferredSize.height());
rect.contract(0, preferredSize.height());
@@ -347,14 +327,18 @@
}
}
- if (steppersPosition[3] != -1) {
+ if (auto* secondaryBackwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryBackward)) {
+ secondaryBackwardStepper->setState(scrollbarPartStateFlags(scrollbar, BackButtonEndPart));
if (scrollbar.orientation() == VerticalScrollbar)
- rect.contract(0, contentsGadget->child(steppersPosition[3])->preferredSize().height());
+ rect.contract(0, secondaryBackwardStepper->preferredSize().height());
else
- rect.contract(contentsGadget->child(steppersPosition[3])->preferredSize().width(), 0);
+ rect.contract(secondaryBackwardStepper->preferredSize().width(), 0);
}
- IntSize preferredSize = contentsGadget->child(steppersPosition[2])->preferredSize();
+ auto* forwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Forward);
+ ASSERT(forwardStepper);
+ forwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart));
+ IntSize preferredSize = forwardStepper->preferredSize();
if (scrollbar.orientation() == VerticalScrollbar)
rect.move(0, rect.height() - preferredSize.height());
else
@@ -369,13 +353,14 @@
if ((part == ForwardButtonStartPart && !m_hasForwardButtonStartPart) || (part == ForwardButtonEndPart && !m_hasForwardButtonEndPart))
return IntRect();
- auto scrollbarGadget = scrollbarGadgetForLayout(scrollbar);
- IntRect rect;
- Vector<int, 4> steppersPosition(4, -1);
- auto contentsGadget = contentsGadgetForLayout(scrollbar, scrollbarGadget.get(), rect, steppersPosition);
+ auto scrollbarState = scrollbarPartStateFlags(scrollbar, AllParts);
+ auto& scrollbarWidget = static_cast<RenderThemeScrollbar&>(RenderThemeWidget::getOrCreate(widgetTypeForScrollbar(scrollbar, scrollbarState)));
+ scrollbarWidget.scrollbar().setState(scrollbarState);
- if (steppersPosition[0] != -1) {
- IntSize preferredSize = contentsGadget->child(steppersPosition[0])->preferredSize();
+ IntRect rect = contentsRectangle(scrollbar, scrollbarWidget);
+ if (auto* backwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Backward)) {
+ backwardStepper->setState(scrollbarPartStateFlags(scrollbar, BackButtonStartPart));
+ IntSize preferredSize = backwardStepper->preferredSize();
if (scrollbar.orientation() == VerticalScrollbar) {
rect.move(0, preferredSize.height());
rect.contract(0, preferredSize.height());
@@ -385,8 +370,9 @@
}
}
- if (steppersPosition[1] != -1) {
- IntSize preferredSize = contentsGadget->child(steppersPosition[1])->preferredSize();
+ if (auto* secondaryForwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
+ secondaryForwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonStartPart));
+ IntSize preferredSize = secondaryForwardStepper->preferredSize();
if (part == ForwardButtonStartPart)
return IntRect(rect.location(), preferredSize);
@@ -399,8 +385,10 @@
}
}
- // Forward button.
- IntSize preferredSize = contentsGadget->child(steppersPosition[3])->preferredSize();
+ auto* forwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Forward);
+ ASSERT(forwardStepper);
+ forwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart));
+ IntSize preferredSize = forwardStepper->preferredSize();
if (scrollbar.orientation() == VerticalScrollbar)
rect.move(0, rect.height() - preferredSize.height());
else
@@ -477,67 +465,38 @@
if (!rect.intersects(damageRect))
return true;
- bool scrollbarOnLeft = scrollbar.scrollableArea().shouldPlaceBlockDirectionScrollbarOnLeft();
-
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Scrollbar, "scrollbar", scrollbarPartStateFlags(scrollbar, AllParts, true), { } };
- if (scrollbar.orientation() == VerticalScrollbar) {
- info.classList.append("vertical");
- info.classList.append(scrollbarOnLeft ? "left" : "right");
- } else {
- info.classList.append("horizontal");
- info.classList.append("bottom");
- }
+ auto scrollbarState = scrollbarPartStateFlags(scrollbar, AllParts, true);
+ auto& scrollbarWidget = static_cast<RenderThemeScrollbar&>(RenderThemeWidget::getOrCreate(widgetTypeForScrollbar(scrollbar, scrollbarState)));
+ auto& scrollbarGadget = scrollbarWidget.scrollbar();
+ scrollbarGadget.setState(scrollbarState);
if (m_usesOverlayScrollbars)
- info.classList.append("overlay-indicator");
- if (info.state & GTK_STATE_FLAG_PRELIGHT)
- info.classList.append("hovering");
- if (scrollbar.pressedPart() != NoPart)
- info.classList.append("dragging");
- auto scrollbarGadget = RenderThemeGadget::create(info);
- if (m_usesOverlayScrollbars)
- opacity *= scrollbarGadget->opacity();
+ opacity *= scrollbarGadget.opacity();
if (!opacity)
return true;
- info.type = RenderThemeGadget::Type::Generic;
- info.name = "contents";
- info.state = GTK_STATE_FLAG_NORMAL;
- info.classList.clear();
- Vector<RenderThemeGadget::Info> children;
- auto steppers = static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->steppers();
- unsigned steppersPosition[4] = { 0, 0, 0, 0 };
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Backward)) {
- steppersPosition[0] = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, BackButtonStartPart), { "up" } });
- }
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
- steppersPosition[1] = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, ForwardButtonStartPart), { "down" } });
- }
- unsigned troughPosition = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "trough", scrollbarPartStateFlags(scrollbar, BackTrackPart), { } });
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryBackward)) {
- steppersPosition[2] = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, BackButtonEndPart), { "up" } });
- }
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward)) {
- steppersPosition[3] = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart), { "down" } });
- }
- auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL,
- children, scrollbarGadget.get());
- RenderThemeGadget* troughGadget = contentsGadget->child(troughPosition);
+ auto& trough = scrollbarWidget.trough();
+ trough.setState(scrollbarPartStateFlags(scrollbar, BackTrackPart));
- IntSize preferredSize = contentsGadget->preferredSize();
- std::unique_ptr<RenderThemeGadget> sliderGadget;
+ auto* backwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Backward);
+ if (backwardStepper)
+ backwardStepper->setState(scrollbarPartStateFlags(scrollbar, BackButtonStartPart));
+ auto* secondaryForwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryForward);
+ if (secondaryForwardStepper)
+ secondaryForwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonStartPart));
+ auto* secondaryBackwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::SecondaryBackward);
+ if (secondaryBackwardStepper)
+ secondaryBackwardStepper->setState(scrollbarPartStateFlags(scrollbar, BackButtonEndPart));
+ auto* forwardStepper = scrollbarWidget.stepper(RenderThemeScrollbarGadget::Steppers::Forward);
+ if (forwardStepper)
+ forwardStepper->setState(scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart));
+
+ IntSize preferredSize = scrollbarWidget.contents().preferredSize();
int thumbSize = thumbLength(scrollbar);
if (thumbSize) {
- info.name = "slider";
- info.state = scrollbarPartStateFlags(scrollbar, ThumbPart);
- sliderGadget = RenderThemeGadget::create(info, troughGadget);
- preferredSize = preferredSize.expandedTo(sliderGadget->preferredSize());
+ scrollbarWidget.slider().setState(scrollbarPartStateFlags(scrollbar, ThumbPart));
+ preferredSize = preferredSize.expandedTo(scrollbarWidget.slider().preferredSize());
}
- preferredSize += scrollbarGadget->preferredSize() - scrollbarGadget->minimumSize();
+ preferredSize += scrollbarGadget.preferredSize() - scrollbarGadget.minimumSize();
FloatRect contentsRect(rect);
// When using overlay scrollbars we always claim the size of the scrollbar when hovered, so when
@@ -544,7 +503,7 @@
// drawing the indicator we need to adjust the rectangle to its actual size in indicator mode.
if (scrollbar.orientation() == VerticalScrollbar) {
if (rect.width() != preferredSize.width()) {
- if (!scrollbarOnLeft)
+ if (!scrollbar.scrollableArea().shouldPlaceBlockDirectionScrollbarOnLeft())
contentsRect.move(std::abs(rect.width() - preferredSize.width()), 0);
contentsRect.setWidth(preferredSize.width());
}
@@ -561,17 +520,16 @@
graphicsContext.beginTransparencyLayer(opacity);
}
- scrollbarGadget->render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
- contentsGadget->render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
+ scrollbarGadget.render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
+ scrollbarWidget.contents().render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Backward)) {
- RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[0]);
+ if (backwardStepper) {
FloatRect buttonRect = contentsRect;
if (scrollbar.orientation() == VerticalScrollbar)
- buttonRect.setHeight(buttonGadget->preferredSize().height());
+ buttonRect.setHeight(backwardStepper->preferredSize().height());
else
- buttonRect.setWidth(buttonGadget->preferredSize().width());
- static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
+ buttonRect.setWidth(backwardStepper->preferredSize().width());
+ static_cast<RenderThemeScrollbarGadget&>(scrollbarGadget).renderStepper(graphicsContext.platformContext()->cr(), buttonRect, backwardStepper,
scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::Backward);
if (scrollbar.orientation() == VerticalScrollbar) {
contentsRect.move(0, buttonRect.height());
@@ -581,14 +539,13 @@
contentsRect.contract(buttonRect.width(), 0);
}
}
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
- RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[1]);
+ if (secondaryForwardStepper) {
FloatRect buttonRect = contentsRect;
if (scrollbar.orientation() == VerticalScrollbar)
- buttonRect.setHeight(buttonGadget->preferredSize().height());
+ buttonRect.setHeight(secondaryForwardStepper->preferredSize().height());
else
- buttonRect.setWidth(buttonGadget->preferredSize().width());
- static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
+ buttonRect.setWidth(secondaryForwardStepper->preferredSize().width());
+ static_cast<RenderThemeScrollbarGadget&>(scrollbarGadget).renderStepper(graphicsContext.platformContext()->cr(), buttonRect, secondaryForwardStepper,
scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::SecondaryForward);
if (scrollbar.orientation() == VerticalScrollbar) {
contentsRect.move(0, buttonRect.height());
@@ -598,36 +555,33 @@
contentsRect.contract(buttonRect.width(), 0);
}
}
-
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward)) {
- RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[3]);
+ if (secondaryBackwardStepper) {
FloatRect buttonRect = contentsRect;
if (scrollbar.orientation() == VerticalScrollbar) {
- buttonRect.setHeight(buttonGadget->preferredSize().height());
+ buttonRect.setHeight(secondaryBackwardStepper->preferredSize().height());
buttonRect.move(0, contentsRect.height() - buttonRect.height());
} else {
- buttonRect.setWidth(buttonGadget->preferredSize().width());
+ buttonRect.setWidth(secondaryBackwardStepper->preferredSize().width());
buttonRect.move(contentsRect.width() - buttonRect.width(), 0);
}
- static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
- scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::Forward);
+ static_cast<RenderThemeScrollbarGadget&>(scrollbarGadget).renderStepper(graphicsContext.platformContext()->cr(), buttonRect, secondaryBackwardStepper,
+ scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::SecondaryBackward);
if (scrollbar.orientation() == VerticalScrollbar)
contentsRect.contract(0, buttonRect.height());
else
contentsRect.contract(buttonRect.width(), 0);
}
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryBackward)) {
- RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[2]);
+ if (forwardStepper) {
FloatRect buttonRect = contentsRect;
if (scrollbar.orientation() == VerticalScrollbar) {
- buttonRect.setHeight(buttonGadget->preferredSize().height());
+ buttonRect.setHeight(forwardStepper->preferredSize().height());
buttonRect.move(0, contentsRect.height() - buttonRect.height());
} else {
- buttonRect.setWidth(buttonGadget->preferredSize().width());
+ buttonRect.setWidth(forwardStepper->preferredSize().width());
buttonRect.move(contentsRect.width() - buttonRect.width(), 0);
}
- static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
- scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::SecondaryBackward);
+ static_cast<RenderThemeScrollbarGadget&>(scrollbarGadget).renderStepper(graphicsContext.platformContext()->cr(), buttonRect, forwardStepper,
+ scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::Forward);
if (scrollbar.orientation() == VerticalScrollbar)
contentsRect.contract(0, buttonRect.height());
else
@@ -634,19 +588,20 @@
contentsRect.contract(buttonRect.width(), 0);
}
- troughGadget->render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
- if (sliderGadget) {
+ trough.render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
+
+ if (thumbSize) {
if (scrollbar.orientation() == VerticalScrollbar) {
contentsRect.move(0, thumbPosition(scrollbar));
- contentsRect.setWidth(sliderGadget->preferredSize().width());
+ contentsRect.setWidth(scrollbarWidget.slider().preferredSize().width());
contentsRect.setHeight(thumbSize);
} else {
contentsRect.move(thumbPosition(scrollbar), 0);
contentsRect.setWidth(thumbSize);
- contentsRect.setHeight(sliderGadget->preferredSize().height());
+ contentsRect.setHeight(scrollbarWidget.slider().preferredSize().height());
}
if (contentsRect.intersects(damageRect))
- sliderGadget->render(graphicsContext.platformContext()->cr(), contentsRect);
+ scrollbarWidget.slider().render(graphicsContext.platformContext()->cr(), contentsRect);
}
if (opacity != 1) {
@@ -846,33 +801,11 @@
#if GTK_CHECK_VERSION(3, 20, 0)
int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize, ScrollbarExpansionState)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Scrollbar, "scrollbar", GTK_STATE_FLAG_PRELIGHT, { "vertical", "right", "hovering" } };
- if (m_usesOverlayScrollbars)
- info.classList.append("overlay-indicator");
- auto scrollbarGadget = RenderThemeGadget::create(info);
- info.type = RenderThemeGadget::Type::Generic;
- info.name = "contents";
- info.state = GTK_STATE_FLAG_NORMAL;
- info.classList.clear();
- Vector<RenderThemeGadget::Info> children;
- auto steppers = static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->steppers();
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Backward))
- children.append({ RenderThemeGadget::Type::Generic, "button", GTK_STATE_FLAG_NORMAL, { "up" } });
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryForward))
- children.append({ RenderThemeGadget::Type::Generic, "button", GTK_STATE_FLAG_NORMAL, { "down" } });
- unsigned troughPositon = children.size();
- children.append({ RenderThemeGadget::Type::Generic, "trough", GTK_STATE_FLAG_PRELIGHT, { } });
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryBackward))
- children.append({ RenderThemeGadget::Type::Generic, "button", GTK_STATE_FLAG_NORMAL, { "up" } });
- if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward))
- children.append({ RenderThemeGadget::Type::Generic, "button", GTK_STATE_FLAG_NORMAL, { "down" } });
- auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_VERTICAL, children, scrollbarGadget.get());
- info.name = "slider";
- auto sliderGadget = RenderThemeGadget::create(info, contentsGadget->child(troughPositon));
- IntSize contentsPreferredSize = contentsGadget->preferredSize();
- contentsPreferredSize = contentsPreferredSize.expandedTo(sliderGadget->preferredSize());
- IntSize preferredSize = contentsPreferredSize + scrollbarGadget->preferredSize() - scrollbarGadget->minimumSize();
-
+ auto& scrollbarWidget = static_cast<RenderThemeScrollbar&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::VerticalScrollbarRight));
+ scrollbarWidget.scrollbar().setState(GTK_STATE_FLAG_PRELIGHT);
+ IntSize contentsPreferredSize = scrollbarWidget.contents().preferredSize();
+ contentsPreferredSize = contentsPreferredSize.expandedTo(scrollbarWidget.slider().preferredSize());
+ IntSize preferredSize = contentsPreferredSize + scrollbarWidget.scrollbar().preferredSize() - scrollbarWidget.scrollbar().minimumSize();
return preferredSize.width();
}
#else
@@ -887,18 +820,9 @@
#if GTK_CHECK_VERSION(3, 20, 0)
int ScrollbarThemeGtk::minimumThumbLength(Scrollbar& scrollbar)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Scrollbar, "scrollbar", GTK_STATE_FLAG_PRELIGHT, { "vertical", "right", "hovering" } };
- if (m_usesOverlayScrollbars)
- info.classList.append("overlay-indicator");
- auto scrollbarGadget = RenderThemeGadget::create(info);
- info.type = RenderThemeGadget::Type::Generic;
- info.name = "contents";
- info.state = GTK_STATE_FLAG_NORMAL;
- info.classList.clear();
- Vector<RenderThemeGadget::Info> children = {{ RenderThemeGadget::Type::Generic, "trough", GTK_STATE_FLAG_PRELIGHT, { } } };
- auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_VERTICAL, children, scrollbarGadget.get());
- info.name = "slider";
- IntSize minSize = RenderThemeGadget::create(info, contentsGadget->child(0))->minimumSize();
+ auto& scrollbarWidget = static_cast<RenderThemeScrollbar&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::VerticalScrollbarRight));
+ scrollbarWidget.scrollbar().setState(GTK_STATE_FLAG_PRELIGHT);
+ IntSize minSize = scrollbarWidget.slider().minimumSize();
return scrollbar.orientation() == VerticalScrollbar ? minSize.height() : minSize.width();
}
#else
Modified: trunk/Source/WebCore/rendering/RenderThemeGtk.cpp (217701 => 217702)
--- trunk/Source/WebCore/rendering/RenderThemeGtk.cpp 2017-06-02 05:55:28 UTC (rev 217701)
+++ trunk/Source/WebCore/rendering/RenderThemeGtk.cpp 2017-06-02 06:40:36 UTC (rev 217702)
@@ -44,7 +44,7 @@
#include "RenderBox.h"
#include "RenderObject.h"
#include "RenderProgress.h"
-#include "RenderThemeGadget.h"
+#include "RenderThemeWidget.h"
#include "ScrollbarThemeGtk.h"
#include "StringTruncator.h"
#include "TimeRanges.h"
@@ -185,6 +185,7 @@
switch (themePart) {
case Entry:
+ case EntrySelection:
gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_ENTRY);
break;
@@ -527,23 +528,11 @@
if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
return;
- RenderThemeGadget::Info info = {
- .type = RenderThemeGadget::Type::Generic,
- .name = themePart == CheckButton ? "checkbutton" : "radiobutton",
- .state = GTK_STATE_FLAG_NORMAL,
- .classList = { }
- };
- auto parentGadget = RenderThemeGadget::create(info);
- if (themePart == CheckButton) {
- info.type = RenderThemeGadget::Type::Check;
- info.name = "check";
- } else {
- info.type = RenderThemeGadget::Type::Radio;
- info.name = "radio";
- }
- auto gadget = RenderThemeToggleGadget::create(info);
- IntSize preferredSize = parentGadget->preferredSize();
- preferredSize = preferredSize.expandedTo(gadget->preferredSize());
+ auto& toggleWidget = static_cast<RenderThemeToggleButton&>(RenderThemeWidget::getOrCreate(themePart == CheckButton ? RenderThemeWidget::Type::CheckButton : RenderThemeWidget::Type::RadioButton));
+ toggleWidget.button().setState(GTK_STATE_FLAG_NORMAL);
+ toggleWidget.toggle().setState(GTK_STATE_FLAG_NORMAL);
+ IntSize preferredSize = toggleWidget.button().preferredSize();
+ preferredSize = preferredSize.expandedTo(toggleWidget.toggle().preferredSize());
if (style.width().isIntrinsicOrAuto())
style.setWidth(Length(preferredSize.width(), Fixed));
@@ -556,23 +545,10 @@
{
ASSERT(themePart == CheckButton || themePart == RadioButton);
- RenderThemeGadget::Info parentInfo = {
- .type = RenderThemeGadget::Type::Generic,
- .name = themePart == CheckButton ? "checkbutton" : "radiobutton",
- .state = themePartStateFlags(*theme, themePart, renderObject),
- .classList = { "text-button" }
- };
- auto parentGadget = RenderThemeGadget::create(parentInfo);
- RenderThemeGadget::Info info;
- info.state = parentInfo.state;
- if (themePart == CheckButton) {
- info.type = RenderThemeGadget::Type::Check;
- info.name = "check";
- } else {
- info.type = RenderThemeGadget::Type::Radio;
- info.name = "radio";
- }
- auto gadget = RenderThemeGadget::create(info, parentGadget.get());
+ auto& toggleWidget = static_cast<RenderThemeToggleButton&>(RenderThemeWidget::getOrCreate(themePart == CheckButton ? RenderThemeWidget::Type::CheckButton : RenderThemeWidget::Type::RadioButton));
+ auto toggleState = themePartStateFlags(*theme, themePart, renderObject);
+ toggleWidget.button().setState(toggleState);
+ toggleWidget.toggle().setState(toggleState);
FloatRect rect = fullRect;
// Some themes do not render large toggle buttons properly, so we simply
@@ -579,14 +555,14 @@
// shrink the rectangle back down to the default size and then center it
// in the full toggle button region. The reason for not simply forcing toggle
// buttons to be a smaller size is that we don't want to break site layouts.
- IntSize preferredSize = parentGadget->preferredSize();
- preferredSize = preferredSize.expandedTo(gadget->preferredSize());
+ IntSize preferredSize = toggleWidget.button().preferredSize();
+ preferredSize = preferredSize.expandedTo(toggleWidget.toggle().preferredSize());
shrinkToMinimumSizeAndCenterRectangle(rect, preferredSize);
- parentGadget->render(paintInfo.context().platformContext()->cr(), rect);
- gadget->render(paintInfo.context().platformContext()->cr(), rect);
+ toggleWidget.button().render(paintInfo.context().platformContext()->cr(), rect);
+ toggleWidget.toggle().render(paintInfo.context().platformContext()->cr(), rect);
if (theme->isFocused(renderObject))
- parentGadget->renderFocus(paintInfo.context().platformContext()->cr(), rect);
+ toggleWidget.button().renderFocus(paintInfo.context().platformContext()->cr(), rect);
}
#else
static void setToggleSize(RenderThemePart themePart, RenderStyle& style)
@@ -683,13 +659,11 @@
#if GTK_CHECK_VERSION(3, 20, 0)
bool RenderThemeGtk::paintButton(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "button", themePartStateFlags(*this, Button, renderObject), { "text-button" } };
- if (isDefault(renderObject))
- info.classList.append("default");
- auto gadget = RenderThemeGadget::create(info);
- gadget->render(paintInfo.context().platformContext()->cr(), rect);
+ auto& buttonWidget = static_cast<RenderThemeButton&>(RenderThemeWidget::getOrCreate(isDefault(renderObject) ? RenderThemeWidget::Type::ButtonDefault : RenderThemeWidget::Type::Button));
+ buttonWidget.button().setState(themePartStateFlags(*this, Button, renderObject));
+ buttonWidget.button().render(paintInfo.context().platformContext()->cr(), rect);
if (isFocused(renderObject))
- gadget->renderFocus(paintInfo.context().platformContext()->cr(), rect);
+ buttonWidget.button().renderFocus(paintInfo.context().platformContext()->cr(), rect);
return false;
}
#else
@@ -771,14 +745,11 @@
static Color menuListColor(const Element* element)
{
#if GTK_CHECK_VERSION(3, 20, 0)
- RenderThemeGadget::Info info { RenderThemeGadget::Type::Generic, "combobox", element->isDisabledFormControl() ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL, { } };
- auto comboGadget = RenderThemeGadget::create(info);
- Vector<RenderThemeGadget::Info> children {
- { RenderThemeGadget::Type::Generic, "button", info.state, { "combo" } }
- };
- info.name = "box";
- info.classList = { "horizontal", "linked" };
- return RenderThemeBoxGadget(info, GTK_ORIENTATION_HORIZONTAL, children, comboGadget.get()).child(0)->color();
+ auto& comboWidget = static_cast<RenderThemeComboBox&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::ComboBox));
+ GtkStateFlags state = element->isDisabledFormControl() ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
+ comboWidget.comboBox().setState(state);
+ comboWidget.button().setState(state);
+ return comboWidget.button().color();
#else
GRefPtr<GtkStyleContext> parentStyleContext = createStyleContext(ComboBox);
GRefPtr<GtkStyleContext> buttonStyleContext = createStyleContext(ComboBoxButton, parentStyleContext.get());
@@ -824,24 +795,14 @@
if (style.appearance() == NoControlPart)
return LengthBox(0);
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "combobox", GTK_STATE_FLAG_NORMAL, { } };
- auto comboGadget = RenderThemeGadget::create(info);
- Vector<RenderThemeGadget::Info> children = {
- { RenderThemeGadget::Type::Generic, "button", GTK_STATE_FLAG_NORMAL, { "combo" } }
- };
- info.name = "box";
- info.classList = { "horizontal", "linked" };
- auto boxGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_HORIZONTAL, children, comboGadget.get());
- RenderThemeGadget* buttonGadget = boxGadget->child(0);
- info.classList.removeLast();
- auto buttonBoxGadget = RenderThemeGadget::create(info, buttonGadget);
- info.name = "arrow";
- info.classList = { };
- auto arrowGadget = RenderThemeGadget::create(info, buttonBoxGadget.get());
- GtkBorder comboContentsBox = comboGadget->contentsBox();
- GtkBorder boxContentsBox = boxGadget->contentsBox();
- GtkBorder buttonContentsBox = buttonGadget->contentsBox();
- GtkBorder buttonBoxContentsBox = buttonBoxGadget->contentsBox();
+ auto& comboWidget = static_cast<RenderThemeComboBox&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::ComboBox));
+ comboWidget.comboBox().setState(GTK_STATE_FLAG_NORMAL);
+ comboWidget.button().setState(GTK_STATE_FLAG_NORMAL);
+ comboWidget.arrow().setState(GTK_STATE_FLAG_NORMAL);
+ GtkBorder comboContentsBox = comboWidget.comboBox().contentsBox();
+ GtkBorder boxContentsBox = comboWidget.box().contentsBox();
+ GtkBorder buttonContentsBox = comboWidget.button().contentsBox();
+ GtkBorder buttonBoxContentsBox = comboWidget.buttonBox().contentsBox();
GtkBorder padding;
padding.left = comboContentsBox.left + boxContentsBox.left + buttonContentsBox.left + buttonBoxContentsBox.left;
padding.right = comboContentsBox.right + boxContentsBox.right + buttonContentsBox.right + buttonBoxContentsBox.right;
@@ -848,7 +809,7 @@
padding.top = comboContentsBox.top + boxContentsBox.top + buttonContentsBox.top + buttonBoxContentsBox.top;
padding.bottom = comboContentsBox.bottom + boxContentsBox.bottom + buttonContentsBox.bottom + buttonBoxContentsBox.bottom;
- auto arrowSize = arrowGadget->preferredSize();
+ auto arrowSize = comboWidget.arrow().preferredSize();
return LengthBox(padding.top, padding.right + (style.direction() == LTR ? arrowSize.width() : 0),
padding.bottom, padding.left + (style.direction() == RTL ? arrowSize.width() : 0));
}
@@ -855,31 +816,21 @@
bool RenderThemeGtk::paintMenuList(const RenderObject& renderObject, const PaintInfo& paintInfo, const FloatRect& rect)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "combobox", themePartStateFlags(*this, ComboBoxButton, renderObject), { } };
- auto comboGadget = RenderThemeGadget::create(info);
- Vector<RenderThemeGadget::Info> children = {
- { RenderThemeGadget::Type::Generic, "button", info.state, { "combo" } }
- };
- info.name = "box";
- info.classList = { "horizontal", "linked" };
- auto boxGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_HORIZONTAL, children, comboGadget.get());
- RenderThemeGadget* buttonGadget = boxGadget->child(0);
- info.classList.removeLast();
- auto buttonBoxGadget = RenderThemeGadget::create(info, buttonGadget);
- info.type = RenderThemeGadget::Type::Arrow;
- info.name = "arrow";
- info.classList = { };
- auto arrowGadget = RenderThemeGadget::create(info, buttonBoxGadget.get());
+ auto& comboWidget = static_cast<RenderThemeComboBox&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::ComboBox));
+ auto comboState = themePartStateFlags(*this, ComboBoxButton, renderObject);
+ comboWidget.comboBox().setState(comboState);
+ comboWidget.button().setState(comboState);
+ comboWidget.arrow().setState(comboState);
cairo_t* cr = paintInfo.context().platformContext()->cr();
- comboGadget->render(cr, rect);
- boxGadget->render(cr, rect);
+ comboWidget.comboBox().render(cr, rect);
+ comboWidget.box().render(cr, rect);
FloatRect contentsRect;
- buttonGadget->render(cr, rect, &contentsRect);
- buttonBoxGadget->render(cr, contentsRect);
- arrowGadget->render(cr, contentsRect);
+ comboWidget.button().render(cr, rect, &contentsRect);
+ comboWidget.buttonBox().render(cr, contentsRect);
+ comboWidget.arrow().render(cr, contentsRect);
if (isFocused(renderObject))
- buttonGadget->renderFocus(cr, rect);
+ comboWidget.button().renderFocus(cr, rect);
return false;
}
@@ -986,24 +937,16 @@
return;
// Spinbuttons need a minimum height to be rendered correctly.
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "spinbutton", GTK_STATE_FLAG_NORMAL, { "horizontal" } };
- auto spinbuttonGadget = RenderThemeGadget::create(info);
- info.type = RenderThemeGadget::Type::TextField;
- info.name = "entry";
- info.classList.clear();
- auto entryGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- info.type = RenderThemeGadget::Type::Icon;
- info.name = "button";
- info.classList.append("up");
- auto buttonUpGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- static_cast<RenderThemeIconGadget*>(buttonUpGadget.get())->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
- info.classList[0] = "down";
- auto buttonDownGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- static_cast<RenderThemeIconGadget*>(buttonDownGadget.get())->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
- IntSize preferredSize = spinbuttonGadget->preferredSize();
- preferredSize = preferredSize.expandedTo(entryGadget->preferredSize());
- IntSize upPreferredSize = preferredSize.expandedTo(buttonUpGadget->preferredSize());
- IntSize downPreferredSize = preferredSize.expandedTo(buttonDownGadget->preferredSize());
+ 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());
int height = std::max(upPreferredSize.height(), downPreferredSize.height());
style.setMinHeight(Length(height, Fixed));
}
@@ -1010,20 +953,18 @@
bool RenderThemeGtk::paintTextField(const RenderObject& renderObject, const PaintInfo& paintInfo, const FloatRect& rect)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::TextField, "entry", themePartStateFlags(*this, Entry, renderObject), { } };
- std::unique_ptr<RenderThemeGadget> parentGadget;
if (is<HTMLInputElement>(renderObject.node()) && shouldHaveSpinButton(downcast<HTMLInputElement>(*renderObject.node()))) {
- info.name = "spinbutton";
- info.classList.append("horizontal");
- parentGadget = RenderThemeTextFieldGadget::create(info);
- info.name = "entry";
- info.classList.clear();
+ 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 entryGadget = RenderThemeTextFieldGadget::create(info, parentGadget.get());
- if (parentGadget)
- parentGadget->render(paintInfo.context().platformContext()->cr(), rect);
- entryGadget->render(paintInfo.context().platformContext()->cr(), rect);
return false;
}
#else
@@ -1065,20 +1006,16 @@
static void adjustSearchFieldIconStyle(RenderThemePart themePart, RenderStyle& style)
{
ASSERT(themePart == EntryIconLeft || themePart == EntryIconRight);
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::TextField, "entry", GTK_STATE_FLAG_NORMAL, { } };
- auto parentGadget = RenderThemeGadget::create(info);
- info.type = RenderThemeGadget::Type::Icon;
- info.name = "image";
- if (themePart == EntryIconLeft)
- info.classList.append("left");
- else
- info.classList.append("right");
- auto gadget = RenderThemeIconGadget::create(info, parentGadget.get());
+ auto& searchEntryWidget = static_cast<RenderThemeSearchEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::SearchEntry));
+ searchEntryWidget.entry().setState(GTK_STATE_FLAG_NORMAL);
+ searchEntryWidget.leftIcon().setState(GTK_STATE_FLAG_NORMAL);
+ searchEntryWidget.rightIcon().setState(GTK_STATE_FLAG_NORMAL);
// Get the icon size based on the font size.
- static_cast<RenderThemeIconGadget*>(gadget.get())->setIconSize(style.fontSize());
- IntSize preferredSize = gadget->preferredSize();
- GtkBorder contentsBox = parentGadget->contentsBox();
+ auto& icon = static_cast<RenderThemeIconGadget&>(themePart == EntryIconLeft ? searchEntryWidget.leftIcon() : searchEntryWidget.rightIcon());
+ icon.setIconSize(style.fontSize());
+ IntSize preferredSize = icon.preferredSize();
+ GtkBorder contentsBox = searchEntryWidget.entry().contentsBox();
if (themePart == EntryIconLeft)
preferredSize.expand(contentsBox.left, contentsBox.top + contentsBox.bottom);
else
@@ -1165,23 +1102,12 @@
static bool paintSearchFieldIcon(RenderThemeGtk* theme, RenderThemePart themePart, const RenderBox& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
{
ASSERT(themePart == EntryIconLeft || themePart == EntryIconRight);
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::TextField, "entry", themePartStateFlags(*theme, Entry, renderObject), { } };
- auto parentGadget = RenderThemeGadget::create(info);
- info.type = RenderThemeGadget::Type::Icon;
- info.state = themePartStateFlags(*theme, themePart, renderObject);
- info.name = "image";
- if (themePart == EntryIconLeft)
- info.classList.append("left");
- else
- info.classList.append("right");
- auto gadget = RenderThemeGadget::create(info, parentGadget.get());
- auto* gadgetIcon = static_cast<RenderThemeIconGadget*>(gadget.get());
- gadgetIcon->setIconSize(renderObject.style().fontSize());
- if (themePart == EntryIconLeft)
- gadgetIcon->setIconName("edit-find-symbolic");
- else
- gadgetIcon->setIconName("edit-clear-symbolic");
- GtkBorder contentsBox = parentGadget->contentsBox();
+ auto& searchEntryWidget = static_cast<RenderThemeSearchEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::SearchEntry));
+ searchEntryWidget.entry().setState(themePartStateFlags(*theme, Entry, renderObject));
+ auto& icon = static_cast<RenderThemeIconGadget&>(themePart == EntryIconLeft ? searchEntryWidget.leftIcon() : searchEntryWidget.rightIcon());
+ icon.setState(themePartStateFlags(*theme, themePart, renderObject));
+ icon.setIconSize(renderObject.style().fontSize());
+ GtkBorder contentsBox = searchEntryWidget.entry().contentsBox();
IntRect iconRect = rect;
if (themePart == EntryIconLeft) {
iconRect.move(contentsBox.left, contentsBox.top);
@@ -1188,7 +1114,7 @@
iconRect.contract(contentsBox.left, contentsBox.top + contentsBox.bottom);
} else
iconRect.contract(contentsBox.right, contentsBox.top + contentsBox.bottom);
- return !gadget->render(paintInfo.context().platformContext()->cr(), iconRect);
+ return !icon.render(paintInfo.context().platformContext()->cr(), iconRect);
}
bool RenderThemeGtk::paintSearchFieldResultsDecorationPart(const RenderBox& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
{
@@ -1309,26 +1235,20 @@
ControlPart part = renderObject.style().appearance();
ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart);
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "scale", themePartStateFlags(*this, Scale, renderObject), { } };
- if (part == SliderHorizontalPart)
- info.classList.append("horizontal");
- else
- info.classList.append("vertical");
- auto scaleGadget = RenderThemeGadget::create(info);
- info.name = "contents";
- info.classList.clear();
- auto contentsGadget = RenderThemeGadget::create(info, scaleGadget.get());
- info.name = "trough";
- auto troughGadget = RenderThemeGadget::create(info, contentsGadget.get());
- info.name = "slider";
- auto sliderGadget = RenderThemeGadget::create(info, troughGadget.get());
- info.name = "highlight";
- auto highlightGadget = RenderThemeGadget::create(info, troughGadget.get());
+ auto& sliderWidget = static_cast<RenderThemeSlider&>(RenderThemeWidget::getOrCreate(part == SliderHorizontalPart ? RenderThemeWidget::Type::HorizontalSlider : RenderThemeWidget::Type::VerticalSlider));
+ auto scaleState = themePartStateFlags(*this, Scale, renderObject);
+ auto& scale = sliderWidget.scale();
+ scale.setState(scaleState);
+ auto& contents = sliderWidget.contents();
+ auto& trough = sliderWidget.trough();
+ trough.setState(scaleState);
+ auto& slider = sliderWidget.slider();
+ auto& highlight = sliderWidget.highlight();
// The given rectangle is not calculated based on the scale size, but all the margins and paddings are based on it.
- IntSize preferredSize = scaleGadget->preferredSize();
- preferredSize = preferredSize.expandedTo(contentsGadget->preferredSize());
- preferredSize = preferredSize.expandedTo(troughGadget->preferredSize());
+ IntSize preferredSize = scale.preferredSize();
+ preferredSize = preferredSize.expandedTo(contents.preferredSize());
+ preferredSize = preferredSize.expandedTo(trough.preferredSize());
FloatRect trackRect = rect;
if (part == SliderHorizontalPart) {
trackRect.move(0, rect.height() / 2 - (preferredSize.height() / 2));
@@ -1339,17 +1259,17 @@
}
FloatRect contentsRect;
- scaleGadget->render(paintInfo.context().platformContext()->cr(), trackRect, &contentsRect);
- contentsGadget->render(paintInfo.context().platformContext()->cr(), contentsRect, &contentsRect);
+ scale.render(paintInfo.context().platformContext()->cr(), trackRect, &contentsRect);
+ contents.render(paintInfo.context().platformContext()->cr(), contentsRect, &contentsRect);
// Scale trough defines its size querying slider and highlight.
if (part == SliderHorizontalPart)
- contentsRect.setHeight(troughGadget->preferredSize().height() + std::max(sliderGadget->preferredSize().height(), highlightGadget->preferredSize().height()));
+ contentsRect.setHeight(trough.preferredSize().height() + std::max(slider.preferredSize().height(), highlight.preferredSize().height()));
else
- contentsRect.setWidth(troughGadget->preferredSize().width() + std::max(sliderGadget->preferredSize().width(), highlightGadget->preferredSize().width()));
+ contentsRect.setWidth(trough.preferredSize().width() + std::max(slider.preferredSize().width(), highlight.preferredSize().width()));
FloatRect troughRect = contentsRect;
- troughGadget->render(paintInfo.context().platformContext()->cr(), troughRect, &contentsRect);
+ trough.render(paintInfo.context().platformContext()->cr(), troughRect, &contentsRect);
if (isFocused(renderObject))
- troughGadget->renderFocus(paintInfo.context().platformContext()->cr(), troughRect);
+ trough.renderFocus(paintInfo.context().platformContext()->cr(), troughRect);
LayoutPoint thumbLocation;
if (is<HTMLInputElement>(renderObject.node())) {
@@ -1366,7 +1286,7 @@
contentsRect.setWidth(thumbLocation.x());
} else
contentsRect.setHeight(thumbLocation.y());
- highlightGadget->render(paintInfo.context().platformContext()->cr(), contentsRect);
+ highlight.render(paintInfo.context().platformContext()->cr(), contentsRect);
return false;
}
@@ -1377,26 +1297,14 @@
if (part != SliderThumbHorizontalPart && part != SliderThumbVerticalPart)
return;
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "scale", GTK_STATE_FLAG_NORMAL, { } };
- if (part == SliderHorizontalPart)
- info.classList.append("horizontal");
- else
- info.classList.append("vertical");
- auto scaleGadget = RenderThemeGadget::create(info);
- info.name = "contents";
- info.classList.clear();
- auto contentsGadget = RenderThemeGadget::create(info, scaleGadget.get());
- info.name = "trough";
- auto troughGadget = RenderThemeGadget::create(info, contentsGadget.get());
- info.name = "slider";
- auto sliderGadget = RenderThemeGadget::create(info, troughGadget.get());
- info.name = "highlight";
- auto highlightGadget = RenderThemeGadget::create(info, troughGadget.get());
+ auto& sliderWidget = static_cast<RenderThemeSlider&>(RenderThemeWidget::getOrCreate(part == SliderHorizontalPart ? RenderThemeWidget::Type::HorizontalSlider : RenderThemeWidget::Type::VerticalSlider));
+ sliderWidget.scale().setState(GTK_STATE_FLAG_NORMAL);
+ sliderWidget.trough().setState(GTK_STATE_FLAG_NORMAL);
- IntSize preferredSize = scaleGadget->preferredSize();
- preferredSize = preferredSize.expandedTo(contentsGadget->preferredSize());
- preferredSize = preferredSize.expandedTo(troughGadget->preferredSize());
- preferredSize = preferredSize.expandedTo(sliderGadget->preferredSize());
+ IntSize preferredSize = sliderWidget.scale().preferredSize();
+ preferredSize = preferredSize.expandedTo(sliderWidget.contents().preferredSize());
+ preferredSize = preferredSize.expandedTo(sliderWidget.trough().preferredSize());
+ preferredSize = preferredSize.expandedTo(sliderWidget.slider().preferredSize());
if (part == SliderThumbHorizontalPart) {
style.setWidth(Length(preferredSize.width(), Fixed));
style.setHeight(Length(preferredSize.height(), Fixed));
@@ -1412,26 +1320,20 @@
ControlPart part = renderObject.style().appearance();
ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart);
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "scale", themePartStateFlags(*this, Scale, renderObject), { } };
- if (part == SliderHorizontalPart)
- info.classList.append("horizontal");
- else
- info.classList.append("vertical");
- auto scaleGadget = RenderThemeGadget::create(info);
- info.name = "contents";
- info.classList.clear();
- auto contentsGadget = RenderThemeGadget::create(info, scaleGadget.get());
- info.name = "trough";
- auto troughGadget = RenderThemeGadget::create(info, contentsGadget.get());
- info.name = "slider";
- info.state = themePartStateFlags(*this, ScaleSlider, renderObject);
- auto sliderGadget = RenderThemeGadget::create(info, troughGadget.get());
- info.name = "highlight";
- auto highlightGadget = RenderThemeGadget::create(info, troughGadget.get());
+ auto& sliderWidget = static_cast<RenderThemeSlider&>(RenderThemeWidget::getOrCreate(part == SliderThumbHorizontalPart ? RenderThemeWidget::Type::HorizontalSlider : RenderThemeWidget::Type::VerticalSlider));
+ auto scaleState = themePartStateFlags(*this, Scale, renderObject);
+ auto& scale = sliderWidget.scale();
+ scale.setState(scaleState);
+ auto& contents = sliderWidget.contents();
+ auto& trough = sliderWidget.trough();
+ trough.setState(scaleState);
+ auto& slider = sliderWidget.slider();
+ slider.setState(themePartStateFlags(*this, ScaleSlider, renderObject));
+ auto& highlight = sliderWidget.highlight();
- GtkBorder scaleContentsBox = scaleGadget->contentsBox();
- GtkBorder contentsContentsBox = contentsGadget->contentsBox();
- GtkBorder troughContentsBox = troughGadget->contentsBox();
+ GtkBorder scaleContentsBox = scale.contentsBox();
+ GtkBorder contentsContentsBox = contents.contentsBox();
+ GtkBorder troughContentsBox = trough.contentsBox();
GtkBorder padding;
padding.left = scaleContentsBox.left + contentsContentsBox.left + troughContentsBox.left;
padding.right = scaleContentsBox.right + contentsContentsBox.right + troughContentsBox.right;
@@ -1439,11 +1341,11 @@
padding.bottom = scaleContentsBox.bottom + contentsContentsBox.bottom + troughContentsBox.bottom;
// Scale trough defines its size querying slider and highlight.
- int troughHeight = troughGadget->preferredSize().height() + std::max(sliderGadget->preferredSize().height(), highlightGadget->preferredSize().height());
+ int troughHeight = trough.preferredSize().height() + std::max(slider.preferredSize().height(), highlight.preferredSize().height());
IntRect sliderRect(rect.location(), IntSize(troughHeight, troughHeight));
sliderRect.move(padding.left, padding.top);
sliderRect.contract(padding.left + padding.right, padding.top + padding.bottom);
- sliderGadget->render(paintInfo.context().platformContext()->cr(), sliderRect);
+ slider.render(paintInfo.context().platformContext()->cr(), sliderRect);
return false;
}
#else
@@ -1540,23 +1442,11 @@
#if GTK_CHECK_VERSION(3, 20, 0)
IntRect RenderThemeGtk::progressBarRectForBounds(const RenderObject& renderObject, const IntRect& bounds) const
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "progressbar", GTK_STATE_FLAG_NORMAL, { "horizontal" } };
- auto progressBarGadget = RenderThemeGadget::create(info);
- info.name = "trough";
- info.classList.clear();
- auto troughGadget = RenderThemeGadget::create(info, progressBarGadget.get());
- info.name = "progress";
- if (renderObject.style().direction() == RTL)
- info.classList.append("right");
- else
- info.classList.append("left");
const auto& renderProgress = downcast<RenderProgress>(renderObject);
- if (renderProgress.isDeterminate())
- info.classList.append("pulse");
- auto progressGadget = RenderThemeGadget::create(info, troughGadget.get());
- IntSize preferredSize = progressBarGadget->preferredSize();
- preferredSize = preferredSize.expandedTo(troughGadget->preferredSize());
- preferredSize = preferredSize.expandedTo(progressGadget->preferredSize());
+ auto& progressBarWidget = static_cast<RenderThemeProgressBar&>(RenderThemeWidget::getOrCreate(renderProgress.isDeterminate() ? RenderThemeProgressBar::Type::ProgressBar : RenderThemeProgressBar::Type::IndeterminateProgressBar));
+ IntSize preferredSize = progressBarWidget.progressBar().preferredSize();
+ preferredSize = preferredSize.expandedTo(progressBarWidget.trough().preferredSize());
+ preferredSize = preferredSize.expandedTo(progressBarWidget.progress().preferredSize());
return IntRect(bounds.x(), bounds.y(), bounds.width(), preferredSize.height());
}
@@ -1565,24 +1455,11 @@
if (!renderObject.isProgress())
return true;
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "progressbar", GTK_STATE_FLAG_NORMAL, { "horizontal" } };
- auto progressBarGadget = RenderThemeGadget::create(info);
- info.name = "trough";
- info.classList.clear();
- auto troughGadget = RenderThemeGadget::create(info, progressBarGadget.get());
- info.name = "progress";
- if (renderObject.style().direction() == RTL)
- info.classList.append("right");
- else
- info.classList.append("left");
const auto& renderProgress = downcast<RenderProgress>(renderObject);
- if (renderProgress.isDeterminate())
- info.classList.append("pulse");
- auto progressGadget = RenderThemeGadget::create(info, troughGadget.get());
-
- progressBarGadget->render(paintInfo.context().platformContext()->cr(), rect);
- troughGadget->render(paintInfo.context().platformContext()->cr(), rect);
- progressGadget->render(paintInfo.context().platformContext()->cr(), calculateProgressRect(renderObject, rect));
+ auto& progressBarWidget = static_cast<RenderThemeProgressBar&>(RenderThemeWidget::getOrCreate(renderProgress.isDeterminate() ? RenderThemeProgressBar::Type::ProgressBar : RenderThemeProgressBar::Type::IndeterminateProgressBar));
+ progressBarWidget.progressBar().render(paintInfo.context().platformContext()->cr(), rect);
+ progressBarWidget.trough().render(paintInfo.context().platformContext()->cr(), rect);
+ progressBarWidget.progress().render(paintInfo.context().platformContext()->cr(), calculateProgressRect(renderObject, rect));
return false;
}
#else
@@ -1635,22 +1512,14 @@
void RenderThemeGtk::adjustInnerSpinButtonStyle(StyleResolver&, RenderStyle& style, const Element*) const
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "spinbutton", GTK_STATE_FLAG_NORMAL, { "horizontal" } };
- auto spinbuttonGadget = RenderThemeGadget::create(info);
- info.type = RenderThemeGadget::Type::TextField;
- info.name = "entry";
- info.classList.clear();
- auto entryGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- info.type = RenderThemeGadget::Type::Icon;
- info.name = "button";
- info.classList.append("up");
- auto buttonUpGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- static_cast<RenderThemeIconGadget*>(buttonUpGadget.get())->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
- info.classList[0] = "down";
- auto buttonDownGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- static_cast<RenderThemeIconGadget*>(buttonDownGadget.get())->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
- IntSize upPreferredSize = buttonUpGadget->preferredSize();
- IntSize downPreferredSize = buttonDownGadget->preferredSize();
+ 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 upPreferredSize = spinButtonWidget.up().preferredSize();
+ IntSize downPreferredSize = spinButtonWidget.down().preferredSize();
int buttonSize = std::max(std::max(upPreferredSize.width(), downPreferredSize.width()), std::max(upPreferredSize.height(), downPreferredSize.height()));
style.setWidth(Length(buttonSize * 2, Fixed));
style.setHeight(Length(buttonSize, Fixed));
@@ -1658,38 +1527,26 @@
bool RenderThemeGtk::paintInnerSpinButton(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "spinbutton", themePartStateFlags(*this, SpinButton, renderObject), { } };
- auto spinbuttonGadget = RenderThemeGadget::create(info);
- info.type = RenderThemeGadget::Type::TextField;
- info.name = "entry";
- info.classList.clear();
- auto entryGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- info.type = RenderThemeGadget::Type::Icon;
- info.name = "button";
- info.classList.append("up");
- info.state = themePartStateFlags(*this, SpinButtonUpButton, renderObject);
- auto buttonUpGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- auto* gadgetIcon = static_cast<RenderThemeIconGadget*>(buttonUpGadget.get());
- gadgetIcon->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
- gadgetIcon->setIconName("list-add-symbolic");
- info.classList[0] = "down";
- info.state = themePartStateFlags(*this, SpinButtonDownButton, renderObject);
- auto buttonDownGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
- gadgetIcon = static_cast<RenderThemeIconGadget*>(buttonDownGadget.get());
- gadgetIcon->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
- gadgetIcon->setIconName("list-remove-symbolic");
+ 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();
+ down.setState(themePartStateFlags(*this, SpinButtonDownButton, renderObject));
IntRect iconRect = rect;
iconRect.setWidth(iconRect.width() / 2);
if (renderObject.style().direction() == RTL)
- buttonUpGadget->render(paintInfo.context().platformContext()->cr(), iconRect);
+ up.render(paintInfo.context().platformContext()->cr(), iconRect);
else
- buttonDownGadget->render(paintInfo.context().platformContext()->cr(), iconRect);
+ down.render(paintInfo.context().platformContext()->cr(), iconRect);
iconRect.move(iconRect.width(), 0);
if (renderObject.style().direction() == RTL)
- buttonDownGadget->render(paintInfo.context().platformContext()->cr(), iconRect);
+ down.render(paintInfo.context().platformContext()->cr(), iconRect);
else
- buttonUpGadget->render(paintInfo.context().platformContext()->cr(), iconRect);
+ up.render(paintInfo.context().platformContext()->cr(), iconRect);
return false;
}
@@ -1822,35 +1679,27 @@
#if GTK_CHECK_VERSION(3, 20, 0)
static Color styleColor(RenderThemePart themePart, GtkStateFlags state, StyleColorType colorType)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, nullptr, state, { } };
- std::unique_ptr<RenderThemeGadget> parentGadget;
- RenderThemePart part = themePart;
- if (themePart == Entry && (state & GTK_STATE_FLAG_SELECTED)) {
- info.name = "entry";
- parentGadget = RenderThemeGadget::create(info);
- part = EntrySelection;
- }
-
- switch (part) {
+ RenderThemeGadget* gadget = nullptr;
+ switch (themePart) {
+ default:
+ ASSERT_NOT_REACHED();
+ FALLTHROUGH;
case Entry:
- info.name = "entry";
+ gadget = &static_cast<RenderThemeEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::Entry)).entry();
break;
case EntrySelection:
- info.name = "selection";
+ gadget = static_cast<RenderThemeEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::SelectedEntry)).selection();
break;
case ListBox:
- info.name = "treeview";
- info.classList.append("view");
+ gadget = &static_cast<RenderThemeListView&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::ListView)).treeview();
break;
case Button:
- info.name = "button";
+ gadget = &static_cast<RenderThemeButton&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::Button)).button();
break;
- default:
- ASSERT_NOT_REACHED();
- info.name = "entry";
}
- auto gadget = RenderThemeGadget::create(info, parentGadget.get());
+ ASSERT(gadget);
+ gadget->setState(state);
return colorType == StyleColorBackground ? gadget->backgroundColor() : gadget->color();
}
#else
@@ -1870,22 +1719,22 @@
Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const
{
- return styleColor(Entry, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorBackground);
+ return styleColor(EntrySelection, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorBackground);
}
Color RenderThemeGtk::platformInactiveSelectionBackgroundColor() const
{
- return styleColor(Entry, GTK_STATE_FLAG_SELECTED, StyleColorBackground);
+ return styleColor(EntrySelection, GTK_STATE_FLAG_SELECTED, StyleColorBackground);
}
Color RenderThemeGtk::platformActiveSelectionForegroundColor() const
{
- return styleColor(Entry, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorForeground);
+ return styleColor(EntrySelection, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorForeground);
}
Color RenderThemeGtk::platformInactiveSelectionForegroundColor() const
{
- return styleColor(Entry, GTK_STATE_FLAG_SELECTED, StyleColorForeground);
+ return styleColor(EntrySelection, GTK_STATE_FLAG_SELECTED, StyleColorForeground);
}
Color RenderThemeGtk::platformActiveListBoxSelectionBackgroundColor() const
@@ -1941,12 +1790,12 @@
#if GTK_CHECK_VERSION(3, 20, 0)
bool RenderThemeGtk::paintMediaButton(const RenderObject& renderObject, GraphicsContext& graphicsContext, const IntRect& rect, const char* iconName)
{
- RenderThemeGadget::Info info = { RenderThemeGadget::Type::Icon, "image", themePartStateFlags(*this, MediaButton, renderObject), { } };
- auto gadget = RenderThemeGadget::create(info);
- auto* gadgetIcon = static_cast<RenderThemeIconGadget*>(gadget.get());
- gadgetIcon->setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
- gadgetIcon->setIconName(iconName);
- return !gadget->render(graphicsContext.platformContext()->cr(), rect);
+ auto& iconWidget = static_cast<RenderThemeIcon&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::Icon));
+ auto& icon = static_cast<RenderThemeIconGadget&>(iconWidget.icon());
+ icon.setState(themePartStateFlags(*this, MediaButton, renderObject));
+ icon.setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+ icon.setIconName(iconName);
+ return !icon.render(graphicsContext.platformContext()->cr(), rect);
}
#else
bool RenderThemeGtk::paintMediaButton(const RenderObject& renderObject, GraphicsContext& graphicsContext, const IntRect& rect, const char* iconName)