| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/frame/RootFrameViewport.h" | 5 #include "core/frame/RootFrameViewport.h" |
| 6 | 6 |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/layout/ScrollAlignment.h" | 8 #include "core/layout/ScrollAlignment.h" |
| 9 #include "platform/geometry/DoubleRect.h" | 9 #include "platform/geometry/DoubleRect.h" |
| 10 #include "platform/geometry/FloatRect.h" | 10 #include "platform/geometry/FloatRect.h" |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 GraphicsLayer* RootFrameViewport::layerForHorizontalScrollbar() const | 225 GraphicsLayer* RootFrameViewport::layerForHorizontalScrollbar() const |
| 226 { | 226 { |
| 227 return layoutViewport().layerForHorizontalScrollbar(); | 227 return layoutViewport().layerForHorizontalScrollbar(); |
| 228 } | 228 } |
| 229 | 229 |
| 230 GraphicsLayer* RootFrameViewport::layerForVerticalScrollbar() const | 230 GraphicsLayer* RootFrameViewport::layerForVerticalScrollbar() const |
| 231 { | 231 { |
| 232 return layoutViewport().layerForVerticalScrollbar(); | 232 return layoutViewport().layerForVerticalScrollbar(); |
| 233 } | 233 } |
| 234 | 234 |
| 235 ScrollResultOneDimensional RootFrameViewport::userScroll(ScrollDirectionPhysical
direction, ScrollGranularity granularity, float delta) | 235 ScrollResult RootFrameViewport::userScroll(ScrollGranularity granularity, const
FloatSize& delta) |
| 236 { | 236 { |
| 237 // TODO(bokan/ymalik): Once smooth scrolling is permanently enabled we |
| 238 // should be able to remove this method override and use the base class |
| 239 // version: ScrollableArea::userScroll. |
| 240 |
| 237 updateScrollAnimator(); | 241 updateScrollAnimator(); |
| 238 | 242 |
| 239 ScrollbarOrientation orientation = scrollbarOrientationFromDirection(directi
on); | 243 // Distribute the scroll between the visual and layout viewport. |
| 240 | 244 |
| 241 if (layoutViewport().userInputScrollable(orientation) && visualViewport().us
erInputScrollable(orientation)) { | 245 float stepX = scrollStep(granularity, HorizontalScrollbar); |
| 242 // Distribute the scroll between the visual and layout viewport. | 246 float stepY = scrollStep(granularity, VerticalScrollbar); |
| 243 float step = scrollStep(granularity, orientation); | |
| 244 | 247 |
| 245 if (direction == ScrollUp || direction == ScrollLeft) | 248 FloatSize pixelDelta(delta); |
| 246 delta = -delta; | 249 pixelDelta.scale(stepX, stepY); |
| 247 | 250 |
| 248 // This is the total amount we need to scroll. Instead of passing step | 251 // Precompute the amount of possible scrolling since, when animated, |
| 249 // to the scroll animator and letting it compute the total delta, we | 252 // ScrollAnimator::userScroll will report having consumed the total given |
| 250 // give it the delta it should scroll. This way we can apply the | 253 // scroll delta, regardless of how much will actually scroll, but we need to |
| 251 // unused delta from the visual viewport to the layout viewport. | 254 // know how much to leave for the layout viewport. |
| 252 delta *= step; | 255 FloatSize visualConsumedDelta = |
| 256 visualViewport().scrollAnimator().computeDeltaToConsume(pixelDelta); |
| 253 | 257 |
| 254 cancelProgrammaticScrollAnimation(); | 258 // Split the remaining delta between scrollable and unscrollable axes of the |
| 259 // layout viewport. We only pass a delta to the scrollable axes and remember |
| 260 // how much was held back so we can add it to the unused delta in the |
| 261 // result. |
| 262 FloatSize layoutDelta = pixelDelta - visualConsumedDelta; |
| 263 FloatSize scrollableAxisDelta( |
| 264 layoutViewport().userInputScrollable(HorizontalScrollbar) |
| 265 ? layoutDelta.width() |
| 266 : 0, |
| 267 layoutViewport().userInputScrollable(VerticalScrollbar) |
| 268 ? layoutDelta.height() |
| 269 : 0); |
| 255 | 270 |
| 256 float visualUsedDelta = visualViewport().scrollAnimator().computeDeltaTo
Consume(orientation, delta); | 271 // If there won't be any scrolling, bail early so we don't produce any side |
| 257 ScrollResultOneDimensional visualResult = visualViewport().scrollAnimato
r().userScroll( | 272 // effects like cancelling existing animations. |
| 258 orientation, granularity, visualUsedDelta); | 273 if (visualConsumedDelta.isZero() && scrollableAxisDelta.isZero()) { |
| 259 | 274 return ScrollResult( |
| 260 // Scroll the layout viewport if all of the scroll was not applied to th
e | 275 false, |
| 261 // visual viewport. | 276 false, |
| 262 if (visualUsedDelta == delta) | 277 pixelDelta.width(), |
| 263 return visualResult; | 278 pixelDelta.height()); |
| 264 | |
| 265 ScrollResultOneDimensional layoutResult = layoutViewport().scrollAnimato
r().userScroll( | |
| 266 orientation, granularity, delta - visualUsedDelta); | |
| 267 | |
| 268 return ScrollResultOneDimensional(visualResult.didScroll || layoutResult
.didScroll, | |
| 269 layoutResult.unusedScrollDelta); | |
| 270 } | 279 } |
| 271 | 280 |
| 272 if (visualViewport().userInputScrollable(orientation)) | 281 cancelProgrammaticScrollAnimation(); |
| 273 return visualViewport().userScroll(direction, granularity, delta); | |
| 274 | 282 |
| 275 if (layoutViewport().userInputScrollable(orientation)) | 283 // TODO(bokan): Why do we call userScroll on the animators directly and |
| 276 return layoutViewport().userScroll(direction, granularity, delta); | 284 // not through the ScrollableAreas? |
| 285 ScrollResult visualResult = visualViewport().scrollAnimator().userScroll( |
| 286 granularity, |
| 287 visualConsumedDelta); |
| 277 | 288 |
| 278 return ScrollResultOneDimensional(false, delta); | 289 if (visualConsumedDelta == pixelDelta) |
| 290 return visualResult; |
| 291 |
| 292 ScrollResult layoutResult = layoutViewport().scrollAnimator().userScroll( |
| 293 granularity, |
| 294 scrollableAxisDelta); |
| 295 |
| 296 // Remember to add any delta not used because of !userInputScrollable to the |
| 297 // unusedScrollDelta in the result. |
| 298 FloatSize unscrollableAxisDelta = layoutDelta - scrollableAxisDelta; |
| 299 |
| 300 return ScrollResult( |
| 301 visualResult.didScrollX || layoutResult.didScrollX, |
| 302 visualResult.didScrollY || layoutResult.didScrollY, |
| 303 layoutResult.unusedScrollDeltaX + unscrollableAxisDelta.width(), |
| 304 layoutResult.unusedScrollDeltaY + unscrollableAxisDelta.height()); |
| 279 } | 305 } |
| 280 | 306 |
| 281 bool RootFrameViewport::scrollAnimatorEnabled() const | 307 bool RootFrameViewport::scrollAnimatorEnabled() const |
| 282 { | 308 { |
| 283 return layoutViewport().scrollAnimatorEnabled(); | 309 return layoutViewport().scrollAnimatorEnabled(); |
| 284 } | 310 } |
| 285 | 311 |
| 286 HostWindow* RootFrameViewport::hostWindow() const | 312 HostWindow* RootFrameViewport::hostWindow() const |
| 287 { | 313 { |
| 288 return layoutViewport().hostWindow(); | 314 return layoutViewport().hostWindow(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 315 } | 341 } |
| 316 | 342 |
| 317 DEFINE_TRACE(RootFrameViewport) | 343 DEFINE_TRACE(RootFrameViewport) |
| 318 { | 344 { |
| 319 visitor->trace(m_visualViewport); | 345 visitor->trace(m_visualViewport); |
| 320 visitor->trace(m_layoutViewport); | 346 visitor->trace(m_layoutViewport); |
| 321 ScrollableArea::trace(visitor); | 347 ScrollableArea::trace(visitor); |
| 322 } | 348 } |
| 323 | 349 |
| 324 } // namespace blink | 350 } // namespace blink |
| OLD | NEW |