1 /* 2 * Copyright (C) 2004, 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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_H_ 27 #define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_H_ 28 29 #include "third_party/blink/public/platform/web_color_scheme.h" 30 #include "third_party/blink/renderer/core/core_export.h" 31 #include "third_party/blink/renderer/core/scroll/scroll_types.h" 32 #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" 33 #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" 34 #include "third_party/blink/renderer/platform/heap/handle.h" 35 #include "third_party/blink/renderer/platform/timer.h" 36 #include "third_party/blink/renderer/platform/wtf/math_extras.h" 37 38 namespace blink { 39 40 class Element; 41 class GraphicsContext; 42 class IntRect; 43 class ChromeClient; 44 class ScrollableArea; 45 class ScrollbarTheme; 46 class WebGestureEvent; 47 class WebMouseEvent; 48 49 class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>, 50 public DisplayItemClient { 51 public: 52 // Theme object ownership remains with the caller and it must outlive the 53 // scrollbar. CreateForTesting(ScrollableArea * scrollable_area,ScrollbarOrientation orientation,ScrollbarControlSize size,ScrollbarTheme * theme)54 static Scrollbar* CreateForTesting(ScrollableArea* scrollable_area, 55 ScrollbarOrientation orientation, 56 ScrollbarControlSize size, 57 ScrollbarTheme* theme) { 58 return MakeGarbageCollected<Scrollbar>(scrollable_area, orientation, size, 59 nullptr, nullptr, theme); 60 } 61 62 Scrollbar(ScrollableArea*, 63 ScrollbarOrientation, 64 ScrollbarControlSize, 65 Element* style_source, 66 ChromeClient* = nullptr, 67 ScrollbarTheme* = nullptr); 68 ~Scrollbar() override; 69 X()70 int X() const { return frame_rect_.X(); } Y()71 int Y() const { return frame_rect_.Y(); } Width()72 int Width() const { return frame_rect_.Width(); } Height()73 int Height() const { return frame_rect_.Height(); } Size()74 IntSize Size() const { return frame_rect_.Size(); } Location()75 IntPoint Location() const { return frame_rect_.Location(); } 76 77 void SetFrameRect(const IntRect&); FrameRect()78 const IntRect& FrameRect() const { return frame_rect_; } 79 80 ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const; 81 bool HasTickmarks() const; 82 Vector<IntRect> GetTickmarks() const; 83 bool IsScrollableAreaActive() const; 84 85 IntPoint ConvertFromRootFrame(const IntPoint&) const; 86 IsCustomScrollbar()87 virtual bool IsCustomScrollbar() const { return false; } Orientation()88 ScrollbarOrientation Orientation() const { return orientation_; } 89 bool IsLeftSideVerticalScrollbar() const; 90 Value()91 int Value() const { return static_cast<int>(lroundf(current_pos_)); } CurrentPos()92 float CurrentPos() const { return current_pos_; } VisibleSize()93 int VisibleSize() const { return visible_size_; } TotalSize()94 int TotalSize() const { return total_size_; } 95 int Maximum() const; GetControlSize()96 ScrollbarControlSize GetControlSize() const { return control_size_; } 97 PressedPart()98 ScrollbarPart PressedPart() const { return pressed_part_; } HoveredPart()99 ScrollbarPart HoveredPart() const { return hovered_part_; } 100 StyleChanged()101 virtual void StyleChanged() {} 102 void SetScrollbarsHiddenFromExternalAnimator(bool); Enabled()103 bool Enabled() const { return enabled_; } 104 virtual void SetEnabled(bool); 105 106 // This returns device-scale-factor-aware pixel value. 107 // e.g. 15 in dsf=1.0, 30 in dsf=2.0. 108 // This returns 0 for overlay scrollbars. 109 // See also ScrolbarTheme::scrollbatThickness(). 110 int ScrollbarThickness() const; 111 112 // Called by the ScrollableArea when the scroll offset changes. 113 // Will trigger paint invalidation if required. 114 void OffsetDidChange(mojom::blink::ScrollType scroll_type); 115 116 virtual void DisconnectFromScrollableArea(); GetScrollableArea()117 ScrollableArea* GetScrollableArea() const { return scrollable_area_; } 118 PressedPos()119 int PressedPos() const { return pressed_pos_; } 120 121 virtual void SetHoveredPart(ScrollbarPart); 122 virtual void SetPressedPart(ScrollbarPart, WebInputEvent::Type); 123 124 void SetProportion(int visible_size, int total_size); SetPressedPos(int p)125 void SetPressedPos(int p) { pressed_pos_ = p; } 126 127 void Paint(GraphicsContext&, const IntPoint& paint_offset) const; 128 129 virtual bool IsSolidColor() const; 130 virtual bool IsOverlayScrollbar() const; 131 bool ShouldParticipateInHitTesting(); 132 133 bool IsWindowActive() const; 134 135 // Return if the gesture event was handled. |shouldUpdateCapture| 136 // will be set to true if the handler should update the capture 137 // state for this scrollbar. 138 bool GestureEvent(const WebGestureEvent&, bool* should_update_capture); 139 140 // These methods are used for platform scrollbars to give :hover feedback. 141 // They will not get called when the mouse went down in a scrollbar, since it 142 // is assumed the scrollbar will start 143 // grabbing all events in that case anyway. 144 void MouseMoved(const WebMouseEvent&); 145 void MouseEntered(); 146 void MouseExited(); 147 148 // Used by some platform scrollbars to know when they've been released from 149 // capture. 150 void MouseUp(const WebMouseEvent&); 151 void MouseDown(const WebMouseEvent&); 152 GetTheme()153 ScrollbarTheme& GetTheme() const { return theme_; } 154 155 IntRect ConvertToContainingEmbeddedContentView(const IntRect&) const; 156 IntPoint ConvertFromContainingEmbeddedContentView(const IntPoint&) const; 157 158 void MoveThumb(int pos, bool dragging_document = false); 159 ElasticOverscroll()160 float ElasticOverscroll() const { return elastic_overscroll_; } SetElasticOverscroll(float elastic_overscroll)161 void SetElasticOverscroll(float elastic_overscroll) { 162 elastic_overscroll_ = elastic_overscroll; 163 } 164 165 // Use SetNeedsPaintInvalidation to cause the scrollbar (or parts thereof) 166 // to repaint. Here "track" includes track, buttons and tickmarks, i.e. all 167 // things except the thumb. TrackNeedsRepaint()168 bool TrackNeedsRepaint() const { return track_needs_repaint_; } ClearTrackNeedsRepaint()169 void ClearTrackNeedsRepaint() { track_needs_repaint_ = false; } ThumbNeedsRepaint()170 bool ThumbNeedsRepaint() const { return thumb_needs_repaint_; } ClearThumbNeedsRepaint()171 void ClearThumbNeedsRepaint() { thumb_needs_repaint_ = false; } 172 173 // DisplayItemClient methods. DebugName()174 String DebugName() const final { 175 return orientation_ == kHorizontalScrollbar ? "HorizontalScrollbar" 176 : "VerticalScrollbar"; 177 } VisualRect()178 IntRect VisualRect() const final { return visual_rect_; } 179 SetVisualRect(const IntRect & r)180 virtual void SetVisualRect(const IntRect& r) { visual_rect_ = r; } 181 182 // Marks the scrollbar as needing to be redrawn. 183 // 184 // If invalid parts are provided, then those parts will also be repainted. 185 // Otherwise, the ScrollableArea may redraw using cached renderings of 186 // individual parts. For instance, if the scrollbar is composited, the thumb 187 // may be cached in a GPU texture (and is only guaranteed to be repainted if 188 // ThumbPart is invalidated). 189 // 190 // Even if no parts are invalidated, the scrollbar may need to be redrawn 191 // if, for instance, the thumb moves without changing the appearance of any 192 // part. 193 void SetNeedsPaintInvalidation(ScrollbarPart invalid_parts); 194 195 CompositorElementId GetElementId(); 196 197 float EffectiveZoom() const; 198 bool ContainerIsRightToLeft() const; 199 200 // The Element that supplies our style information. If the scrollbar is 201 // for a document, this is either the <body> or <html> element. Otherwise, it 202 // is the element that owns our PaintLayerScrollableArea. StyleSource()203 Element* StyleSource() const { return style_source_.Get(); } 204 205 WebColorScheme UsedColorScheme() const; 206 207 virtual void Trace(Visitor*); 208 209 protected: 210 void AutoscrollTimerFired(TimerBase*); 211 void StartTimerIfNeeded(base::TimeDelta delay); 212 void StopTimerIfNeeded(); 213 void AutoscrollPressedPart(base::TimeDelta delay); 214 bool HandleTapGesture(); 215 void InjectScrollGestureForPressedPart(WebInputEvent::Type gesture_type); 216 void InjectGestureScrollUpdateForThumbMove(float single_axis_target_offset); 217 void InjectScrollGesture(WebInputEvent::Type type, 218 ScrollOffset delta, 219 ScrollGranularity granularity); 220 ScrollDirectionPhysical PressedPartScrollDirectionPhysical(); 221 ScrollGranularity PressedPartScrollGranularity(); 222 223 Member<ScrollableArea> scrollable_area_; 224 ScrollbarOrientation orientation_; 225 ScrollbarControlSize control_size_; 226 ScrollbarTheme& theme_; 227 Member<ChromeClient> chrome_client_; 228 229 int visible_size_; 230 int total_size_; 231 float current_pos_; 232 float drag_origin_; 233 234 ScrollbarPart hovered_part_; 235 ScrollbarPart pressed_part_; 236 int pressed_pos_; 237 float scroll_pos_; 238 bool dragging_document_; 239 int document_drag_pos_; 240 241 bool enabled_; 242 243 TaskRunnerTimer<Scrollbar> scroll_timer_; 244 245 float elastic_overscroll_; 246 247 private: 248 float ScrollableAreaCurrentPos() const; 249 float ScrollableAreaTargetPos() const; 250 bool ThumbWillBeUnderMouse() const; 251 bool DeltaWillScroll(ScrollOffset delta) const; 252 253 int theme_scrollbar_thickness_; 254 bool track_needs_repaint_; 255 bool thumb_needs_repaint_; 256 bool injected_gesture_scroll_begin_; 257 258 // This is set based on the event modifiers. In scenarios like scrolling or 259 // layout, the element that the cursor is over can change without the cursor 260 // itself moving. In these cases, a "fake" mouse move may be dispatched (see 261 // MouseEventManager::RecomputeMouseHoverState) in order to apply hover etc. 262 // Such mouse events do not have the modifier set and hence, maintaining this 263 // additional state is necessary. 264 bool scrollbar_manipulation_in_progress_on_cc_thread_; 265 266 IntRect visual_rect_; 267 IntRect frame_rect_; 268 Member<Element> style_source_; 269 }; 270 271 } // namespace blink 272 273 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_H_ 274