示例#1
0
void RootFrameViewport::setScrollOffset(const ScrollOffset& offset,
                                        ScrollType scrollType,
                                        ScrollBehavior scrollBehavior) {
  updateScrollAnimator();

  if (scrollBehavior == ScrollBehaviorAuto)
    scrollBehavior = scrollBehaviorStyle();

  if (scrollType == ProgrammaticScroll &&
      !layoutViewport().isProgrammaticallyScrollable())
    return;

  if (scrollType == AnchoringScroll) {
    distributeScrollBetweenViewports(offset, scrollType, scrollBehavior,
                                     LayoutViewport);
    return;
  }

  if (scrollBehavior == ScrollBehaviorSmooth) {
    distributeScrollBetweenViewports(offset, scrollType, scrollBehavior,
                                     VisualViewport);
    return;
  }

  ScrollOffset clampedOffset = clampScrollOffset(offset);
  ScrollableArea::setScrollOffset(clampedOffset, scrollType, scrollBehavior);
}
void RootFrameViewport::setScrollPosition(const DoublePoint& position, ScrollType scrollType, ScrollBehavior scrollBehavior)
{
    updateScrollAnimator();

    // TODO(bokan): Support smooth scrolling the visual viewport.
    if (scrollBehavior == ScrollBehaviorAuto)
        scrollBehavior = scrollBehaviorStyle();
    if (scrollBehavior == ScrollBehaviorSmooth) {
        layoutViewport().setScrollPosition(position, scrollType, scrollBehavior);
        return;
    }

    if (scrollType == ProgrammaticScroll && !layoutViewport().isProgrammaticallyScrollable())
        return;

    DoublePoint clampedPosition = clampScrollPosition(position);
    ScrollableArea::setScrollPosition(clampedPosition, scrollType, scrollBehavior);
}
void RootFrameViewport::setScrollPosition(const DoublePoint& position, ScrollType scrollType, ScrollBehavior scrollBehavior)
{
    updateScrollAnimator();

    if (scrollBehavior == ScrollBehaviorAuto)
        scrollBehavior = scrollBehaviorStyle();

    if (scrollType == ProgrammaticScroll && !layoutViewport().isProgrammaticallyScrollable())
        return;

    if (scrollBehavior == ScrollBehaviorSmooth) {
        distributeScrollBetweenViewports(position, scrollType, scrollBehavior);
        return;
    }

    DoublePoint clampedPosition = clampScrollPosition(position);
    ScrollableArea::setScrollPosition(clampedPosition, scrollType, scrollBehavior);
}
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());
}
ScrollResultOneDimensional RootFrameViewport::userScroll(ScrollDirectionPhysical direction, ScrollGranularity granularity, float delta)
{
    updateScrollAnimator();

    ScrollbarOrientation orientation;

    if (direction == ScrollUp || direction == ScrollDown)
        orientation = VerticalScrollbar;
    else
        orientation = HorizontalScrollbar;

    if (layoutViewport().userInputScrollable(orientation) && visualViewport().userInputScrollable(orientation))
        return ScrollableArea::userScroll(direction, granularity, delta);

    if (visualViewport().userInputScrollable(orientation))
        return visualViewport().userScroll(direction, granularity, delta);

    if (layoutViewport().userInputScrollable(orientation))
        return layoutViewport().userScroll(direction, granularity, delta);

    return ScrollResultOneDimensional(false, delta);
}
示例#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());
}