[BlackBerry] Animate changes to viewport due to input focus changes.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Nov 2012 19:55:12 +0000 (19:55 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Nov 2012 19:55:12 +0000 (19:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102410

Patch by Andrew Lo <anlo@rim.com> on 2012-11-15
Reviewed by Rob Buis.

When changing scroll position or zoom level for input field focus,
animate the change.
Internal PR 231937

Internally reviewed by Mike Fenton.

* WebKitSupport/InputHandler.cpp:
(BlackBerry::WebKit::InputHandler::ensureFocusTextElementVisible):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@134807 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/blackberry/ChangeLog
Source/WebKit/blackberry/WebKitSupport/InputHandler.cpp

index 620cc49..7f74451 100644 (file)
@@ -1,3 +1,19 @@
+2012-11-15  Andrew Lo  <anlo@rim.com>
+
+        [BlackBerry] Animate changes to viewport due to input focus changes.
+        https://bugs.webkit.org/show_bug.cgi?id=102410
+
+        Reviewed by Rob Buis.
+
+        When changing scroll position or zoom level for input field focus,
+        animate the change.
+        Internal PR 231937
+
+        Internally reviewed by Mike Fenton.
+
+        * WebKitSupport/InputHandler.cpp:
+        (BlackBerry::WebKit::InputHandler::ensureFocusTextElementVisible):
+
 2012-11-15  Mike Fenton  <mifenton@rim.com>
 
         [BlackBerry] Don't restore zoom and scroll when leaving an input field.
index eb550e9..55533e4 100644 (file)
@@ -1126,11 +1126,17 @@ void InputHandler::ensureFocusTextElementVisible(CaretScrollType scrollType)
     // The minimum size being defined as 3 mm is a good value based on my observations.
     static const int s_minimumTextHeightInPixels = Graphics::Screen::primaryScreen()->heightInMMToPixels(3);
 
-    if (m_webPage->isUserScalable() && fontHeight && fontHeight * m_webPage->currentScale() < s_minimumTextHeightInPixels && !isRunningDrt()) {
-        double zoomScaleRequired = static_cast<double>(s_minimumTextHeightInPixels) / fontHeight;
-        m_webPage->zoomAboutPoint(zoomScaleRequired, selectionFocusRect.location());
-        InputLog(LogLevelInfo, "InputHandler::ensureFocusTextElementVisible zooming in to %f at point %d, %d", zoomScaleRequired, selectionFocusRect.location().x(), selectionFocusRect.location().y());
-    }
+    double zoomScaleRequired;
+    if (m_webPage->isUserScalable() && fontHeight && fontHeight * m_webPage->currentScale() < s_minimumTextHeightInPixels && !isRunningDrt())
+        zoomScaleRequired = static_cast<double>(s_minimumTextHeightInPixels) / fontHeight;
+    else
+        zoomScaleRequired = m_webPage->currentScale(); // Don't scale.
+
+    // The scroll location we should go to given the zoom required, could be adjusted later.
+    WebCore::FloatPoint offset(selectionFocusRect.location().y() - m_webPage->scrollPosition().x(), selectionFocusRect.location().y() - m_webPage->scrollPosition().y());
+    double inverseScale = zoomScaleRequired / m_webPage->currentScale();
+    WebCore::IntPoint destinationScrollLocation = WebCore::IntPoint(max(0, static_cast<int>(roundf(selectionFocusRect.location().x() - offset.x() / inverseScale))),
+                                                                    max(0, static_cast<int>(roundf(selectionFocusRect.location().y() - offset.y() / inverseScale))));
 
     if (elementFrame != mainFrame) { // Element is in a subframe.
         // Remove any scroll offset within the subframe to get the point relative to the main frame.
@@ -1146,7 +1152,9 @@ void InputHandler::ensureFocusTextElementVisible(CaretScrollType scrollType)
     Position start = elementFrame->selection()->start();
     if (start.anchorNode() && start.anchorNode()->renderer()) {
         if (RenderLayer* layer = start.anchorNode()->renderer()->enclosingLayer()) {
-            WebCore::IntRect actualScreenRect = WebCore::IntRect(mainFrameView->scrollPosition(), m_webPage->actualVisibleSize());
+            // Screen rect after the required zoom.
+            WebCore::IntRect actualScreenRect = WebCore::IntRect(destinationScrollLocation.x(), destinationScrollLocation.y(), m_webPage->actualVisibleSize().width() / inverseScale, m_webPage->actualVisibleSize().height() / inverseScale);
+
             ScrollAlignment horizontalScrollAlignment = ScrollAlignment::alignToEdgeIfNeeded;
             ScrollAlignment verticalScrollAlignment = ScrollAlignment::alignToEdgeIfNeeded;
 
@@ -1193,17 +1201,26 @@ void InputHandler::ensureFocusTextElementVisible(CaretScrollType scrollType)
             // In order to adjust the scroll position to ensure the focused input field is visible,
             // we allow overscrolling. However this overscroll has to be strictly allowed towards the
             // bottom of the page on the y axis only, where the virtual keyboard pops up from.
-            WebCore::IntPoint scrollLocation = revealRect.location();
-            scrollLocation.clampNegativeToZero();
+            destinationScrollLocation = revealRect.location();
+            destinationScrollLocation.clampNegativeToZero();
             WebCore::IntPoint maximumScrollPosition = WebCore::IntPoint(mainFrameView->contentsWidth() - actualScreenRect.width(), mainFrameView->contentsHeight() - actualScreenRect.height());
-            scrollLocation = scrollLocation.shrunkTo(maximumScrollPosition);
-            if (scrollLocation != mainFrameView->scrollPosition()) {
-                mainFrameView->setScrollPosition(scrollLocation);
-                mainFrameView->setConstrainsScrollingToContentEdge(true);
-                InputLog(LogLevelInfo, "InputHandler::ensureFocusTextElementVisible scrolling to point %d, %d", scrollLocation.x(), scrollLocation.y());
-            }
+            destinationScrollLocation = destinationScrollLocation.shrunkTo(maximumScrollPosition);
         }
     }
+
+    if (destinationScrollLocation != mainFrameView->scrollPosition() || zoomScaleRequired != m_webPage->currentScale()) {
+        mainFrameView->setConstrainsScrollingToContentEdge(true);
+
+        InputLog(LogLevelInfo, "InputHandler::ensureFocusTextElementVisible zooming in to %f and scrolling to point %d, %d", zoomScaleRequired, destinationScrollLocation.x(), destinationScrollLocation.y());
+
+        // Animate to given scroll position & zoom level
+        m_webPage->m_finalBlockPoint = WebCore::FloatPoint(destinationScrollLocation);
+        m_webPage->m_blockZoomFinalScale = zoomScaleRequired;
+        m_webPage->m_shouldReflowBlock = false;
+        m_webPage->m_userPerformedManualZoom = true;
+        m_webPage->m_userPerformedManualScroll = true;
+        m_webPage->client()->animateBlockZoom(zoomScaleRequired, m_webPage->m_finalBlockPoint);
+    }
     m_webPage->resumeBackingStore();
 }