source: webkit/trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp @ 186680

Last change on this file since 186680 was 185964, checked in by andersca@apple.com, 3 years ago

Stop using ScrollbarThemeClient and just use Scrollbar directly
https://bugs.webkit.org/show_bug.cgi?id=146320

Reviewed by Tim Horton.

  • page/scrolling/mac/ScrollingStateFrameScrollingNodeMac.mm:

(WebCore::ScrollingStateFrameScrollingNode::setScrollbarPaintersFromScrollbars):

  • platform/ScrollableArea.cpp:

(WebCore::ScrollableArea::setScrollbarOverlayStyle):

  • platform/Scrollbar.cpp:

(WebCore::Scrollbar::Scrollbar):
(WebCore::Scrollbar::~Scrollbar):
(WebCore::Scrollbar::offsetDidChange):
(WebCore::Scrollbar::updateThumb):
(WebCore::Scrollbar::paint):
(WebCore::thumbUnderMouse):
(WebCore::Scrollbar::autoscrollPressedPart):
(WebCore::Scrollbar::startTimerIfNeeded):
(WebCore::Scrollbar::moveThumb):
(WebCore::Scrollbar::setHoveredPart):
(WebCore::Scrollbar::setPressedPart):
(WebCore::Scrollbar::mouseMoved):
(WebCore::Scrollbar::mouseUp):
(WebCore::Scrollbar::mouseDown):
(WebCore::Scrollbar::setEnabled):

  • platform/ScrollbarTheme.h:

(WebCore::ScrollbarTheme::updateEnabledState):
(WebCore::ScrollbarTheme::paint):
(WebCore::ScrollbarTheme::hitTest):
(WebCore::ScrollbarTheme::updateScrollbarOverlayStyle):
(WebCore::ScrollbarTheme::invalidateParts):
(WebCore::ScrollbarTheme::invalidatePart):
(WebCore::ScrollbarTheme::paintTickmarks):
(WebCore::ScrollbarTheme::shouldCenterOnThumb):
(WebCore::ScrollbarTheme::shouldSnapBackToDragOrigin):
(WebCore::ScrollbarTheme::shouldDragDocumentInsteadOfThumb):
(WebCore::ScrollbarTheme::thumbPosition):
(WebCore::ScrollbarTheme::thumbLength):
(WebCore::ScrollbarTheme::trackPosition):
(WebCore::ScrollbarTheme::trackLength):
(WebCore::ScrollbarTheme::registerScrollbar):
(WebCore::ScrollbarTheme::unregisterScrollbar):

  • platform/ScrollbarThemeComposite.cpp:

(WebCore::ScrollbarThemeComposite::paint):
(WebCore::ScrollbarThemeComposite::hitTest):
(WebCore::ScrollbarThemeComposite::invalidatePart):
(WebCore::ScrollbarThemeComposite::splitTrack):
(WebCore::usedTotalSize):
(WebCore::ScrollbarThemeComposite::thumbPosition):
(WebCore::ScrollbarThemeComposite::thumbLength):
(WebCore::ScrollbarThemeComposite::minimumThumbLength):
(WebCore::ScrollbarThemeComposite::trackPosition):
(WebCore::ScrollbarThemeComposite::trackLength):
(WebCore::ScrollbarThemeComposite::thumbRect):

  • platform/ScrollbarThemeComposite.h:

(WebCore::ScrollbarThemeComposite::willPaintScrollbar):
(WebCore::ScrollbarThemeComposite::didPaintScrollbar):
(WebCore::ScrollbarThemeComposite::paintScrollbarBackground):
(WebCore::ScrollbarThemeComposite::paintTrackBackground):
(WebCore::ScrollbarThemeComposite::paintTrackPiece):
(WebCore::ScrollbarThemeComposite::paintButton):
(WebCore::ScrollbarThemeComposite::paintThumb):
(WebCore::ScrollbarThemeComposite::constrainTrackRectToTrackPieces):

  • platform/efl/ScrollbarThemeEfl.h:
  • platform/gtk/ScrollbarThemeGtk.cpp:

