Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2383)

Unified Diff: Source/web/WebViewImpl.cpp

Issue 19281007: Allow zoom-in to a target rect when tapping multiple targets. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/web/WebViewImpl.h ('k') | Source/web/tests/WebFrameTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/web/WebViewImpl.cpp
diff --git a/Source/web/WebViewImpl.cpp b/Source/web/WebViewImpl.cpp
index 63acb394798b362fc0514ee09f7d47747ad05755..7fbcfc2b4074522e1913fa69c4acca3ee164b521 100644
--- a/Source/web/WebViewImpl.cpp
+++ b/Source/web/WebViewImpl.cpp
@@ -191,6 +191,9 @@ static const float doubleTapZoomContentMinimumMargin = 2;
static const double doubleTapZoomAnimationDurationInSeconds = 0.25;
static const float doubleTapZoomAlreadyLegibleRatio = 1.2f;
+static const double multipleTargetsZoomAnimationDurationInSeconds = 0.25;
+static const double findInPageAnimationDurationInSeconds = 0;
+
// Constants for viewport anchoring on resize.
static const float viewportAnchorXCoord = 0.5f;
static const float viewportAnchorYCoord = 0;
@@ -384,9 +387,9 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
, m_exitFullscreenPageScaleFactor(0)
, m_doubleTapZoomPageScaleFactor(0)
, m_doubleTapZoomPending(false)
- , m_enableFakeDoubleTapAnimationForTesting(false)
- , m_fakeDoubleTapPageScaleFactor(0)
- , m_fakeDoubleTapUseAnchor(false)
+ , m_enableFakePageScaleAnimationForTesting(false)
+ , m_fakePageScaleAnimationPageScaleFactor(0)
+ , m_fakePageScaleAnimationUseAnchor(false)
, m_contextMenuAllowed(false)
, m_doingDragAndDrop(false)
, m_ignoreInputEvents(false)
@@ -771,7 +774,7 @@ bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event)
case WebInputEvent::GestureDoubleTap:
if (m_webSettings->doubleTapToZoomEnabled() && minimumPageScaleFactor() != maximumPageScaleFactor()) {
m_client->cancelScheduledContentIntents();
- animateZoomAroundPoint(platformEvent.position(), DoubleTap);
+ animateDoubleTapZoom(platformEvent.position());
}
// GestureDoubleTap is currently only used by Android for zooming. For WebCore,
// GestureTap with tap count = 2 is used instead. So we drop GestureDoubleTap here.
@@ -822,10 +825,10 @@ bool WebViewImpl::startPageScaleAnimation(const IntPoint& targetPosition, bool u
if (useAnchor && newScale == pageScaleFactor())
return false;
- if (m_enableFakeDoubleTapAnimationForTesting) {
- m_fakeDoubleTapTargetPosition = targetPosition;
- m_fakeDoubleTapUseAnchor = useAnchor;
- m_fakeDoubleTapPageScaleFactor = newScale;
+ if (m_enableFakePageScaleAnimationForTesting) {
+ m_fakePageScaleAnimationTargetPosition = targetPosition;
+ m_fakePageScaleAnimationUseAnchor = useAnchor;
+ m_fakePageScaleAnimationPageScaleFactor = newScale;
} else {
if (!m_layerTreeView)
return false;
@@ -834,9 +837,9 @@ bool WebViewImpl::startPageScaleAnimation(const IntPoint& targetPosition, bool u
return true;
}
-void WebViewImpl::enableFakeDoubleTapAnimationForTesting(bool enable)
+void WebViewImpl::enableFakePageScaleAnimationForTesting(bool enable)
{
- m_enableFakeDoubleTapAnimationForTesting = enable;
+ m_enableFakePageScaleAnimationForTesting = enable;
}
WebViewBenchmarkSupport* WebViewImpl::benchmarkSupport()
@@ -1062,15 +1065,14 @@ bool WebViewImpl::handleCharEvent(const WebKeyboardEvent& event)
return true;
}
-WebRect WebViewImpl::computeBlockBounds(const WebRect& rect, AutoZoomType zoomType)
+WebRect WebViewImpl::computeBlockBounds(const WebRect& rect, bool ignoreClipping)
{
if (!mainFrameImpl())
return WebRect();
// Use the rect-based hit test to find the node.
IntPoint point = mainFrameImpl()->frameView()->windowToContents(IntPoint(rect.x, rect.y));
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent
- | ((zoomType == FindInPage) ? HitTestRequest::IgnoreClipping : 0);
+ HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent | (ignoreClipping ? HitTestRequest::IgnoreClipping : 0);
HitTestResult result = mainFrameImpl()->frame()->eventHandler()->hitTestResultAtPoint(point, hitType, IntSize(rect.width, rect.height));
Node* node = result.innerNonSharedNode();
@@ -1122,21 +1124,12 @@ WebRect WebViewImpl::widenRectWithinPageBounds(const WebRect& source, int target
return WebRect(newX, source.y, newWidth, source.height);
}
-void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZoomType zoomType, float& scale, WebPoint& scroll, bool& isAnchor)
+void WebViewImpl::computeScaleAndScrollForBlockRect(const WebRect& blockRect, float padding, float& scale, WebPoint& scroll, bool& doubleTapShouldZoomOut)
{
scale = pageScaleFactor();
scroll.x = scroll.y = 0;
- WebRect targetRect = hitRect;
- // Padding only depends on page scale when triggered by manually tapping
- int padding = (zoomType == DoubleTap) ? touchPointPadding : nonUserInitiatedPointPadding;
- if (targetRect.isEmpty())
- targetRect.width = targetRect.height = padding;
- WebRect rect = computeBlockBounds(targetRect, zoomType);
- if (zoomType == FindInPage && rect.isEmpty()) {
- // Keep current scale (no need to scroll as x,y will normally already
- // be visible). FIXME: Revisit this if it isn't always true.
- return;
- }
+
+ WebRect rect = blockRect;
bool scaleUnchanged = true;
if (!rect.isEmpty()) {
@@ -1173,46 +1166,40 @@ void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZo
bool stillAtPreviousDoubleTapScale = (pageScaleFactor() == m_doubleTapZoomPageScaleFactor
&& m_doubleTapZoomPageScaleFactor != minimumPageScaleFactor())
|| m_doubleTapZoomPending;
- if (zoomType == DoubleTap && (rect.isEmpty() || scaleUnchanged || stillAtPreviousDoubleTapScale)) {
- // Zoom out to minimum scale.
- scale = minimumPageScaleFactor();
- scroll = WebPoint(hitRect.x, hitRect.y);
- isAnchor = true;
+
+ doubleTapShouldZoomOut = rect.isEmpty() || scaleUnchanged || stillAtPreviousDoubleTapScale;
+
+ // FIXME: If this is being called for auto zoom during find in page,
+ // then if the user manually zooms in it'd be nice to preserve the
+ // relative increase in zoom they caused (if they zoom out then it's ok
+ // to zoom them back in again). This isn't compatible with our current
+ // double-tap zoom strategy (fitting the containing block to the screen)
+ // though.
+
+ float screenWidth = m_size.width / scale;
+ float screenHeight = m_size.height / scale;
+
+ // Scroll to vertically align the block.
+ if (rect.height < screenHeight) {
+ // Vertically center short blocks.
+ rect.y -= 0.5 * (screenHeight - rect.height);
} else {
- // FIXME: If this is being called for auto zoom during find in page,
- // then if the user manually zooms in it'd be nice to preserve the
- // relative increase in zoom they caused (if they zoom out then it's ok
- // to zoom them back in again). This isn't compatible with our current
- // double-tap zoom strategy (fitting the containing block to the screen)
- // though.
-
- float screenWidth = m_size.width / scale;
- float screenHeight = m_size.height / scale;
-
- // Scroll to vertically align the block.
- if (rect.height < screenHeight) {
- // Vertically center short blocks.
- rect.y -= 0.5 * (screenHeight - rect.height);
- } else {
- // Ensure position we're zooming to (+ padding) isn't off the bottom of
- // the screen.
- rect.y = max<float>(rect.y, hitRect.y + padding - screenHeight);
- } // Otherwise top align the block.
-
- // Do the same thing for horizontal alignment.
- if (rect.width < screenWidth)
- rect.x -= 0.5 * (screenWidth - rect.width);
- else
- rect.x = max<float>(rect.x, hitRect.x + padding - screenWidth);
- scroll.x = rect.x;
- scroll.y = rect.y;
- isAnchor = false;
- }
+ // Ensure position we're zooming to (+ padding) isn't off the bottom of
+ // the screen.
+ rect.y = max<float>(rect.y, blockRect.y + padding - screenHeight);
+ } // Otherwise top align the block.
+
+ // Do the same thing for horizontal alignment.
+ if (rect.width < screenWidth)
+ rect.x -= 0.5 * (screenWidth - rect.width);
+ else
+ rect.x = max<float>(rect.x, blockRect.x + padding - screenWidth);
+ scroll.x = rect.x;
+ scroll.y = rect.y;
scale = clampPageScaleFactorToLimits(scale);
scroll = mainFrameImpl()->frameView()->windowToContents(scroll);
- if (!isAnchor)
- scroll = clampOffsetAtScale(scroll, scale);
+ scroll = clampOffsetAtScale(scroll, scale);
}
static bool invokesHandCursor(Node* node, bool shiftKey, Frame* frame)
@@ -1271,22 +1258,29 @@ void WebViewImpl::enableTapHighlight(const PlatformGestureEvent& tapEvent)
m_linkHighlight = LinkHighlight::create(touchNode, this);
}
-void WebViewImpl::animateZoomAroundPoint(const IntPoint& point, AutoZoomType zoomType)
+void WebViewImpl::animateDoubleTapZoom(const IntPoint& point)
{
if (!mainFrameImpl())
return;
+ WebRect rect(point.x(), point.y(), touchPointPadding, touchPointPadding);
+ WebRect blockBounds = computeBlockBounds(rect, false);
+
float scale;
WebPoint scroll;
- bool isAnchor;
- WebPoint webPoint = point;
- computeScaleAndScrollForHitRect(WebRect(webPoint.x, webPoint.y, 0, 0), zoomType, scale, scroll, isAnchor);
+ bool doubleTapShouldZoomOut;
- bool isDoubleTap = (zoomType == DoubleTap);
- double durationInSeconds = isDoubleTap ? doubleTapZoomAnimationDurationInSeconds : 0;
- bool isAnimating = startPageScaleAnimation(scroll, isAnchor, scale, durationInSeconds);
+ computeScaleAndScrollForBlockRect(blockBounds, touchPointPadding, scale, scroll, doubleTapShouldZoomOut);
- if (isDoubleTap && isAnimating) {
+ bool isAnimating;
+
+ if (doubleTapShouldZoomOut) {
+ isAnimating = startPageScaleAnimation(mainFrameImpl()->frameView()->windowToContents(point), true, minimumPageScaleFactor(), doubleTapZoomAnimationDurationInSeconds);
+ } else {
+ isAnimating = startPageScaleAnimation(scroll, false, scale, doubleTapZoomAnimationDurationInSeconds);
+ }
+
+ if (isAnimating) {
m_doubleTapZoomPageScaleFactor = scale;
m_doubleTapZoomPending = true;
}
@@ -1294,7 +1288,42 @@ void WebViewImpl::animateZoomAroundPoint(const IntPoint& point, AutoZoomType zoo
void WebViewImpl::zoomToFindInPageRect(const WebRect& rect)
{
- animateZoomAroundPoint(IntRect(rect).center(), FindInPage);
+ if (!mainFrameImpl())
+ return;
+
+ WebRect blockBounds = computeBlockBounds(rect, true);
+
+ if (blockBounds.isEmpty()) {
+ // Keep current scale (no need to scroll as x,y will normally already
+ // be visible). FIXME: Revisit this if it isn't always true.
+ return;
+ }
+
+ float scale;
+ WebPoint scroll;
+ bool doubleTapShouldZoomOut;
+
+ computeScaleAndScrollForBlockRect(blockBounds, nonUserInitiatedPointPadding, scale, scroll, doubleTapShouldZoomOut);
+
+ startPageScaleAnimation(scroll, false, scale, findInPageAnimationDurationInSeconds);
+}
+
+bool WebViewImpl::zoomToMultipleTargetsRect(const WebRect& rect)
+{
+ if (!mainFrameImpl())
+ return false;
+
+ float scale;
+ WebPoint scroll;
+ bool doubleTapShouldZoomOut;
+
+ computeScaleAndScrollForBlockRect(rect, nonUserInitiatedPointPadding, scale, scroll, doubleTapShouldZoomOut);
+
+ if (scale <= pageScaleFactor())
+ return false;
+
+ startPageScaleAnimation(scroll, false, scale, multipleTargetsZoomAnimationDurationInSeconds);
+ return true;
}
void WebViewImpl::numberOfWheelEventHandlersChanged(unsigned numberOfWheelHandlers)
« no previous file with comments | « Source/web/WebViewImpl.h ('k') | Source/web/tests/WebFrameTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698