1 /* 2 * Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved. 3 * 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 5 * 6 * Other contributors: 7 * Robert O'Callahan <roc+@cs.cmu.edu> 8 * David Baron <dbaron (at) fas.harvard.edu> 9 * Christian Biesinger <cbiesinger (at) web.de> 10 * Randall Jesup <rjesup (at) wgate.com> 11 * Roland Mainz <roland.mainz (at) informatik.med.uni-giessen.de> 12 * Josh Soref <timeless (at) mac.com> 13 * Boris Zbarsky <bzbarsky (at) mit.edu> 14 * 15 * This library is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU Lesser General Public 17 * License as published by the Free Software Foundation; either 18 * version 2.1 of the License, or (at your option) any later version. 19 * 20 * This library is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 * Lesser General Public License for more details. 24 * 25 * You should have received a copy of the GNU Lesser General Public 26 * License along with this library; if not, write to the Free Software 27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 28 * 29 * Alternatively, the contents of this file may be used under the terms 30 * of either the Mozilla Public License Version 1.1, found at 31 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public 32 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html 33 * (the "GPL"), in which case the provisions of the MPL or the GPL are 34 * applicable instead of those above. If you wish to allow use of your 35 * version of this file only under the terms of one of those two 36 * licenses (the MPL or the GPL) and not to allow others to use your 37 * version of this file under the LGPL, indicate your decision by 38 * deletingthe provisions above and replace them with the notice and 39 * other provisions required by the MPL or the GPL, as the case may be. 40 * If you do not delete the provisions above, a recipient may use your 41 * version of this file under any of the LGPL, the MPL or the GPL. 42 */ 43 44 #ifndef RenderLayerScrollableArea_h 45 #define RenderLayerScrollableArea_h 46 47 #include "platform/scroll/ScrollableArea.h" 48 49 namespace blink { 50 51 enum ResizerHitTestType { 52 ResizerForPointer, 53 ResizerForTouch 54 }; 55 56 class PlatformEvent; 57 class RenderBox; 58 class RenderLayer; 59 class RenderScrollbarPart; 60 61 class RenderLayerScrollableArea FINAL : public ScrollableArea { 62 friend class Internals; 63 64 public: 65 // FIXME: We should pass in the RenderBox but this opens a window 66 // for crashers during RenderLayer setup (see crbug.com/368062). 67 RenderLayerScrollableArea(RenderLayer&); 68 virtual ~RenderLayerScrollableArea(); 69 70 bool hasHorizontalScrollbar() const { return horizontalScrollbar(); } 71 bool hasVerticalScrollbar() const { return verticalScrollbar(); } 72 73 virtual Scrollbar* horizontalScrollbar() const OVERRIDE { return m_hBar.get(); } 74 virtual Scrollbar* verticalScrollbar() const OVERRIDE { return m_vBar.get(); } 75 76 virtual HostWindow* hostWindow() const OVERRIDE; 77 78 virtual GraphicsLayer* layerForScrolling() const OVERRIDE; 79 virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE; 80 virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE; 81 virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE; 82 virtual bool usesCompositedScrolling() const OVERRIDE; 83 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE; 84 virtual void invalidateScrollCornerRect(const IntRect&) OVERRIDE; 85 virtual bool isActive() const OVERRIDE; 86 virtual bool isScrollCornerVisible() const OVERRIDE; 87 virtual IntRect scrollCornerRect() const OVERRIDE; 88 virtual IntRect convertFromScrollbarToContainingView(const Scrollbar*, const IntRect&) const OVERRIDE; 89 virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const OVERRIDE; 90 virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const OVERRIDE; 91 virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const OVERRIDE; 92 virtual int scrollSize(ScrollbarOrientation) const OVERRIDE; 93 virtual void setScrollOffset(const IntPoint&) OVERRIDE; 94 virtual IntPoint scrollPosition() const OVERRIDE; 95 virtual IntPoint minimumScrollPosition() const OVERRIDE; 96 virtual IntPoint maximumScrollPosition() const OVERRIDE; 97 virtual IntRect visibleContentRect(IncludeScrollbarsInRect) const OVERRIDE; 98 virtual int visibleHeight() const OVERRIDE; 99 virtual int visibleWidth() const OVERRIDE; 100 virtual IntSize contentsSize() const OVERRIDE; 101 virtual IntSize overhangAmount() const OVERRIDE; 102 virtual IntPoint lastKnownMousePosition() const OVERRIDE; 103 virtual bool shouldSuspendScrollAnimations() const OVERRIDE; 104 virtual bool scrollbarsCanBeActive() const OVERRIDE; 105 virtual IntRect scrollableAreaBoundingBox() const OVERRIDE; 106 virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE; 107 virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE; 108 virtual int pageStep(ScrollbarOrientation) const OVERRIDE; 109 110 int scrollXOffset() const { return m_scrollOffset.width() + scrollOrigin().x(); } 111 int scrollYOffset() const { return m_scrollOffset.height() + scrollOrigin().y(); } 112 113 IntSize scrollOffset() const { return m_scrollOffset; } 114 115 // FIXME: We shouldn't allow access to m_overflowRect outside this class. 116 LayoutRect overflowRect() const { return m_overflowRect; } 117 118 void scrollToOffset(const IntSize& scrollOffset, ScrollOffsetClamping = ScrollOffsetUnclamped); 119 void scrollToXOffset(int x, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(x, scrollYOffset()), clamp); } 120 void scrollToYOffset(int y, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(scrollXOffset(), y), clamp); } 121 122 void updateAfterLayout(); 123 void updateAfterStyleChange(const RenderStyle*); 124 void updateAfterOverflowRecalc(); 125 126 virtual bool updateAfterCompositingChange() OVERRIDE; 127 128 bool hasScrollbar() const { return m_hBar || m_vBar; } 129 130 // FIXME: This should be removed. 131 bool hasScrollCorner() const { return m_scrollCorner; } 132 133 void resize(const PlatformEvent&, const LayoutSize&); 134 IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const; 135 136 bool inResizeMode() const { return m_inResizeMode; } 137 void setInResizeMode(bool inResizeMode) { m_inResizeMode = inResizeMode; } 138 139 IntRect touchResizerCornerRect(const IntRect& bounds) const 140 { 141 return resizerCornerRect(bounds, ResizerForTouch); 142 } 143 144 LayoutUnit scrollWidth() const; 145 LayoutUnit scrollHeight() const; 146 int pixelSnappedScrollWidth() const; 147 int pixelSnappedScrollHeight() const; 148 149 int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 150 int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 151 152 IntSize adjustedScrollOffset() const { return IntSize(scrollXOffset(), scrollYOffset()); } 153 154 void paintResizer(GraphicsContext*, const IntPoint& paintOffset, const IntRect& damageRect); 155 void paintOverflowControls(GraphicsContext*, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls); 156 void paintScrollCorner(GraphicsContext*, const IntPoint&, const IntRect& damageRect); 157 158 void positionOverflowControls(const IntSize& offsetFromRoot); 159 160 // isPointInResizeControl() is used for testing if a pointer/touch position is in the resize control 161 // area. 162 bool isPointInResizeControl(const IntPoint& absolutePoint, ResizerHitTestType) const; 163 bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint); 164 165 bool hitTestResizerInFragments(const LayerFragments&, const HitTestLocation&) const; 166 167 LayoutRect exposeRect(const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY); 168 169 // Returns true our scrollable area is in the FrameView's collection of scrollable areas. This can 170 // only happen if we're both scrollable, and we do in fact overflow. This means that overflow: hidden 171 // layers never get added to the FrameView's collection. 172 bool scrollsOverflow() const { return m_scrollsOverflow; } 173 174 // Rectangle encompassing the scroll corner and resizer rect. 175 IntRect scrollCornerAndResizerRect() const; 176 177 void updateNeedsCompositedScrolling(); 178 bool needsCompositedScrolling() const { return m_needsCompositedScrolling; } 179 180 // These are used during compositing updates to determine if the overflow 181 // controls need to be repositioned in the GraphicsLayer tree. 182 void setTopmostScrollChild(RenderLayer*); 183 RenderLayer* topmostScrollChild() const { ASSERT(!m_nextTopmostScrollChild); return m_topmostScrollChild; } 184 185 private: 186 bool hasHorizontalOverflow() const; 187 bool hasVerticalOverflow() const; 188 bool hasScrollableHorizontalOverflow() const; 189 bool hasScrollableVerticalOverflow() const; 190 191 void computeScrollDimensions(); 192 193 IntSize clampScrollOffset(const IntSize&) const; 194 195 void setScrollOffset(const IntSize& scrollOffset) { m_scrollOffset = scrollOffset; } 196 197 IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const; 198 IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const; 199 LayoutUnit verticalScrollbarStart(int minX, int maxX) const; 200 LayoutUnit horizontalScrollbarStart(int minX) const; 201 IntSize scrollbarOffset(const Scrollbar*) const; 202 203 PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation); 204 void destroyScrollbar(ScrollbarOrientation); 205 206 void setHasHorizontalScrollbar(bool hasScrollbar); 207 void setHasVerticalScrollbar(bool hasScrollbar); 208 209 void updateScrollCornerStyle(); 210 211 // See comments on isPointInResizeControl. 212 IntRect resizerCornerRect(const IntRect&, ResizerHitTestType) const; 213 bool overflowControlsIntersectRect(const IntRect& localRect) const; 214 void updateResizerAreaSet(); 215 void updateResizerStyle(); 216 void drawPlatformResizerImage(GraphicsContext*, IntRect resizerCornerRect); 217 218 RenderBox& box() const; 219 RenderLayer* layer() const; 220 221 void updateScrollableAreaSet(bool hasOverflow); 222 223 void updateCompositingLayersAfterScroll(); 224 225 RenderLayer& m_layer; 226 227 // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop. 228 unsigned m_inResizeMode : 1; 229 unsigned m_scrollsOverflow : 1; 230 231 unsigned m_scrollDimensionsDirty : 1; 232 unsigned m_inOverflowRelayout : 1; 233 234 RenderLayer* m_nextTopmostScrollChild; 235 RenderLayer* m_topmostScrollChild; 236 237 // FIXME: once cc can handle composited scrolling with clip paths, we will 238 // no longer need this bit. 239 unsigned m_needsCompositedScrolling : 1; 240 241 // The width/height of our scrolled area. 242 LayoutRect m_overflowRect; 243 244 // This is the (scroll) offset from scrollOrigin(). 245 IntSize m_scrollOffset; 246 247 IntPoint m_cachedOverlayScrollbarOffset; 248 249 // For areas with overflow, we have a pair of scrollbars. 250 RefPtr<Scrollbar> m_hBar; 251 RefPtr<Scrollbar> m_vBar; 252 253 // Renderers to hold our custom scroll corner. 254 RawPtrWillBePersistent<RenderScrollbarPart> m_scrollCorner; 255 256 // Renderers to hold our custom resizer. 257 RawPtrWillBePersistent<RenderScrollbarPart> m_resizer; 258 }; 259 260 } // namespace blink 261 262 #endif // RenderLayerScrollableArea_h 263