void TextureMapperLayer::scrollBy(const FloatSize& offset) { if (!isScrollable() || !m_scrollClient || offset.isZero()) return; FloatSize scrollOffset = mapScrollOffset(offset); m_userScrollOffset += scrollOffset; m_currentTransform.setPosition(adjustedPosition()); commitScrollOffset(scrollOffset); }
bool ViewportScrollCallback::scrollBrowserControls(ScrollState& state) { // Scroll browser controls. if (m_browserControls) { if (state.isBeginning()) m_browserControls->scrollBegin(); FloatSize delta(state.deltaX(), state.deltaY()); ScrollGranularity granularity = ScrollGranularity(static_cast<int>(state.deltaGranularity())); if (shouldScrollBrowserControls(delta, granularity)) { FloatSize remainingDelta = m_browserControls->scrollBy(delta); FloatSize consumed = delta - remainingDelta; state.consumeDeltaNative(consumed.width(), consumed.height()); return !consumed.isZero(); } } return false; }
void Gradient::adjustParametersForTiledDrawing(FloatSize& size, FloatRect& srcRect, const FloatSize& spacing) { if (m_radial) return; if (srcRect.isEmpty()) return; if (!spacing.isZero()) return; if (m_p0.x() == m_p1.x()) { size.setWidth(1); srcRect.setWidth(1); srcRect.setX(0); return; } if (m_p0.y() != m_p1.y()) return; size.setHeight(1); srcRect.setHeight(1); srcRect.setY(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()); }
void AutoscrollController::animate(double) { if (!m_autoscrollLayoutObject || !m_autoscrollLayoutObject->frame()) { stopAutoscroll(); return; } EventHandler& eventHandler = m_autoscrollLayoutObject->frame()->eventHandler(); IntSize offset = m_autoscrollLayoutObject->calculateAutoscrollDirection( eventHandler.lastKnownMousePosition()); IntPoint selectionPoint = eventHandler.lastKnownMousePosition() + offset; switch (m_autoscrollType) { case AutoscrollForDragAndDrop: if (WTF::monotonicallyIncreasingTime() - m_dragAndDropAutoscrollStartTime > autoscrollDelay) m_autoscrollLayoutObject->autoscroll( m_dragAndDropAutoscrollReferencePosition); break; case AutoscrollForSelection: if (!eventHandler.mousePressed()) { stopAutoscroll(); return; } eventHandler.updateSelectionForMouseDrag(); m_autoscrollLayoutObject->autoscroll(selectionPoint); break; case NoAutoscroll: break; case AutoscrollForMiddleClickCanStop: case AutoscrollForMiddleClick: DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); if (!middleClickAutoscrollInProgress()) { stopAutoscroll(); return; } if (FrameView* view = m_autoscrollLayoutObject->frame()->view()) updateMiddleClickAutoscrollState(view, eventHandler.lastKnownMousePosition()); FloatSize delta = calculateAutoscrollDelta(); if (delta.isZero()) break; ScrollResult result = m_autoscrollLayoutObject->scroll(ScrollByPixel, delta); LayoutObject* layoutObject = m_autoscrollLayoutObject; while (!m_didLatchForMiddleClickAutoscroll && !result.didScroll()) { if (layoutObject->node() && layoutObject->node()->isDocumentNode()) { Element* owner = toDocument(layoutObject->node())->localOwner(); layoutObject = owner ? owner->layoutObject() : nullptr; } else { layoutObject = layoutObject->parent(); } if (!layoutObject) { break; } if (layoutObject && layoutObject->isBox() && toLayoutBox(layoutObject)->canBeScrolledAndHasScrollableArea()) result = toLayoutBox(layoutObject)->scroll(ScrollByPixel, delta); } if (result.didScroll()) { m_didLatchForMiddleClickAutoscroll = true; m_autoscrollLayoutObject = toLayoutBox(layoutObject); } break; } if (m_autoscrollType != NoAutoscroll && m_autoscrollLayoutObject) m_page->chromeClient().scheduleAnimation( m_autoscrollLayoutObject->frame()->view()); }