bool QtViewportInteractionEngine::ensureContentWithinViewportBoundary(bool immediate) { ASSERT(m_suspendCount); if (scrollAnimationActive() || scaleAnimationActive()) return false; qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(currentCSSScale())); const QRectF viewportRect = m_viewport->boundingRect(); QPointF viewportHotspot = viewportRect.center(); QPointF endPosition = m_viewport->mapToWebContent(viewportHotspot) * endItemScale - viewportHotspot; QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale); if (immediate) { setItemRectVisible(endVisibleContentRect); return true; } return !animateItemRectVisible(endVisibleContentRect); }
/* * This is called for all changes of item scale, width or height. * This is called when interacting, ie. during for instance pinch-zooming. * * FIXME: This is currently called twice if you concurrently change width and height. */ void QtViewportInteractionEngine::itemSizeChanged() { if (m_suspendCount) return; setItemRectVisible(nearestValidBounds()); }
void QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect) { ASSERT(m_scaleAnimation->state() == QAbstractAnimation::Stopped); ASSERT(!scrollAnimationActive()); if (scrollAnimationActive()) return; QRectF currentItemRectVisible = m_viewport->mapRectToWebContent(m_viewport->boundingRect()); if (itemRect == currentItemRectVisible) return; // FIXME: Investigate why that animation doesn't run when we are unfocused. if (!m_viewport->isVisible() || !m_viewport->hasFocus()) { // Apply the end result immediately when we are non-visible. setItemRectVisible(itemRect); return; } QEasingCurve easingCurve; easingCurve.setCustomType(physicalOvershoot); m_scaleAnimation->setDuration(kScaleAnimationDurationMillis); m_scaleAnimation->setEasingCurve(easingCurve); m_scaleAnimation->setStartValue(currentItemRectVisible); m_scaleAnimation->setEndValue(itemRect); m_scaleAnimation->start(); }
void QtViewportInteractionEngine::cancelScrollAnimation() { if (!scrollAnimationActive()) return; // If the pan gesture recognizer receives a touch begin event // during an ongoing kinetic scroll animation of a previous // pan gesture, the animation is stopped and the content is // immediately positioned back to valid boundaries. m_viewport->cancelFlick(); setItemRectVisible(nearestValidBounds()); }
void QtViewportInteractionEngine::pagePositionRequest(const QPoint& pagePosition) { // Ignore the request if suspended. Can only happen due to delay in event delivery. if (m_suspendCount) return; qreal endItemScale = m_content->contentsScale(); // Stay at same scale. QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); QPointF endPosition = boundPosition(endPosRange.topLeft(), pagePosition * endItemScale, endPosRange.bottomRight()); QRectF endVisibleContentRect(endPosition / endItemScale, m_viewport->boundingRect().size() / endItemScale); setItemRectVisible(endVisibleContentRect); }
bool QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect) { QRectF currentItemRectVisible = m_viewport->mapRectToWebContent(m_viewport->boundingRect()); if (itemRect == currentItemRectVisible) return false; // FIXME: Investigate why that animation doesn't run when we are unfocused. if (!m_viewport->isVisible() || !m_viewport->hasFocus()) { // Apply the end result immediately when we are non-visible. setItemRectVisible(itemRect); return true; } m_scaleAnimation->setDuration(kScaleAnimationDurationMillis); m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic); m_scaleAnimation->setStartValue(currentItemRectVisible); m_scaleAnimation->setEndValue(itemRect); m_scaleAnimation->start(); return true; }