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@fas.harvard.edu> 9 * Christian Biesinger <cbiesinger@web.de> 10 * Randall Jesup <rjesup@wgate.com> 11 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> 12 * Josh Soref <timeless@mac.com> 13 * Boris Zbarsky <bzbarsky@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 WebCore { 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 hasHorizontalScrollbar()70 bool hasHorizontalScrollbar() const { return horizontalScrollbar(); } hasVerticalScrollbar()71 bool hasVerticalScrollbar() const { return verticalScrollbar(); } 72 horizontalScrollbar()73 virtual Scrollbar* horizontalScrollbar() const OVERRIDE { return m_hBar.get(); } verticalScrollbar()74 virtual Scrollbar* verticalScrollbar() const OVERRIDE { return m_vBar.get(); } 75 76 virtual GraphicsLayer* layerForScrolling() const OVERRIDE; 77 virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE; 78 virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE; 79 virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE; 80 virtual bool usesCompositedScrolling() const OVERRIDE; 81 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE; 82 virtual void invalidateScrollCornerRect(const IntRect&) OVERRIDE; 83 virtual bool isActive() const OVERRIDE; 84 virtual bool isScrollCornerVisible() const OVERRIDE; 85 virtual IntRect scrollCornerRect() const OVERRIDE; 86 virtual IntRect convertFromScrollbarToContainingView(const Scrollbar*, const IntRect&) const OVERRIDE; 87 virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const OVERRIDE; 88 virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const OVERRIDE; 89 virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const OVERRIDE; 90 virtual int scrollSize(ScrollbarOrientation) const OVERRIDE; 91 virtual void setScrollOffset(const IntPoint&) OVERRIDE; 92 virtual IntPoint scrollPosition() const OVERRIDE; 93 virtual IntPoint minimumScrollPosition() const OVERRIDE; 94 virtual IntPoint maximumScrollPosition() const OVERRIDE; 95 virtual IntRect visibleContentRect(IncludeScrollbarsInRect) const OVERRIDE; 96 virtual int visibleHeight() const OVERRIDE; 97 virtual int visibleWidth() const OVERRIDE; 98 virtual IntSize contentsSize() const OVERRIDE; 99 virtual IntSize overhangAmount() const OVERRIDE; 100 virtual IntPoint lastKnownMousePosition() const OVERRIDE; 101 virtual bool shouldSuspendScrollAnimations() const OVERRIDE; 102 virtual bool scrollbarsCanBeActive() const OVERRIDE; 103 virtual IntRect scrollableAreaBoundingBox() const OVERRIDE; 104 virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE; 105 virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE; pageStep(ScrollbarOrientation)106 virtual int pageStep(ScrollbarOrientation) const OVERRIDE; 107 108 int scrollXOffset() const { return m_scrollOffset.width() + scrollOrigin().x(); } scrollYOffset()109 int scrollYOffset() const { return m_scrollOffset.height() + scrollOrigin().y(); } 110 scrollOffset()111 IntSize scrollOffset() const { return m_scrollOffset; } 112 113 // FIXME: We shouldn't allow access to m_overflowRect outside this class. overflowRect()114 LayoutRect overflowRect() const { return m_overflowRect; } 115 116 void scrollToOffset(const IntSize& scrollOffset, ScrollOffsetClamping = ScrollOffsetUnclamped); 117 void scrollToXOffset(int x, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(x, scrollYOffset()), clamp); } 118 void scrollToYOffset(int y, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(scrollXOffset(), y), clamp); } 119 120 void updateAfterLayout(); 121 void updateAfterStyleChange(const RenderStyle*); 122 void updateAfterOverflowRecalc(); 123 124 virtual void updateAfterCompositingChange() OVERRIDE; 125 hasScrollbar()126 bool hasScrollbar() const { return m_hBar || m_vBar; } 127 128 // FIXME: This should be removed. hasScrollCorner()129 bool hasScrollCorner() const { return m_scrollCorner; } 130 131 void resize(const PlatformEvent&, const LayoutSize&); 132 IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const; 133 inResizeMode()134 bool inResizeMode() const { return m_inResizeMode; } setInResizeMode(bool inResizeMode)135 void setInResizeMode(bool inResizeMode) { m_inResizeMode = inResizeMode; } 136 touchResizerCornerRect(const IntRect & bounds)137 IntRect touchResizerCornerRect(const IntRect& bounds) const 138 { 139 return resizerCornerRect(bounds, ResizerForTouch); 140 } 141 142 LayoutUnit scrollWidth() const; 143 LayoutUnit scrollHeight() const; 144 145 int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 146 int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 147 adjustedScrollOffset()148 IntSize adjustedScrollOffset() const { return IntSize(scrollXOffset(), scrollYOffset()); } 149 150 void paintResizer(GraphicsContext*, const IntPoint& paintOffset, const IntRect& damageRect); 151 void paintOverflowControls(GraphicsContext*, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls); 152 void paintScrollCorner(GraphicsContext*, const IntPoint&, const IntRect& damageRect); 153 154 void positionOverflowControls(const IntSize& offsetFromRoot); 155 156 // isPointInResizeControl() is used for testing if a pointer/touch position is in the resize control 157 // area. 158 bool isPointInResizeControl(const IntPoint& absolutePoint, ResizerHitTestType) const; 159 bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint); 160 161 bool hitTestResizerInFragments(const LayerFragments&, const HitTestLocation&) const; 162 163 LayoutRect exposeRect(const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY); 164 165 // Returns true our scrollable area is in the FrameView's collection of scrollable areas. This can 166 // only happen if we're both scrollable, and we do in fact overflow. This means that overflow: hidden 167 // layers never get added to the FrameView's collection. scrollsOverflow()168 bool scrollsOverflow() const { return m_scrollsOverflow; } 169 170 // Rectangle encompassing the scroll corner and resizer rect. 171 IntRect scrollCornerAndResizerRect() const; 172 173 bool needsCompositedScrolling() const; 174 175 // FIXME: This needs to be exposed as forced compositing scrolling is a RenderLayerScrollableArea 176 // concept and stacking container is a RenderLayerStackingNode concept. 177 bool adjustForForceCompositedScrollingMode(bool) const; 178 179 private: 180 bool hasHorizontalOverflow() const; 181 bool hasVerticalOverflow() const; 182 bool hasScrollableHorizontalOverflow() const; 183 bool hasScrollableVerticalOverflow() const; 184 185 void computeScrollDimensions(); 186 187 IntSize clampScrollOffset(const IntSize&) const; 188 setScrollOffset(const IntSize & scrollOffset)189 void setScrollOffset(const IntSize& scrollOffset) { m_scrollOffset = scrollOffset; } 190 191 IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const; 192 IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const; 193 LayoutUnit verticalScrollbarStart(int minX, int maxX) const; 194 LayoutUnit horizontalScrollbarStart(int minX) const; 195 IntSize scrollbarOffset(const Scrollbar*) const; 196 197 PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation); 198 void destroyScrollbar(ScrollbarOrientation); 199 200 void setHasHorizontalScrollbar(bool hasScrollbar); 201 void setHasVerticalScrollbar(bool hasScrollbar); 202 203 void updateScrollCornerStyle(); 204 205 // See comments on isPointInResizeControl. 206 IntRect resizerCornerRect(const IntRect&, ResizerHitTestType) const; 207 bool overflowControlsIntersectRect(const IntRect& localRect) const; 208 void updateResizerAreaSet(); 209 void updateResizerStyle(); 210 void drawPlatformResizerImage(GraphicsContext*, IntRect resizerCornerRect); 211 212 RenderBox& box() const; 213 RenderLayer* layer() const; 214 215 void updateScrollableAreaSet(bool hasOverflow); 216 217 void updateCompositingLayersAfterScroll(); 218 219 RenderLayer& m_layer; 220 221 // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop. 222 unsigned m_inResizeMode : 1; 223 unsigned m_scrollsOverflow : 1; 224 225 unsigned m_scrollDimensionsDirty : 1; 226 unsigned m_inOverflowRelayout : 1; 227 228 // The width/height of our scrolled area. 229 LayoutRect m_overflowRect; 230 231 // This is the (scroll) offset from scrollOrigin(). 232 IntSize m_scrollOffset; 233 234 IntPoint m_cachedOverlayScrollbarOffset; 235 236 // For areas with overflow, we have a pair of scrollbars. 237 RefPtr<Scrollbar> m_hBar; 238 RefPtr<Scrollbar> m_vBar; 239 240 // Renderers to hold our custom scroll corner. 241 RenderScrollbarPart* m_scrollCorner; 242 243 // Renderers to hold our custom resizer. 244 RenderScrollbarPart* m_resizer; 245 }; 246 247 } // Namespace WebCore 248 249 #endif // RenderLayerScrollableArea_h 250