Home | History | Annotate | Download | only in rendering
      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