Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | /* |
michael@0 | 7 | * interface that provides scroll APIs implemented by scrollable frames |
michael@0 | 8 | */ |
michael@0 | 9 | |
michael@0 | 10 | #ifndef nsIScrollFrame_h___ |
michael@0 | 11 | #define nsIScrollFrame_h___ |
michael@0 | 12 | |
michael@0 | 13 | #include "nsCoord.h" |
michael@0 | 14 | #include "ScrollbarStyles.h" |
michael@0 | 15 | #include "mozilla/gfx/Point.h" |
michael@0 | 16 | #include "nsIScrollbarOwner.h" |
michael@0 | 17 | #include "Units.h" |
michael@0 | 18 | |
michael@0 | 19 | #define NS_DEFAULT_VERTICAL_SCROLL_DISTANCE 3 |
michael@0 | 20 | #define NS_DEFAULT_HORIZONTAL_SCROLL_DISTANCE 5 |
michael@0 | 21 | |
michael@0 | 22 | class nsBoxLayoutState; |
michael@0 | 23 | class nsIScrollPositionListener; |
michael@0 | 24 | class nsIFrame; |
michael@0 | 25 | class nsPresContext; |
michael@0 | 26 | class nsIContent; |
michael@0 | 27 | class nsRenderingContext; |
michael@0 | 28 | class nsIAtom; |
michael@0 | 29 | |
michael@0 | 30 | /** |
michael@0 | 31 | * Interface for frames that are scrollable. This interface exposes |
michael@0 | 32 | * APIs for examining scroll state, observing changes to scroll state, |
michael@0 | 33 | * and triggering scrolling. |
michael@0 | 34 | */ |
michael@0 | 35 | class nsIScrollableFrame : public nsIScrollbarOwner { |
michael@0 | 36 | public: |
michael@0 | 37 | typedef mozilla::CSSIntPoint CSSIntPoint; |
michael@0 | 38 | |
michael@0 | 39 | NS_DECL_QUERYFRAME_TARGET(nsIScrollableFrame) |
michael@0 | 40 | |
michael@0 | 41 | /** |
michael@0 | 42 | * Get the frame for the content that we are scrolling within |
michael@0 | 43 | * this scrollable frame. |
michael@0 | 44 | */ |
michael@0 | 45 | virtual nsIFrame* GetScrolledFrame() const = 0; |
michael@0 | 46 | |
michael@0 | 47 | /** |
michael@0 | 48 | * Get the styles (NS_STYLE_OVERFLOW_SCROLL, NS_STYLE_OVERFLOW_HIDDEN, |
michael@0 | 49 | * or NS_STYLE_OVERFLOW_AUTO) governing the horizontal and vertical |
michael@0 | 50 | * scrollbars for this frame. |
michael@0 | 51 | */ |
michael@0 | 52 | virtual mozilla::ScrollbarStyles GetScrollbarStyles() const = 0; |
michael@0 | 53 | |
michael@0 | 54 | enum { HORIZONTAL = 0x01, VERTICAL = 0x02 }; |
michael@0 | 55 | /** |
michael@0 | 56 | * Return the scrollbars which are visible. It's OK to call this during reflow |
michael@0 | 57 | * of the scrolled contents, in which case it will reflect the current |
michael@0 | 58 | * assumptions about scrollbar visibility. |
michael@0 | 59 | */ |
michael@0 | 60 | virtual uint32_t GetScrollbarVisibility() const = 0; |
michael@0 | 61 | /** |
michael@0 | 62 | * Returns the directions in which scrolling is perceived to be allowed. |
michael@0 | 63 | * A direction is perceived to be allowed if there is a visible scrollbar |
michael@0 | 64 | * for that direction or if the scroll range is at least one device pixel. |
michael@0 | 65 | */ |
michael@0 | 66 | uint32_t GetPerceivedScrollingDirections() const; |
michael@0 | 67 | /** |
michael@0 | 68 | * Return the actual sizes of all possible scrollbars. Returns 0 for scrollbar |
michael@0 | 69 | * positions that don't have a scrollbar or where the scrollbar is not visible. |
michael@0 | 70 | * Do not call this while this frame's descendants are being reflowed, it won't be |
michael@0 | 71 | * accurate. |
michael@0 | 72 | */ |
michael@0 | 73 | virtual nsMargin GetActualScrollbarSizes() const = 0; |
michael@0 | 74 | /** |
michael@0 | 75 | * Return the sizes of all scrollbars assuming that any scrollbars that could |
michael@0 | 76 | * be visible due to overflowing content, are. This can be called during reflow |
michael@0 | 77 | * of the scrolled contents. |
michael@0 | 78 | */ |
michael@0 | 79 | virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) = 0; |
michael@0 | 80 | /** |
michael@0 | 81 | * Return the sizes of all scrollbars assuming that any scrollbars that could |
michael@0 | 82 | * be visible due to overflowing content, are. This can be called during reflow |
michael@0 | 83 | * of the scrolled contents. |
michael@0 | 84 | */ |
michael@0 | 85 | virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, |
michael@0 | 86 | nsRenderingContext* aRC) = 0; |
michael@0 | 87 | /** |
michael@0 | 88 | * Return the width for non-disappearing scrollbars. |
michael@0 | 89 | */ |
michael@0 | 90 | virtual nscoord GetNondisappearingScrollbarWidth(nsPresContext* aPresContext, |
michael@0 | 91 | nsRenderingContext* aRC) = 0; |
michael@0 | 92 | /** |
michael@0 | 93 | * GetScrolledRect is designed to encapsulate deciding which |
michael@0 | 94 | * directions of overflow should be reachable by scrolling and which |
michael@0 | 95 | * should not. Callers should NOT depend on it having any particular |
michael@0 | 96 | * behavior (although nsXULScrollFrame currently does). |
michael@0 | 97 | * |
michael@0 | 98 | * This should only be called when the scrolled frame has been |
michael@0 | 99 | * reflowed with the scroll port size given in mScrollPort. |
michael@0 | 100 | * |
michael@0 | 101 | * Currently it allows scrolling down and to the right for |
michael@0 | 102 | * nsHTMLScrollFrames with LTR directionality and for all |
michael@0 | 103 | * nsXULScrollFrames, and allows scrolling down and to the left for |
michael@0 | 104 | * nsHTMLScrollFrames with RTL directionality. |
michael@0 | 105 | */ |
michael@0 | 106 | virtual nsRect GetScrolledRect() const = 0; |
michael@0 | 107 | /** |
michael@0 | 108 | * Get the area of the scrollport relative to the origin of this frame's |
michael@0 | 109 | * border-box. |
michael@0 | 110 | * This is the area of this frame minus border and scrollbars. |
michael@0 | 111 | */ |
michael@0 | 112 | virtual nsRect GetScrollPortRect() const = 0; |
michael@0 | 113 | /** |
michael@0 | 114 | * Get the offset of the scrollport origin relative to the scrolled |
michael@0 | 115 | * frame origin. Typically the position will be non-negative. |
michael@0 | 116 | * This will always be a multiple of device pixels. |
michael@0 | 117 | */ |
michael@0 | 118 | virtual nsPoint GetScrollPosition() const = 0; |
michael@0 | 119 | /** |
michael@0 | 120 | * As GetScrollPosition(), but uses the top-right as origin for RTL frames. |
michael@0 | 121 | */ |
michael@0 | 122 | virtual nsPoint GetLogicalScrollPosition() const = 0; |
michael@0 | 123 | /** |
michael@0 | 124 | * Get the area that must contain the scroll position. Typically |
michael@0 | 125 | * (but not always, e.g. for RTL content) x and y will be 0, and |
michael@0 | 126 | * width or height will be nonzero if the content can be scrolled in |
michael@0 | 127 | * that direction. Since scroll positions must be a multiple of |
michael@0 | 128 | * device pixels, the range extrema will also be a multiple of |
michael@0 | 129 | * device pixels. |
michael@0 | 130 | */ |
michael@0 | 131 | virtual nsRect GetScrollRange() const = 0; |
michael@0 | 132 | /** |
michael@0 | 133 | * Get the size of the scroll port to use when clamping the scroll |
michael@0 | 134 | * position. |
michael@0 | 135 | */ |
michael@0 | 136 | virtual nsSize GetScrollPositionClampingScrollPortSize() const = 0; |
michael@0 | 137 | /** |
michael@0 | 138 | * Get the element resolution. |
michael@0 | 139 | */ |
michael@0 | 140 | virtual gfxSize GetResolution() const = 0; |
michael@0 | 141 | /** |
michael@0 | 142 | * Set the element resolution. |
michael@0 | 143 | */ |
michael@0 | 144 | virtual void SetResolution(const gfxSize& aResolution) = 0; |
michael@0 | 145 | /** |
michael@0 | 146 | * Return how much we would try to scroll by in each direction if |
michael@0 | 147 | * asked to scroll by one "line" vertically and horizontally. |
michael@0 | 148 | */ |
michael@0 | 149 | virtual nsSize GetLineScrollAmount() const = 0; |
michael@0 | 150 | /** |
michael@0 | 151 | * Return how much we would try to scroll by in each direction if |
michael@0 | 152 | * asked to scroll by one "page" vertically and horizontally. |
michael@0 | 153 | */ |
michael@0 | 154 | virtual nsSize GetPageScrollAmount() const = 0; |
michael@0 | 155 | |
michael@0 | 156 | /** |
michael@0 | 157 | * When a scroll operation is requested, we ask for instant, smooth or normal |
michael@0 | 158 | * scrolling. SMOOTH will only be smooth if smooth scrolling is actually |
michael@0 | 159 | * enabled. INSTANT is always synchronous, NORMAL can be asynchronous. |
michael@0 | 160 | * If an INSTANT request happens while a smooth or async scroll is already in |
michael@0 | 161 | * progress, the async scroll is interrupted and we instantly scroll to the |
michael@0 | 162 | * destination. |
michael@0 | 163 | */ |
michael@0 | 164 | enum ScrollMode { INSTANT, SMOOTH, NORMAL }; |
michael@0 | 165 | /** |
michael@0 | 166 | * @note This method might destroy the frame, pres shell and other objects. |
michael@0 | 167 | * Clamps aScrollPosition to GetScrollRange and sets the scroll position |
michael@0 | 168 | * to that value. |
michael@0 | 169 | * @param aRange If non-null, specifies area which contains aScrollPosition |
michael@0 | 170 | * and can be used for choosing a performance-optimized scroll position. |
michael@0 | 171 | * Any point within this area can be chosen. |
michael@0 | 172 | * The choosen point will be as close as possible to aScrollPosition. |
michael@0 | 173 | */ |
michael@0 | 174 | virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, |
michael@0 | 175 | const nsRect* aRange = nullptr) = 0; |
michael@0 | 176 | /** |
michael@0 | 177 | * @note This method might destroy the frame, pres shell and other objects. |
michael@0 | 178 | * Scrolls to a particular position in integer CSS pixels. |
michael@0 | 179 | * Keeps the exact current horizontal or vertical position if the current |
michael@0 | 180 | * position, rounded to CSS pixels, matches aScrollPosition. If |
michael@0 | 181 | * aScrollPosition.x/y is different from the current CSS pixel position, |
michael@0 | 182 | * makes sure we only move in the direction given by the difference. |
michael@0 | 183 | * Ensures that GetScrollPositionCSSPixels (the scroll position after |
michael@0 | 184 | * rounding to CSS pixels) will be exactly aScrollPosition. |
michael@0 | 185 | * The scroll mode is INSTANT. |
michael@0 | 186 | */ |
michael@0 | 187 | virtual void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition) = 0; |
michael@0 | 188 | /** |
michael@0 | 189 | * @note This method might destroy the frame, pres shell and other objects. |
michael@0 | 190 | * Scrolls to a particular position in float CSS pixels. |
michael@0 | 191 | * This does not guarantee that GetScrollPositionCSSPixels equals |
michael@0 | 192 | * aScrollPosition afterward. It tries to scroll as close to |
michael@0 | 193 | * aScrollPosition as possible while scrolling by an integer |
michael@0 | 194 | * number of layer pixels (so the operation is fast and looks clean). |
michael@0 | 195 | * The scroll mode is INSTANT. |
michael@0 | 196 | */ |
michael@0 | 197 | virtual void ScrollToCSSPixelsApproximate(const mozilla::CSSPoint& aScrollPosition, |
michael@0 | 198 | nsIAtom *aOrigin = nullptr) = 0; |
michael@0 | 199 | |
michael@0 | 200 | /** |
michael@0 | 201 | * Returns the scroll position in integer CSS pixels, rounded to the nearest |
michael@0 | 202 | * pixel. |
michael@0 | 203 | */ |
michael@0 | 204 | virtual CSSIntPoint GetScrollPositionCSSPixels() = 0; |
michael@0 | 205 | /** |
michael@0 | 206 | * When scrolling by a relative amount, we can choose various units. |
michael@0 | 207 | */ |
michael@0 | 208 | enum ScrollUnit { DEVICE_PIXELS, LINES, PAGES, WHOLE }; |
michael@0 | 209 | /** |
michael@0 | 210 | * @note This method might destroy the frame, pres shell and other objects. |
michael@0 | 211 | * Modifies the current scroll position by aDelta units given by aUnit, |
michael@0 | 212 | * clamping it to GetScrollRange. If WHOLE is specified as the unit, |
michael@0 | 213 | * content is scrolled all the way in the direction(s) given by aDelta. |
michael@0 | 214 | * @param aOverflow if non-null, returns the amount that scrolling |
michael@0 | 215 | * was clamped by in each direction (how far we moved the scroll position |
michael@0 | 216 | * to bring it back into the legal range). This is never negative. The |
michael@0 | 217 | * values are in device pixels. |
michael@0 | 218 | */ |
michael@0 | 219 | virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, |
michael@0 | 220 | nsIntPoint* aOverflow = nullptr, nsIAtom *aOrigin = nullptr) = 0; |
michael@0 | 221 | /** |
michael@0 | 222 | * @note This method might destroy the frame, pres shell and other objects. |
michael@0 | 223 | * This tells the scroll frame to try scrolling to the scroll |
michael@0 | 224 | * position that was restored from the history. This must be called |
michael@0 | 225 | * at least once after state has been restored. It is called by the |
michael@0 | 226 | * scrolled frame itself during reflow, but sometimes state can be |
michael@0 | 227 | * restored after reflows are done... |
michael@0 | 228 | * XXX should we take an aMode parameter here? Currently it's instant. |
michael@0 | 229 | */ |
michael@0 | 230 | virtual void ScrollToRestoredPosition() = 0; |
michael@0 | 231 | |
michael@0 | 232 | /** |
michael@0 | 233 | * Add a scroll position listener. This listener must be removed |
michael@0 | 234 | * before it is destroyed. |
michael@0 | 235 | */ |
michael@0 | 236 | virtual void AddScrollPositionListener(nsIScrollPositionListener* aListener) = 0; |
michael@0 | 237 | /** |
michael@0 | 238 | * Remove a scroll position listener. |
michael@0 | 239 | */ |
michael@0 | 240 | virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) = 0; |
michael@0 | 241 | |
michael@0 | 242 | /** |
michael@0 | 243 | * Internal method used by scrollbars to notify their scrolling |
michael@0 | 244 | * container of changes. |
michael@0 | 245 | */ |
michael@0 | 246 | virtual void CurPosAttributeChanged(nsIContent* aChild) = 0; |
michael@0 | 247 | |
michael@0 | 248 | /** |
michael@0 | 249 | * Allows the docshell to request that the scroll frame post an event |
michael@0 | 250 | * after being restored from history. |
michael@0 | 251 | */ |
michael@0 | 252 | NS_IMETHOD PostScrolledAreaEventForCurrentArea() = 0; |
michael@0 | 253 | |
michael@0 | 254 | /** |
michael@0 | 255 | * Returns true if this scrollframe is being "actively scrolled". |
michael@0 | 256 | * This basically means that we should allocate resources in the |
michael@0 | 257 | * expectation that scrolling is going to happen. |
michael@0 | 258 | */ |
michael@0 | 259 | virtual bool IsScrollingActive() = 0; |
michael@0 | 260 | /** |
michael@0 | 261 | * Returns true if the scrollframe is currently processing an async |
michael@0 | 262 | * or smooth scroll. |
michael@0 | 263 | */ |
michael@0 | 264 | virtual bool IsProcessingAsyncScroll() = 0; |
michael@0 | 265 | /** |
michael@0 | 266 | * Call this when the layer(s) induced by active scrolling are being |
michael@0 | 267 | * completely redrawn. |
michael@0 | 268 | */ |
michael@0 | 269 | virtual void ResetScrollPositionForLayerPixelAlignment() = 0; |
michael@0 | 270 | /** |
michael@0 | 271 | * Was the current presentation state for this frame restored from history? |
michael@0 | 272 | */ |
michael@0 | 273 | virtual bool DidHistoryRestore() const = 0; |
michael@0 | 274 | /** |
michael@0 | 275 | * Was the current resolution set by the user or just default initialized? |
michael@0 | 276 | */ |
michael@0 | 277 | virtual bool IsResolutionSet() const = 0; |
michael@0 | 278 | /** |
michael@0 | 279 | * Clear the flag so that DidHistoryRestore() returns false until the next |
michael@0 | 280 | * RestoreState call. |
michael@0 | 281 | * @see nsIStatefulFrame::RestoreState |
michael@0 | 282 | */ |
michael@0 | 283 | virtual void ClearDidHistoryRestore() = 0; |
michael@0 | 284 | /** |
michael@0 | 285 | * Determine if the passed in rect is nearly visible according to the image |
michael@0 | 286 | * visibility heuristics for how close it is to the visible scrollport. |
michael@0 | 287 | */ |
michael@0 | 288 | virtual bool IsRectNearlyVisible(const nsRect& aRect) = 0; |
michael@0 | 289 | /** |
michael@0 | 290 | * Returns the origin passed in to the last ScrollToImpl call that took |
michael@0 | 291 | * effect. |
michael@0 | 292 | */ |
michael@0 | 293 | virtual nsIAtom* OriginOfLastScroll() = 0; |
michael@0 | 294 | /** |
michael@0 | 295 | * Returns the current generation counter for the scroll. This counter |
michael@0 | 296 | * increments every time the scroll position is set. |
michael@0 | 297 | */ |
michael@0 | 298 | virtual uint32_t CurrentScrollGeneration() = 0; |
michael@0 | 299 | /** |
michael@0 | 300 | * Clears the "origin of last scroll" property stored in this frame, if |
michael@0 | 301 | * the generation counter passed in matches the current scroll generation |
michael@0 | 302 | * counter. |
michael@0 | 303 | */ |
michael@0 | 304 | virtual void ResetOriginIfScrollAtGeneration(uint32_t aGeneration) = 0; |
michael@0 | 305 | /** |
michael@0 | 306 | * Determine whether it is desirable to be able to asynchronously scroll this |
michael@0 | 307 | * scroll frame. |
michael@0 | 308 | */ |
michael@0 | 309 | virtual bool WantAsyncScroll() const = 0; |
michael@0 | 310 | }; |
michael@0 | 311 | |
michael@0 | 312 | #endif |