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 WebCore { 50 51 enum ResizerHitTestType { 52 ResizerForPointer, 53 ResizerForTouch 54 }; 55 56 enum ForceNeedsCompositedScrollingMode { 57 DoNotForceCompositedScrolling = 0, 58 CompositedScrollingAlwaysOn = 1, 59 CompositedScrollingAlwaysOff = 2 60 }; 61 62 class PlatformEvent; 63 class RenderBox; 64 class RenderLayer; 65 class RenderScrollbarPart; 66 67 class RenderLayerScrollableArea FINAL : public ScrollableArea { 68 friend class Internals; 69 70 public: 71 RenderLayerScrollableArea(RenderBox*); 72 virtual ~RenderLayerScrollableArea(); 73 74 bool hasHorizontalScrollbar() const { return horizontalScrollbar(); } 75 bool hasVerticalScrollbar() const { return verticalScrollbar(); } 76 77 virtual Scrollbar* horizontalScrollbar() const OVERRIDE { return m_hBar.get(); } 78 virtual Scrollbar* verticalScrollbar() const OVERRIDE { return m_vBar.get(); } 79 virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE; 80 81 virtual GraphicsLayer* layerForScrolling() const OVERRIDE; 82 virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE; 83 virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE; 84 virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE; 85 virtual bool usesCompositedScrolling() const OVERRIDE; 86 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE; 87 virtual void invalidateScrollCornerRect(const IntRect&) OVERRIDE; 88 virtual bool isActive() const OVERRIDE; 89 virtual bool isScrollCornerVisible() const OVERRIDE; 90 virtual IntRect scrollCornerRect() const OVERRIDE; 91 virtual IntRect convertFromScrollbarToContainingView(const Scrollbar*, const IntRect&) const OVERRIDE; 92 virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const OVERRIDE; 93 virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const OVERRIDE; 94 virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const OVERRIDE; 95 virtual int scrollSize(ScrollbarOrientation) const OVERRIDE; 96 virtual void setScrollOffset(const IntPoint&) OVERRIDE; 97 virtual IntPoint scrollPosition() const OVERRIDE; 98 virtual IntPoint minimumScrollPosition() const OVERRIDE; 99 virtual IntPoint maximumScrollPosition() const OVERRIDE; 100 virtual IntRect visibleContentRect(IncludeScrollbarsInRect) const OVERRIDE; 101 virtual int visibleHeight() const OVERRIDE; 102 virtual int visibleWidth() const OVERRIDE; 103 virtual IntSize contentsSize() const OVERRIDE; 104 virtual IntSize overhangAmount() const OVERRIDE; 105 virtual IntPoint lastKnownMousePosition() const OVERRIDE; 106 virtual bool shouldSuspendScrollAnimations() const OVERRIDE; 107 virtual bool scrollbarsCanBeActive() const OVERRIDE; 108 virtual IntRect scrollableAreaBoundingBox() const OVERRIDE; 109 virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE; 110 virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE; 111 virtual int pageStep(ScrollbarOrientation) const OVERRIDE; 112 113 int scrollXOffset() const { return m_scrollOffset.width() + scrollOrigin().x(); } 114 int scrollYOffset() const { return m_scrollOffset.height() + scrollOrigin().y(); } 115 116 IntSize scrollOffset() const { return m_scrollOffset; } 117 118 // FIXME: We shouldn't allow access to m_overflowRect outside this class. 119 LayoutRect overflowRect() const { return m_overflowRect; } 120 121 void scrollToOffset(const IntSize& scrollOffset, ScrollOffsetClamping = ScrollOffsetUnclamped); 122 void scrollToXOffset(int x, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(x, scrollYOffset()), clamp); } 123 void scrollToYOffset(int y, ScrollOffsetClamping clamp = ScrollOffsetUnclamped) { scrollToOffset(IntSize(scrollXOffset(), y), clamp); } 124 125 void updateAfterLayout(); 126 void updateAfterStyleChange(const RenderStyle*); 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 int scrollWidth() const; 145 int scrollHeight() const; 146 147 int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 148 int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const; 149 150 IntSize adjustedScrollOffset() const { return IntSize(scrollXOffset(), scrollYOffset()); } 151 152 void paintResizer(GraphicsContext*, const IntPoint& paintOffset, const IntRect& damageRect); 153 void paintOverflowControls(GraphicsContext*, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls); 154 void paintScrollCorner(GraphicsContext*, const IntPoint&, const IntRect& damageRect); 155 156 // If IntSize is not given, then we must incur additional overhead to instantiate a RenderGeometryMap 157 // and compute the correct offset ourselves. 158 void positionOverflowControls(); 159 void positionOverflowControls(const IntSize& offsetFromRoot); 160 161 // isPointInResizeControl() is used for testing if a pointer/touch position is in the resize control 162 // area. 163 bool isPointInResizeControl(const IntPoint& absolutePoint, ResizerHitTestType) const; 164 bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint); 165 166 bool hitTestResizerInFragments(const LayerFragments&, const HitTestLocation&) const; 167 168 LayoutRect exposeRect(const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY); 169 170 bool scrollsOverflow() const; 171 172 // Rectangle encompassing the scroll corner and resizer rect. 173 IntRect scrollCornerAndResizerRect() const; 174 175 bool needsCompositedScrolling() const; 176 177 // FIXME: This needs to be exposed as forced compositing scrolling is a RenderLayerScrollableArea 178 // concept and stacking container is a RenderLayerStackingNode concept. 179 bool adjustForForceCompositedScrollingMode(bool) const; 180 181 private: 182 bool hasHorizontalOverflow() const; 183 bool hasVerticalOverflow() const; 184 bool hasScrollableHorizontalOverflow() const; 185 bool hasScrollableVerticalOverflow() const; 186 187 void computeScrollDimensions(); 188 189 IntSize clampScrollOffset(const IntSize&) const; 190 191 void setScrollOffset(const IntSize& scrollOffset) { m_scrollOffset = scrollOffset; } 192 193 IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const; 194 IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const; 195 LayoutUnit verticalScrollbarStart(int minX, int maxX) const; 196 LayoutUnit horizontalScrollbarStart(int minX) const; 197 IntSize scrollbarOffset(const Scrollbar*) const; 198 199 PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation); 200 void destroyScrollbar(ScrollbarOrientation); 201 202 void setHasHorizontalScrollbar(bool hasScrollbar); 203 void setHasVerticalScrollbar(bool hasScrollbar); 204 205 void updateScrollCornerStyle(); 206 207 // See comments on isPointInResizeControl. 208 IntRect resizerCornerRect(const IntRect&, ResizerHitTestType) const; 209 bool overflowControlsIntersectRect(const IntRect& localRect) const; 210 void updateResizerAreaSet(); 211 void updateResizerStyle(); 212 void drawPlatformResizerImage(GraphicsContext*, IntRect resizerCornerRect); 213 214 RenderLayer* layer() const; 215 216 void updateScrollableAreaSet(bool hasOverflow); 217 218 void updateCompositingLayersAfterScroll(); 219 virtual void updateNeedsCompositedScrolling() OVERRIDE; 220 bool setNeedsCompositedScrolling(bool); 221 222 virtual void updateHasVisibleNonLayerContent() OVERRIDE; 223 224 void setForceNeedsCompositedScrolling(ForceNeedsCompositedScrollingMode); 225 226 RenderBox* m_box; 227 228 // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop. 229 unsigned m_inResizeMode : 1; 230 231 unsigned m_scrollDimensionsDirty : 1; 232 unsigned m_inOverflowRelayout : 1; 233 234 unsigned m_needsCompositedScrolling : 1; 235 unsigned m_willUseCompositedScrollingHasBeenRecorded : 1; 236 237 unsigned m_isScrollableAreaHasBeenRecorded : 1; 238 239 ForceNeedsCompositedScrollingMode m_forceNeedsCompositedScrolling; 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 RenderScrollbarPart* m_scrollCorner; 255 256 // Renderers to hold our custom resizer. 257 RenderScrollbarPart* m_resizer; 258 }; 259 260 } // Namespace WebCore 261 262 #endif // RenderLayerScrollableArea_h 263