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 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 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;
    106     virtual int pageStep(ScrollbarOrientation) const OVERRIDE;
    107 
    108     int scrollXOffset() const { return m_scrollOffset.width() + scrollOrigin().x(); }
    109     int scrollYOffset() const { return m_scrollOffset.height() + scrollOrigin().y(); }
    110 
    111     IntSize scrollOffset() const { return m_scrollOffset; }
    112 
    113     // FIXME: We shouldn't allow access to m_overflowRect outside this class.
    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 
    126     bool hasScrollbar() const { return m_hBar || m_vBar; }
    127 
    128     // FIXME: This should be removed.
    129     bool hasScrollCorner() const { return m_scrollCorner; }
    130 
    131     void resize(const PlatformEvent&, const LayoutSize&);
    132     IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const;
    133 
    134     bool inResizeMode() const { return m_inResizeMode; }
    135     void setInResizeMode(bool inResizeMode) { m_inResizeMode = inResizeMode; }
    136 
    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 
    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.
    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 
    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