(WebCore::ScrollbarThemeGtk::hasThumb):
(WebCore::ScrollbarThemeGtk::backButtonRect):
(WebCore::ScrollbarThemeGtk::forwardButtonRect):
(WebCore::ScrollbarThemeGtk::trackRect):
(WebCore::ScrollbarThemeGtk::registerScrollbar):
(WebCore::ScrollbarThemeGtk::unregisterScrollbar):
(WebCore::ScrollbarThemeGtk::updateScrollbarsFrameThickness):
(WebCore::ScrollbarThemeGtk::thumbRect):
(WebCore::ScrollbarThemeGtk::paintTrackBackground):
(WebCore::ScrollbarThemeGtk::paintScrollbarBackground):
(WebCore::ScrollbarThemeGtk::paintThumb):
(WebCore::ScrollbarThemeGtk::paintButton):
(WebCore::ScrollbarThemeGtk::paint):
(WebCore::ScrollbarThemeGtk::shouldCenterOnThumb):
(WebCore::ScrollbarThemeGtk::buttonSize):
(WebCore::ScrollbarThemeGtk::minimumThumbLength):

  • platform/gtk/ScrollbarThemeGtk.h:

(WebCore::ScrollbarThemeGtk::hasButtons):

  • platform/ios/ScrollbarThemeIOS.h:
  • platform/ios/ScrollbarThemeIOS.mm:

(WebCore::ScrollbarThemeIOS::registerScrollbar):
(WebCore::ScrollbarThemeIOS::unregisterScrollbar):
(WebCore::ScrollbarThemeIOS::hasButtons):
(WebCore::ScrollbarThemeIOS::hasThumb):
(WebCore::ScrollbarThemeIOS::backButtonRect):
(WebCore::ScrollbarThemeIOS::forwardButtonRect):
(WebCore::ScrollbarThemeIOS::trackRect):
(WebCore::ScrollbarThemeIOS::minimumThumbLength):
(WebCore::ScrollbarThemeIOS::shouldCenterOnThumb):
(WebCore::ScrollbarThemeIOS::paint):

  • platform/mac/ScrollAnimatorMac.mm:

(scrollbarPainterForScrollbar):
(-[WebScrollbarPainterControllerDelegate scrollerImpPair:convertContentPoint:toScrollerImp:]):
(-[WebScrollbarPartAnimation startAnimation]):
(-[WebScrollbarPainterDelegate mouseLocationInScrollerForScrollerImp:]):
(-[WebScrollbarPainterDelegate setUpAlphaAnimation:scrollerPainter:part:animateAlphaTo:duration:]):
(-[WebScrollbarPainterDelegate scrollerImp:animateKnobAlphaTo:duration:]):
(-[WebScrollbarPainterDelegate scrollerImp:animateTrackAlphaTo:duration:]):
(-[WebScrollbarPainterDelegate scrollerImp:animateUIStateTransitionWithDuration:]):
(-[WebScrollbarPainterDelegate scrollerImp:animateExpansionTransitionWithDuration:]):
(WebCore::ScrollAnimatorMac::mouseEnteredScrollbar):
(WebCore::ScrollAnimatorMac::mouseExitedScrollbar):
(WebCore::ScrollAnimatorMac::didAddVerticalScrollbar):
(WebCore::ScrollAnimatorMac::willRemoveVerticalScrollbar):
(WebCore::ScrollAnimatorMac::didAddHorizontalScrollbar):
(WebCore::ScrollAnimatorMac::willRemoveHorizontalScrollbar):
(WebCore::ScrollAnimatorMac::invalidateScrollbarPartLayers):
(WebCore::ScrollAnimatorMac::verticalScrollbarLayerDidChange):
(WebCore::ScrollAnimatorMac::horizontalScrollbarLayerDidChange):
(WebCore::ScrollAnimatorMac::shouldScrollbarParticipateInHitTesting):
(WebCore::ScrollAnimatorMac::updateScrollerStyle):

  • platform/mac/ScrollbarThemeMac.h:
  • platform/mac/ScrollbarThemeMac.mm:

