ScrollResult ScrollAnimatorBase::userScroll(ScrollGranularity,
                                            const ScrollOffset& delta) {
  ScrollOffset consumedDelta = computeDeltaToConsume(delta);
  ScrollOffset newPos = m_currentOffset + consumedDelta;
  if (m_currentOffset == newPos)
    return ScrollResult(false, false, delta.width(), delta.height());

  m_currentOffset = newPos;

  notifyOffsetChanged();

  return ScrollResult(consumedDelta.width(), consumedDelta.height(),
                      delta.width() - consumedDelta.width(),
                      delta.height() - consumedDelta.height());
}
ScrollResult ScrollAnimatorBase::userScroll(ScrollGranularity, const FloatSize& delta)
{
    FloatSize consumedDelta = computeDeltaToConsume(delta);
    FloatPoint newPos = m_currentPos + consumedDelta;
    if (m_currentPos == newPos)
        return ScrollResult(false, false, delta.width(), delta.height());

    m_currentPos = newPos;

    notifyPositionChanged();

    return ScrollResult(
        consumedDelta.width(),
        consumedDelta.height(),
        delta.width() - consumedDelta.width(),
        delta.height() - consumedDelta.height());
}
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);
}
Exemple #4
0
ScrollResult ScrollAnimator::userScroll(ScrollGranularity granularity,
                                        const ScrollOffset& delta) {
  if (!m_scrollableArea->scrollAnimatorEnabled())
    return ScrollAnimatorBase::userScroll(granularity, delta);

  TRACE_EVENT0("blink", "ScrollAnimator::scroll");

  if (granularity == ScrollByPrecisePixel) {
    // Cancel scroll animation because asked to instant scroll.
    if (hasRunningAnimation())
      cancelAnimation();
    return ScrollAnimatorBase::userScroll(granularity, delta);
  }

  bool needsPostAnimationCleanup = m_runState == RunState::PostAnimationCleanup;
  if (m_runState == RunState::PostAnimationCleanup)
    resetAnimationState();

  ScrollOffset consumedDelta = computeDeltaToConsume(delta);
  ScrollOffset targetOffset = desiredTargetOffset();
  targetOffset += consumedDelta;

  if (willAnimateToOffset(targetOffset)) {
    m_lastGranularity = granularity;
    // Report unused delta only if there is no animation running. See
    // comment below regarding scroll latching.
    // TODO(bokan): Need to standardize how ScrollAnimators report
    // unusedDelta. This differs from ScrollAnimatorMac currently.
    return ScrollResult(true, true, 0, 0);
  }

  // If the run state when this method was called was PostAnimationCleanup and
  // we're not starting an animation, stay in PostAnimationCleanup state so
  // that the main thread scrolling reason can be removed.
  if (needsPostAnimationCleanup)
    m_runState = RunState::PostAnimationCleanup;

  // Report unused delta only if there is no animation and we are not
  // starting one. This ensures we latch for the duration of the
  // animation rather than animating multiple scrollers at the same time.
  return ScrollResult(false, false, delta.width(), delta.height());
}
ScrollResult RootFrameViewport::handleWheel(const PlatformWheelEvent& event)
{
    updateScrollAnimator();

    ScrollableArea& primary = !m_invertScrollOrder ? layoutViewport() : visualViewport();
    ScrollableArea& secondary = !m_invertScrollOrder ? visualViewport() : layoutViewport();

    ScrollResult viewScrollResult = primary.handleWheel(event);

    // The visual viewport will only accept pixel scrolls.
    if (!event.canScroll() || event.granularity() == ScrollByPageWheelEvent)
        return viewScrollResult;

    // TODO(sataya.m) : The delta in PlatformWheelEvent is negative when scrolling the
    // wheel towards the user, so negate it to get the scroll delta that should be applied
    // to the page. unusedScrollDelta computed in the ScrollResult is also negative. Say
    // there is WheelEvent({0, -10} and page scroll by 2px and unusedScrollDelta computed
    // is {0, -8}. Due to which we have to negate the unusedScrollDelta to obtain the expected
    // animation.Please address http://crbug.com/504389.
    DoublePoint oldOffset = secondary.scrollPositionDouble();
    DoublePoint locationDelta;
    if (viewScrollResult.didScroll()) {
        locationDelta = -DoublePoint(viewScrollResult.unusedScrollDeltaX, viewScrollResult.unusedScrollDeltaY);
    } else {
        if (event.railsMode() != PlatformEvent::RailsModeVertical)
            locationDelta.setX(-event.deltaX());
        if (event.railsMode() != PlatformEvent::RailsModeHorizontal)
            locationDelta.setY(-event.deltaY());
    }

    DoublePoint targetPosition = secondary.clampScrollPosition(
        secondary.scrollPositionDouble() + toDoubleSize(locationDelta));
    secondary.setScrollPosition(targetPosition, UserScroll);

    DoublePoint usedLocationDelta(secondary.scrollPositionDouble() - oldOffset);

    bool didScrollX = viewScrollResult.didScrollX || usedLocationDelta.x();
    bool didScrollY = viewScrollResult.didScrollY || usedLocationDelta.y();
    return ScrollResult(didScrollX, didScrollY, -viewScrollResult.unusedScrollDeltaX - usedLocationDelta.x(), -viewScrollResult.unusedScrollDeltaY - usedLocationDelta.y());
}
Exemple #6
0
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());
}