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 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_H_
27 #define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_H_
28 
29 #include "third_party/blink/renderer/core/core_export.h"
30 #include "third_party/blink/renderer/core/scroll/scroll_types.h"
31 #include "third_party/blink/renderer/core/scroll/scrollbar.h"
32 #include "third_party/blink/renderer/platform/geometry/int_rect.h"
33 #include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
34 #include "third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h"
35 
36 namespace blink {
37 
38 class GraphicsContext;
39 class WebMouseEvent;
40 
41 class CORE_EXPORT ScrollbarTheme {
42   DISALLOW_COPY_AND_ASSIGN(ScrollbarTheme);
43   USING_FAST_MALLOC(ScrollbarTheme);
44 
45  public:
46   ScrollbarTheme() = default;
47   virtual ~ScrollbarTheme() = default;
48 
49   // If true, then scrollbars with this theme will be painted every time
50   // Scrollbar::SetNeedsPaintInvalidation is called. If false, then only parts
51   // which are explicitly invalidated will be repainted.
ShouldRepaintAllPartsOnInvalidation()52   virtual bool ShouldRepaintAllPartsOnInvalidation() const { return true; }
53 
UpdateEnabledState(const Scrollbar &)54   virtual void UpdateEnabledState(const Scrollbar&) {}
55 
56   // |context|'s current space is the space of the scrollbar's FrameRect().
57   void Paint(const Scrollbar&,
58              GraphicsContext& context,
59              const IntPoint& paint_offset);
60 
61   ScrollbarPart HitTestRootFramePosition(const Scrollbar&, const IntPoint&);
62 
63   // This returns a fixed value regardless of device-scale-factor.
64   // This returns thickness when scrollbar is painted.  i.e. It's not 0 even in
65   // overlay scrollbar mode.
66   // See also Scrollbar::scrollbarThickness().
67   virtual int ScrollbarThickness(ScrollbarControlSize = kRegularScrollbar) {
68     return 0;
69   }
ScrollbarMargin()70   virtual int ScrollbarMargin() const { return 0; }
71 
IsSolidColor()72   virtual bool IsSolidColor() const { return false; }
UsesOverlayScrollbars()73   virtual bool UsesOverlayScrollbars() const { return false; }
UpdateScrollbarOverlayColorTheme(const Scrollbar &)74   virtual void UpdateScrollbarOverlayColorTheme(const Scrollbar&) {}
75 
76   // If true, scrollbars that become invisible (i.e. overlay scrollbars that
77   // fade out) should be marked as disabled. This option exists since Mac and
78   // Aura overlays implement the fade out differently, with Mac painting code
79   // fading out the scrollbars. Aura scrollbars require disabling the scrollbar
80   // to prevent painting it.
ShouldDisableInvisibleScrollbars()81   virtual bool ShouldDisableInvisibleScrollbars() const { return true; }
82 
83   // If true, Blink is in charge of hiding/showing of overlay scrollbars.  As
84   // above, this option exists because on Mac the visibility is controlled by
85   // Mac painting code which Blink doesn't have an input into. In order to
86   // prevent the two from getting out of sync we disable setting the Blink-side
87   // parameter on Mac.
BlinkControlsOverlayVisibility()88   virtual bool BlinkControlsOverlayVisibility() const { return true; }
89 
InvalidateOnMouseEnterExit()90   virtual bool InvalidateOnMouseEnterExit() { return false; }
91 
92   // Returns parts of the scrollbar which must be repainted following a change
93   // in the thumb position, given scroll positions before and after.
PartsToInvalidateOnThumbPositionChange(const Scrollbar &,float old_position,float new_position)94   virtual ScrollbarPart PartsToInvalidateOnThumbPositionChange(
95       const Scrollbar&,
96       float old_position,
97       float new_position) const {
98     return kAllParts;
99   }
100 
101   virtual void PaintScrollCorner(GraphicsContext&,
102                                  const Scrollbar* vertical_scrollbar,
103                                  const DisplayItemClient&,
104                                  const IntRect& corner_rect,
105                                  WebColorScheme color_scheme);
106   virtual void PaintTickmarks(GraphicsContext&,
107                               const Scrollbar&,
108                               const IntRect&);
109 
ShouldCenterOnThumb(const Scrollbar &,const WebMouseEvent &)110   virtual bool ShouldCenterOnThumb(const Scrollbar&, const WebMouseEvent&) {
111     return false;
112   }
ShouldSnapBackToDragOrigin(const Scrollbar &,const WebMouseEvent &)113   virtual bool ShouldSnapBackToDragOrigin(const Scrollbar&,
114                                           const WebMouseEvent&) {
115     return false;
116   }
ShouldDragDocumentInsteadOfThumb(const Scrollbar &,const WebMouseEvent &)117   virtual bool ShouldDragDocumentInsteadOfThumb(const Scrollbar&,
118                                                 const WebMouseEvent&) {
119     return false;
120   }
121 
SupportsDragSnapBack()122   virtual bool SupportsDragSnapBack() const { return false; }
123 
124   // The position of the thumb relative to the track.
ThumbPosition(const Scrollbar & scrollbar)125   int ThumbPosition(const Scrollbar& scrollbar) {
126     return ThumbPosition(scrollbar, scrollbar.CurrentPos());
127   }
128   virtual base::TimeDelta OverlayScrollbarFadeOutDelay() const;
129   virtual base::TimeDelta OverlayScrollbarFadeOutDuration() const;
130   // The position the thumb would have, relative to the track, at the specified
131   // scroll position.
132   virtual int ThumbPosition(const Scrollbar&, float scroll_position);
133   // The length of the thumb along the axis of the scrollbar.
134   virtual int ThumbLength(const Scrollbar&);
135   // The position of the track relative to the scrollbar.
136   virtual int TrackPosition(const Scrollbar&);
137   // The length of the track along the axis of the scrollbar.
138   virtual int TrackLength(const Scrollbar&);
139   // The opacity to be applied to the scrollbar. A theme overriding Opacity()
140   // should also override PaintThumbWithOpacity().
Opacity(const Scrollbar &)141   virtual float Opacity(const Scrollbar&) const { return 1.0f; }
142 
143   // Whether the native theme of the OS has scrollbar buttons.
144   virtual bool NativeThemeHasButtons() = 0;
145   // Whether the scrollbar has buttons. It's the same as NativeThemeHasButtons()
146   // except for custom scrollbars which can override the OS settings.
HasButtons(const Scrollbar &)147   virtual bool HasButtons(const Scrollbar&) { return NativeThemeHasButtons(); }
148 
149   virtual bool HasThumb(const Scrollbar&) = 0;
150 
151   // All these rects are in the same coordinate space as the scrollbar's
152   // FrameRect.
153   virtual IntRect BackButtonRect(const Scrollbar&) = 0;
154   virtual IntRect ForwardButtonRect(const Scrollbar&) = 0;
155   virtual IntRect TrackRect(const Scrollbar&) = 0;
156   virtual IntRect ThumbRect(const Scrollbar&);
157   virtual int ThumbThickness(const Scrollbar&);
158 
159   virtual int MinimumThumbLength(const Scrollbar&) = 0;
160 
161   virtual void SplitTrack(const Scrollbar&,
162                           const IntRect& track,
163                           IntRect& start_track,
164                           IntRect& thumb,
165                           IntRect& end_track);
166 
PaintThumb(GraphicsContext &,const Scrollbar &,const IntRect &)167   virtual void PaintThumb(GraphicsContext&, const Scrollbar&, const IntRect&) {}
168 
169   // |offset| is from the space of the scrollbar's FrameRect() to |context|'s
170   // current space.
171   void PaintTrackButtonsTickmarks(GraphicsContext& context,
172                                   const Scrollbar&,
173                                   const IntPoint& offset);
174 
MaxOverlapBetweenPages()175   virtual int MaxOverlapBetweenPages() {
176     return std::numeric_limits<int>::max();
177   }
178 
179   virtual base::TimeDelta InitialAutoscrollTimerDelay();
180   virtual base::TimeDelta AutoscrollTimerDelay();
181 
ConstrainTrackRectToTrackPieces(const Scrollbar &,const IntRect & rect)182   virtual IntRect ConstrainTrackRectToTrackPieces(const Scrollbar&,
183                                                   const IntRect& rect) {
184     return rect;
185   }
186 
RegisterScrollbar(Scrollbar &)187   virtual void RegisterScrollbar(Scrollbar&) {}
188 
IsMockTheme()189   virtual bool IsMockTheme() const { return false; }
190 
UsesNinePatchThumbResource()191   virtual bool UsesNinePatchThumbResource() const { return false; }
192 
193   // For a nine-patch scrollbar, this defines the painting canvas size which the
194   // painting code will use to paint the scrollbar into. The actual scrollbar
195   // dimensions will be ignored for purposes of painting since the resource can
196   // be then resized without a repaint.
NinePatchThumbCanvasSize(const Scrollbar &)197   virtual IntSize NinePatchThumbCanvasSize(const Scrollbar&) const {
198     NOTREACHED();
199     return IntSize();
200   }
201 
202   // For a nine-patch resource, the aperture defines the center patch that will
203   // be stretched out.
NinePatchThumbAperture(const Scrollbar &)204   virtual IntRect NinePatchThumbAperture(const Scrollbar&) const {
205     NOTREACHED();
206     return IntRect();
207   }
208 
AllowsHitTest()209   virtual bool AllowsHitTest() const { return true; }
210 
211  protected:
212   // The point is in the same coordinate space as the scrollbar's FrameRect.
213   virtual ScrollbarPart HitTest(const Scrollbar&, const IntPoint&);
214 
TickmarkBorderWidth()215   virtual int TickmarkBorderWidth() { return 0; }
PaintTrack(GraphicsContext &,const Scrollbar &,const IntRect &)216   virtual void PaintTrack(GraphicsContext&, const Scrollbar&, const IntRect&) {}
PaintButton(GraphicsContext &,const Scrollbar &,const IntRect &,ScrollbarPart)217   virtual void PaintButton(GraphicsContext&,
218                            const Scrollbar&,
219                            const IntRect&,
220                            ScrollbarPart) {}
221 
222   // |offset| is the offset of the |context|'s current space to the space of
223   // scrollbar's FrameRect().
224   virtual void PaintTrackAndButtons(GraphicsContext& context,
225                                     const Scrollbar&,
226                                     const IntPoint& offset);
227 
228   // Paint the thumb with Opacity() applied.
PaintThumbWithOpacity(GraphicsContext & context,const Scrollbar & scrollbar,const IntRect & rect)229   virtual void PaintThumbWithOpacity(GraphicsContext& context,
230                                      const Scrollbar& scrollbar,
231                                      const IntRect& rect) {
232     // By default this method just calls PaintThumb(). A theme with custom
233     // Opacity() should override this method to apply the opacity.
234     DCHECK_EQ(1.0f, Opacity(scrollbar));
235     PaintThumb(context, scrollbar, rect);
236   }
237 
238  protected:
239   // For GetTheme().
240   friend class MockScrollableArea;
241   friend class MockScrollableAreaForAnimatorTest;
242   friend class Page;
243 
244   // Get the theme based on global scrollbar settings. We should always use
245   // Page::GetScrollbarTheme() to get scrollbar theme because we support
246   // different native scrollbar theme base on page settings.
247   // See http://crrev.com/c/646727.
248   static ScrollbarTheme& GetTheme();
249 
OverlayScrollbarsEnabled()250   static bool OverlayScrollbarsEnabled() {
251     return ScrollbarThemeSettings::OverlayScrollbarsEnabled();
252   }
MockScrollbarsEnabled()253   static bool MockScrollbarsEnabled() {
254     return ScrollbarThemeSettings::MockScrollbarsEnabled();
255   }
256 
257  private:
258   // Must be implemented to return the correct theme subclass.
259   static ScrollbarTheme& NativeTheme();
260 };
261 
262 }  // namespace blink
263 #endif
264