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 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