ScrollResultOneDimensional ScrollableArea::userScroll(ScrollDirectionPhysical direction, ScrollGranularity granularity, float delta) { ScrollbarOrientation orientation; if (direction == ScrollUp || direction == ScrollDown) orientation = VerticalScrollbar; else orientation = HorizontalScrollbar; if (!userInputScrollable(orientation)) return ScrollResultOneDimensional(false, delta); cancelProgrammaticScrollAnimation(); float step = 0; switch (granularity) { case ScrollByLine: step = lineStep(orientation); break; case ScrollByPage: step = pageStep(orientation); break; case ScrollByDocument: step = documentStep(orientation); break; case ScrollByPixel: case ScrollByPrecisePixel: step = pixelStep(orientation); break; } if (direction == ScrollUp || direction == ScrollLeft) delta = -delta; return scrollAnimator()->userScroll(orientation, granularity, step, delta); }
bool ScrollableArea::handleWheelEvent(const PlatformWheelEvent& wheelEvent) { // ctrl+wheel events are used to trigger zooming, not scrolling. if (wheelEvent.modifiers() & PlatformEvent::CtrlKey) return false; cancelProgrammaticScrollAnimation(); return scrollAnimator()->handleWheelEvent(wheelEvent); }
ScrollResult ScrollableArea::handleWheel(const PlatformWheelEvent& wheelEvent) { // Wheel events which do not scroll are used to trigger zooming. if (!wheelEvent.canScroll()) return ScrollResult(); cancelProgrammaticScrollAnimation(); return scrollAnimator()->handleWheelEvent(wheelEvent); }
void ScrollableArea::userScrollHelper(const DoublePoint& position, ScrollBehavior scrollBehavior) { cancelProgrammaticScrollAnimation(); // Smooth user scrolls (keyboard, wheel clicks) are handled via the userScroll method. // TODO(bokan): The userScroll method should probably be modified to call this method // and ScrollAnimator to have a simpler animateToOffset method like the // ProgrammaticScrollAnimator. ASSERT(scrollBehavior == ScrollBehaviorInstant); scrollAnimator()->scrollToOffsetWithoutAnimation(toFloatPoint(position)); }
void ScrollableArea::scrollToOffsetWithoutAnimation(const FloatPoint& offset) { cancelProgrammaticScrollAnimation(); scrollAnimator()->scrollToOffsetWithoutAnimation(offset); }
ScrollResult RootFrameViewport::userScroll(ScrollGranularity granularity, const FloatSize& delta) { // TODO(bokan/ymalik): Once smooth scrolling is permanently enabled we // should be able to remove this method override and use the base class // version: ScrollableArea::userScroll. updateScrollAnimator(); // Distribute the scroll between the visual and layout viewport. float stepX = scrollStep(granularity, HorizontalScrollbar); float stepY = scrollStep(granularity, VerticalScrollbar); FloatSize pixelDelta(delta); pixelDelta.scale(stepX, stepY); // Precompute the amount of possible scrolling since, when animated, // ScrollAnimator::userScroll will report having consumed the total given // scroll delta, regardless of how much will actually scroll, but we need to // know how much to leave for the layout viewport. FloatSize visualConsumedDelta = visualViewport().scrollAnimator().computeDeltaToConsume(pixelDelta); // Split the remaining delta between scrollable and unscrollable axes of the // layout viewport. We only pass a delta to the scrollable axes and remember // how much was held back so we can add it to the unused delta in the // result. FloatSize layoutDelta = pixelDelta - visualConsumedDelta; FloatSize scrollableAxisDelta( layoutViewport().userInputScrollable(HorizontalScrollbar) ? layoutDelta.width() : 0, layoutViewport().userInputScrollable(VerticalScrollbar) ? layoutDelta.height() : 0); // If there won't be any scrolling, bail early so we don't produce any side // effects like cancelling existing animations. if (visualConsumedDelta.isZero() && scrollableAxisDelta.isZero()) { return ScrollResult(false, false, pixelDelta.width(), pixelDelta.height()); } cancelProgrammaticScrollAnimation(); // TODO(bokan): Why do we call userScroll on the animators directly and // not through the ScrollableAreas? ScrollResult visualResult = visualViewport().scrollAnimator().userScroll( granularity, visualConsumedDelta); if (visualConsumedDelta == pixelDelta) return visualResult; ScrollResult layoutResult = layoutViewport().scrollAnimator().userScroll( granularity, scrollableAxisDelta); // Remember to add any delta not used because of !userInputScrollable to the // unusedScrollDelta in the result. FloatSize unscrollableAxisDelta = layoutDelta - scrollableAxisDelta; return ScrollResult( visualResult.didScrollX || layoutResult.didScrollX, visualResult.didScrollY || layoutResult.didScrollY, layoutResult.unusedScrollDeltaX + unscrollableAxisDelta.width(), layoutResult.unusedScrollDeltaY + unscrollableAxisDelta.height()); }