(WebCore::ScrollbarThemeMac::registerScrollbar):
(WebCore::ScrollbarThemeMac::unregisterScrollbar):
(WebCore::ScrollbarThemeMac::setNewPainterForScrollbar):
(WebCore::ScrollbarThemeMac::painterForScrollbar):
(WebCore::ScrollbarThemeMac::updateScrollbarOverlayStyle):
(WebCore::ScrollbarThemeMac::hasButtons):
(WebCore::ScrollbarThemeMac::hasThumb):
(WebCore::ScrollbarThemeMac::backButtonRect):
(WebCore::ScrollbarThemeMac::forwardButtonRect):
(WebCore::ScrollbarThemeMac::trackRect):
(WebCore::ScrollbarThemeMac::minimumThumbLength):
(WebCore::ScrollbarThemeMac::shouldCenterOnThumb):
(WebCore::ScrollbarThemeMac::shouldDragDocumentInsteadOfThumb):
(WebCore::ScrollbarThemeMac::updateEnabledState):
(WebCore::ScrollbarThemeMac::setPaintCharacteristicsForScrollbar):
(WebCore::ScrollbarThemeMac::paint):

  • platform/mock/ScrollbarThemeMock.cpp:

(WebCore::ScrollbarThemeMock::trackRect):
(WebCore::ScrollbarThemeMock::paintTrackBackground):
(WebCore::ScrollbarThemeMock::paintThumb):

  • platform/mock/ScrollbarThemeMock.h:

(WebCore::ScrollbarThemeMock::hasButtons): Deleted.
(WebCore::ScrollbarThemeMock::hasThumb): Deleted.
(WebCore::ScrollbarThemeMock::backButtonRect): Deleted.
(WebCore::ScrollbarThemeMock::forwardButtonRect): Deleted.
(WebCore::ScrollbarThemeMock::maxOverlapBetweenPages): Deleted.
(WebCore::ScrollbarThemeMock::isMockTheme): Deleted.

  • platform/win/ScrollbarThemeSafari.cpp:

(WebCore::ScrollbarThemeSafari::hasButtons):
(WebCore::ScrollbarThemeSafari::hasThumb):
(WebCore::ScrollbarThemeSafari::backButtonRect):
(WebCore::ScrollbarThemeSafari::forwardButtonRect):
(WebCore::ScrollbarThemeSafari::trackRect):
(WebCore::ScrollbarThemeSafari::minimumThumbLength):
(WebCore::ScrollbarThemeSafari::shouldCenterOnThumb):
(WebCore::ScrollbarThemeSafari::paintTrackBackground):
(WebCore::ScrollbarThemeSafari::paintButton):
(WebCore::ScrollbarThemeSafari::paintThumb):

  • platform/win/ScrollbarThemeSafari.h:
  • platform/win/ScrollbarThemeWin.cpp:

(WebCore::ScrollbarThemeWin::hasThumb):
(WebCore::ScrollbarThemeWin::backButtonRect):
(WebCore::ScrollbarThemeWin::forwardButtonRect):
(WebCore::ScrollbarThemeWin::trackRect):
(WebCore::ScrollbarThemeWin::shouldCenterOnThumb):
(WebCore::ScrollbarThemeWin::shouldSnapBackToDragOrigin):
(WebCore::ScrollbarThemeWin::paintTrackBackground):
(WebCore::ScrollbarThemeWin::paintTrackPiece):
(WebCore::ScrollbarThemeWin::paintButton):
(WebCore::paintGripper):
(WebCore::ScrollbarThemeWin::paintThumb):

  • platform/win/ScrollbarThemeWin.h:
  • rendering/RenderScrollbar.h:

(isType):

  • rendering/RenderScrollbarPart.cpp:

(WebCore::RenderScrollbarPart::styleDidChange):
(WebCore::RenderScrollbarPart::imageChanged):

  • rendering/RenderScrollbarTheme.cpp:

(WebCore::RenderScrollbarTheme::buttonSizesAlongTrackAxis):
(WebCore::RenderScrollbarTheme::hasButtons):
(WebCore::RenderScrollbarTheme::hasThumb):
(WebCore::RenderScrollbarTheme::minimumThumbLength):
(WebCore::RenderScrollbarTheme::backButtonRect):
(WebCore::RenderScrollbarTheme::forwardButtonRect):
(WebCore::RenderScrollbarTheme::trackRect):
(WebCore::RenderScrollbarTheme::constrainTrackRectToTrackPieces):
(WebCore::RenderScrollbarTheme::willPaintScrollbar):
(WebCore::RenderScrollbarTheme::didPaintScrollbar):
(WebCore::RenderScrollbarTheme::paintScrollbarBackground):
(WebCore::RenderScrollbarTheme::paintTrackBackground):
(WebCore::RenderScrollbarTheme::paintTrackPiece):
(WebCore::RenderScrollbarTheme::paintButton):
(WebCore::RenderScrollbarTheme::paintThumb):
(WebCore::RenderScrollbarTheme::paintTickmarks):

  • rendering/RenderScrollbarTheme.h:
  • Property svn:eol-style set to native
File size: 19.1 KB
Line 
1/*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ScrollbarThemeGtk.h"
28
29#include "PlatformContextCairo.h"
30#include "PlatformMouseEvent.h"
31#include "ScrollView.h"
32#include "Scrollbar.h"
33#include <gtk/gtk.h>
34#include <wtf/NeverDestroyed.h>
35#include <wtf/glib/GRefPtr.h>
36
37namespace WebCore {
38
39ScrollbarTheme* ScrollbarTheme::nativeTheme()
40{
41    static ScrollbarThemeGtk theme;
42    return &theme;
43}
44
45ScrollbarThemeGtk::~ScrollbarThemeGtk()
46{
47}
48
49bool ScrollbarThemeGtk::hasThumb(Scrollbar& scrollbar)
50{
51#ifndef GTK_API_VERSION_2
52    // This method is just called as a paint-time optimization to see if
53    // painting the thumb can be skipped.  We don't have to be exact here.
54    return thumbLength(scrollbar) > 0;
55#else
56    UNUSED_PARAM(scrollbar);
57    return false;
58#endif
59}
60
61IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool)
62{
63#ifndef GTK_API_VERSION_2
64    if (part == BackButtonEndPart && !m_hasBackButtonEndPart)
65        return IntRect();
66    if (part == BackButtonStartPart && !m_hasBackButtonStartPart)
67        return IntRect();
68
69    int x = scrollbar.x() + m_troughBorderWidth;
70    int y = scrollbar.y() + m_troughBorderWidth;
71    IntSize size = buttonSize(scrollbar);
72    if (part == BackButtonStartPart)
73        return IntRect(x, y, size.width(), size.height());
74
75    // BackButtonEndPart (alternate button)
76    if (scrollbar.orientation() == HorizontalScrollbar)
77        return IntRect(scrollbar.x() + scrollbar.width() - m_troughBorderWidth - (2 * size.width()), y, size.width(), size.height());
78
79    // VerticalScrollbar alternate button
80    return IntRect(x, scrollbar.y() + scrollbar.height() - m_troughBorderWidth - (2 * size.height()), size.width(), size.height());
81#else
82    UNUSED_PARAM(scrollbar);
83    UNUSED_PARAM(part);
84    return IntRect();
85#endif
86}
87
88IntRect ScrollbarThemeGtk::forwardButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool)
89{
90#ifndef GTK_API_VERSION_2
91    if (part == ForwardButtonStartPart && !m_hasForwardButtonStartPart)
92        return IntRect();
93    if (part == ForwardButtonEndPart && !m_hasForwardButtonEndPart)
94        return IntRect();
95
96    IntSize size = buttonSize(scrollbar);
97    if (scrollbar.orientation() == HorizontalScrollbar) {
98        int y = scrollbar.y() + m_troughBorderWidth;
99        if (part == ForwardButtonEndPart)
100            return IntRect(scrollbar.x() + scrollbar.width() - size.width() - m_troughBorderWidth, y, size.width(), size.height());
101
102        // ForwardButtonStartPart (alternate button)
103        return IntRect(scrollbar.x() + m_troughBorderWidth + size.width(), y, size.width(), size.height());
104    }
105
106    // VerticalScrollbar
107    int x = scrollbar.x() + m_troughBorderWidth;
108    if (part == ForwardButtonEndPart)
109        return IntRect(x, scrollbar.y() + scrollbar.height() - size.height() - m_troughBorderWidth, size.width(), size.height());
110
111    // ForwardButtonStartPart (alternate button)
112    return IntRect(x, scrollbar.y() + m_troughBorderWidth + size.height(), size.width(), size.height());
113#else
114    UNUSED_PARAM(scrollbar);
115    UNUSED_PARAM(part);
116    return IntRect();
117#endif
118}
119
120IntRect ScrollbarThemeGtk::trackRect(Scrollbar& scrollbar, bool)
121{
122#ifndef GTK_API_VERSION_2
123    // The padding along the thumb movement axis includes the trough border
124    // plus the size of stepper spacing (the space between the stepper and
125    // the place where the thumb stops). There is often no stepper spacing.
126    int movementAxisPadding = m_troughBorderWidth + m_stepperSpacing;
127
128    // The fatness of the scrollbar on the non-movement axis.
129    int thickness = scrollbarThickness(scrollbar.controlSize());
130
131    int startButtonsOffset = 0;
132    int buttonsWidth = 0;
133    if (m_hasForwardButtonStartPart) {
134        startButtonsOffset += m_stepperSize;
135        buttonsWidth += m_stepperSize;
136    }
137    if (m_hasBackButtonStartPart) {
138        startButtonsOffset += m_stepperSize;
139        buttonsWidth += m_stepperSize;
140    }
141    if (m_hasBackButtonEndPart)
142        buttonsWidth += m_stepperSize;
143    if (m_hasForwardButtonEndPart)
144        buttonsWidth += m_stepperSize;
145
146    if (scrollbar.orientation() == HorizontalScrollbar) {
147        // Once the scrollbar becomes smaller than the natural size of the
148        // two buttons, the track disappears.
149        if (scrollbar.width() < 2 * thickness)
150            return IntRect();
151        return IntRect(scrollbar.x() + movementAxisPadding + startButtonsOffset, scrollbar.y(),
152                       scrollbar.width() - (2 * movementAxisPadding) - buttonsWidth, thickness);
153    }
154
155    if (scrollbar.height() < 2 * thickness)
156        return IntRect();
157    return IntRect(scrollbar.x(), scrollbar.y() + movementAxisPadding + startButtonsOffset,
158                   thickness, scrollbar.height() - (2 * movementAxisPadding) - buttonsWidth);
159#else
160    UNUSED_PARAM(scrollbar);
161    return IntRect();
162#endif
163}
164
165#ifndef GTK_API_VERSION_2
166class ScrollbarStyleContext {
167    WTF_MAKE_NONCOPYABLE(ScrollbarStyleContext); WTF_MAKE_FAST_ALLOCATED;
168public:
169    ScrollbarStyleContext()
170        : m_context(adoptGRef(gtk_style_context_new()))
171    {
172        GtkWidgetPath* path = gtk_widget_path_new();
173        gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
174        gtk_widget_path_iter_add_class(path, 0, GTK_STYLE_CLASS_SCROLLBAR);
175        gtk_style_context_set_path(m_context.get(), path);
176        gtk_widget_path_free(path);
177    }
178
179    ~ScrollbarStyleContext()
180    {
181    }
182
183    GtkStyleContext* context() const { return m_context.get(); }
184
185private:
186    GRefPtr<GtkStyleContext> m_context;
187};
188
189static GtkStyleContext* gtkScrollbarStyleContext()
190{
191    static NeverDestroyed<ScrollbarStyleContext> styleContext;
192    return styleContext.get().context();
193}
194
195ScrollbarThemeGtk::ScrollbarThemeGtk()
196{
197    updateThemeProperties();
198}
199
200void ScrollbarThemeGtk::themeChanged()
201{
202    gtk_style_context_invalidate(gtkScrollbarStyleContext());
203    updateThemeProperties();
204}
205
206void ScrollbarThemeGtk::updateThemeProperties()
207{
208    gtk_style_context_get_style(
209        gtkScrollbarStyleContext(),
210        "min-slider-length", &m_minThumbLength,
211        "slider-width", &m_thumbFatness,
212        "trough-border", &m_troughBorderWidth,
213        "stepper-size", &m_stepperSize,
214        "stepper-spacing", &m_stepperSpacing,
215        "trough-under-steppers", &m_troughUnderSteppers,
216        "has-backward-stepper", &m_hasBackButtonStartPart,
217        "has-forward-stepper", &m_hasForwardButtonEndPart,
218        "has-secondary-backward-stepper", &m_hasBackButtonEndPart,
219        "has-secondary-forward-stepper", &m_hasForwardButtonStartPart,
220        nullptr);
221    updateScrollbarsFrameThickness();
222}
223
224typedef HashSet<Scrollbar*> ScrollbarMap;
225
226static ScrollbarMap& scrollbarMap()
227{
228    static NeverDestroyed<ScrollbarMap> map;
229    return map;
230}
231
232void ScrollbarThemeGtk::registerScrollbar(Scrollbar& scrollbar)
233{
234    scrollbarMap().add(&scrollbar);
235}
236
237void ScrollbarThemeGtk::unregisterScrollbar(Scrollbar& scrollbar)
238{
239    scrollbarMap().remove(&scrollbar);
240}
241
242void ScrollbarThemeGtk::updateScrollbarsFrameThickness()
243{
244    if (scrollbarMap().isEmpty())
245        return;
246
247    // Update the thickness of every interior frame scrollbar widget. The
248    // platform-independent scrollbar them code isn't yet smart enough to get
249    // this information when it paints.
250    for (const auto& scrollbar : scrollbarMap()) {
251        // Top-level scrollbar i.e. scrollbars who have a parent ScrollView
252        // with no parent are native, and thus do not need to be resized.
253        if (!scrollbar->parent() || !scrollbar->parent()->parent())
254            return;
255
256        int thickness = scrollbarThickness(scrollbar->controlSize());
257        if (scrollbar->orientation() == HorizontalScrollbar)
258            scrollbar->setFrameRect(IntRect(0, scrollbar->parent()->height() - thickness, scrollbar->width(), thickness));
259        else
260            scrollbar->setFrameRect(IntRect(scrollbar->parent()->width() - thickness, 0, thickness, scrollbar->height()));
261    }
262}
263
264IntRect ScrollbarThemeGtk::thumbRect(Scrollbar& scrollbar, const IntRect& unconstrainedTrackRect)
265{
266    IntRect trackRect = constrainTrackRectToTrackPieces(scrollbar, unconstrainedTrackRect);
267    int thumbPos = thumbPosition(scrollbar);
268    if (scrollbar.orientation() == HorizontalScrollbar)
269        return IntRect(trackRect.x() + thumbPos, trackRect.y() + (trackRect.height() - m_thumbFatness) / 2, thumbLength(scrollbar), m_thumbFatness); 
270
271    // VerticalScrollbar
272    return IntRect(trackRect.x() + (trackRect.width() - m_thumbFatness) / 2, trackRect.y() + thumbPos, m_thumbFatness, thumbLength(scrollbar));
273}
274
275static void applyScrollbarStyleContextClasses(GtkStyleContext* context, ScrollbarOrientation orientation)
276{
277    gtk_style_context_add_class(context, GTK_STYLE_CLASS_SCROLLBAR);
278    gtk_style_context_add_class(context, orientation == VerticalScrollbar ?  GTK_STYLE_CLASS_VERTICAL : GTK_STYLE_CLASS_HORIZONTAL);
279}
280
281static void adjustRectAccordingToMargin(GtkStyleContext* context, GtkStateFlags state, IntRect& rect)
282{
283    GtkBorder margin;
284    gtk_style_context_get_margin(context, state, &margin);
285    rect.move(margin.left, margin.right);
286    rect.contract(margin.left + margin.right, margin.top + margin.bottom);
287}
288
289void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect)
290{
291    // Paint the track background. If the trough-under-steppers property is true, this
292    // should be the full size of the scrollbar, but if is false, it should only be the
293    // track rect.
294    IntRect fullScrollbarRect(rect);
295    if (m_troughUnderSteppers)
296        fullScrollbarRect = IntRect(scrollbar.x(), scrollbar.y(), scrollbar.width(), scrollbar.height());
297
298    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
299    gtk_style_context_save(styleContext);
300
301    applyScrollbarStyleContextClasses(styleContext, scrollbar.orientation());
302    gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_TROUGH);
303
304    adjustRectAccordingToMargin(styleContext, static_cast<GtkStateFlags>(0), fullScrollbarRect);
305    gtk_render_background(styleContext, context.platformContext()->cr(), fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
306    gtk_render_frame(styleContext, context.platformContext()->cr(), fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
307
308    gtk_style_context_restore(styleContext);
309}
310
311void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext& context, Scrollbar& scrollbar)
312{
313    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
314    gtk_style_context_save(styleContext);
315
316    applyScrollbarStyleContextClasses(styleContext, scrollbar.orientation());
317    gtk_style_context_add_class(styleContext, "scrolled-window");
318    gtk_render_frame(styleContext, context.platformContext()->cr(), scrollbar.x(), scrollbar.y(), scrollbar.width(), scrollbar.height());
319
320    gtk_style_context_restore(styleContext);
321}
322
323void ScrollbarThemeGtk::paintThumb(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect)
324{
325    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
326    gtk_style_context_save(styleContext);
327
328    ScrollbarOrientation orientation = scrollbar.orientation();
329    applyScrollbarStyleContextClasses(styleContext, orientation);
330    gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_SLIDER);
331
332    guint flags = 0;
333    if (scrollbar.pressedPart() == ThumbPart)
334        flags |= GTK_STATE_FLAG_ACTIVE;
335    if (scrollbar.hoveredPart() == ThumbPart)
336        flags |= GTK_STATE_FLAG_PRELIGHT;
337    gtk_style_context_set_state(styleContext, static_cast<GtkStateFlags>(flags));
338
339    IntRect thumbRect(rect);
340    adjustRectAccordingToMargin(styleContext, static_cast<GtkStateFlags>(flags), thumbRect);
341    gtk_render_slider(styleContext, context.platformContext()->cr(), thumbRect.x(), thumbRect.y(), thumbRect.width(), thumbRect.height(),
342        orientation == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL);
343
344    gtk_style_context_restore(styleContext);
345}
346
347void ScrollbarThemeGtk::paintButton(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart part)
348{
349    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
350    gtk_style_context_save(styleContext);
351
352    ScrollbarOrientation orientation = scrollbar.orientation();
353    applyScrollbarStyleContextClasses(styleContext, orientation);
354
355    guint flags = 0;
356    if ((BackButtonStartPart == part && scrollbar.currentPos())
357        || (BackButtonEndPart == part && scrollbar.currentPos())
358        || (ForwardButtonEndPart == part && scrollbar.currentPos() != scrollbar.maximum())
359        || (ForwardButtonStartPart == part && scrollbar.currentPos() != scrollbar.maximum())) {
360        if (part == scrollbar.pressedPart())
361            flags |= GTK_STATE_FLAG_ACTIVE;
362        if (part == scrollbar.hoveredPart())
363            flags |= GTK_STATE_FLAG_PRELIGHT;
364    } else
365        flags |= GTK_STATE_FLAG_INSENSITIVE;
366    gtk_style_context_set_state(styleContext, static_cast<GtkStateFlags>(flags));
367
368    gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_BUTTON);
369    gtk_render_background(styleContext, context.platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
370    gtk_render_frame(styleContext, context.platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
371
372    gfloat arrowScaling;
373    gtk_style_context_get_style(styleContext, "arrow-scaling", &arrowScaling, nullptr);
374
375    double arrowSize = std::min(rect.width(), rect.height()) * arrowScaling;
376    FloatPoint arrowPoint(
377        rect.x() + (rect.width() - arrowSize) / 2,
378        rect.y() + (rect.height() - arrowSize) / 2);
379
380    if (flags & GTK_STATE_FLAG_ACTIVE) {
381        gint arrowDisplacementX, arrowDisplacementY;
382        gtk_style_context_get_style(styleContext, "arrow-displacement-x", &arrowDisplacementX, "arrow-displacement-y", &arrowDisplacementY, nullptr);
383        arrowPoint.move(arrowDisplacementX, arrowDisplacementY);
384    }
385
386    gdouble angle;
387    if (orientation == VerticalScrollbar)
388        angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI : 0;
389    else
390        angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI / 2 : 3 * (G_PI / 2);
391
392    gtk_render_arrow(styleContext, context.platformContext()->cr(), angle, arrowPoint.x(), arrowPoint.y(), arrowSize);
393
394    gtk_style_context_restore(styleContext);
395}
396
397bool ScrollbarThemeGtk::paint(Scrollbar& scrollbar, GraphicsContext& graphicsContext, const IntRect& damageRect)
398{
399    if (graphicsContext.paintingDisabled())
400        return false;
401
402    // Create the ScrollbarControlPartMask based on the damageRect
403    ScrollbarControlPartMask scrollMask = NoPart;
404
405    IntRect backButtonStartPaintRect;
406    IntRect backButtonEndPaintRect;
407    IntRect forwardButtonStartPaintRect;
408    IntRect forwardButtonEndPaintRect;
409    if (hasButtons(scrollbar)) {
410        backButtonStartPaintRect = backButtonRect(scrollbar, BackButtonStartPart, true);
411        if (damageRect.intersects(backButtonStartPaintRect))
412            scrollMask |= BackButtonStartPart;
413        backButtonEndPaintRect = backButtonRect(scrollbar, BackButtonEndPart, true);
414        if (damageRect.intersects(backButtonEndPaintRect))
415            scrollMask |= BackButtonEndPart;
416        forwardButtonStartPaintRect = forwardButtonRect(scrollbar, ForwardButtonStartPart, true);
417        if (damageRect.intersects(forwardButtonStartPaintRect))
418            scrollMask |= ForwardButtonStartPart;
419        forwardButtonEndPaintRect = forwardButtonRect(scrollbar, ForwardButtonEndPart, true);
420        if (damageRect.intersects(forwardButtonEndPaintRect))
421            scrollMask |= ForwardButtonEndPart;
422    }
423
424    IntRect trackPaintRect = trackRect(scrollbar, true);
425    if (damageRect.intersects(trackPaintRect))
426        scrollMask |= TrackBGPart;
427
428    if (m_troughUnderSteppers && (scrollMask & BackButtonStartPart
429            || scrollMask & BackButtonEndPart
430            || scrollMask & ForwardButtonStartPart
431            || scrollMask & ForwardButtonEndPart))
432        scrollMask |= TrackBGPart;
433
434    bool thumbPresent = hasThumb(scrollbar);
435    IntRect currentThumbRect;
436    if (thumbPresent) {
437        IntRect track = trackRect(scrollbar, false);
438        currentThumbRect = thumbRect(scrollbar, track);
439        if (damageRect.intersects(currentThumbRect))
440            scrollMask |= ThumbPart;
441    }
442
443    ScrollbarControlPartMask allButtons = BackButtonStartPart | BackButtonEndPart | ForwardButtonStartPart | ForwardButtonEndPart;
444    if (scrollMask & TrackBGPart || scrollMask & ThumbPart || scrollMask & allButtons)
445        paintScrollbarBackground(graphicsContext, scrollbar);
446        paintTrackBackground(graphicsContext, scrollbar, trackPaintRect);
447
448    // Paint the back and forward buttons.
449    if (scrollMask & BackButtonStartPart)
450        paintButton(graphicsContext, scrollbar, backButtonStartPaintRect, BackButtonStartPart);
451    if (scrollMask & BackButtonEndPart)
452        paintButton(graphicsContext, scrollbar, backButtonEndPaintRect, BackButtonEndPart);
453    if (scrollMask & ForwardButtonStartPart)
454        paintButton(graphicsContext, scrollbar, forwardButtonStartPaintRect, ForwardButtonStartPart);
455    if (scrollMask & ForwardButtonEndPart)
456        paintButton(graphicsContext, scrollbar, forwardButtonEndPaintRect, ForwardButtonEndPart);
457
458    // Paint the thumb.
459    if (scrollMask & ThumbPart)
460        paintThumb(graphicsContext, scrollbar, currentThumbRect);
461
462    return true;
463}
464
465bool ScrollbarThemeGtk::shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent& event)
466{
467    return (event.shiftKey() && event.button() == LeftButton) || (event.button() == MiddleButton);
468}
469
470int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize)
471{
472    return m_thumbFatness + (m_troughBorderWidth * 2);
473}
474
475IntSize ScrollbarThemeGtk::buttonSize(Scrollbar& scrollbar)
476{
477    if (scrollbar.orientation() == VerticalScrollbar)
478        return IntSize(m_thumbFatness, m_stepperSize);
479
480    // HorizontalScrollbar
481    return IntSize(m_stepperSize, m_thumbFatness);
482}
483
484int ScrollbarThemeGtk::minimumThumbLength(Scrollbar&)
485{
486    return m_minThumbLength;
487}
488#endif // GTK_API_VERSION_2
489
490}
Note: See TracBrowser for help on using the repository browser.