diff options
author | Leon Scroggins <scroggo@google.com> | 2011-01-19 17:01:55 -0500 |
---|---|---|
committer | Leon Scroggins <scroggo@google.com> | 2011-01-21 15:42:03 -0500 |
commit | d5188657dcde0f40a6954a00d569c0575bf6095a (patch) | |
tree | a9212df979cf5b5a8d4ed7d676a15bfc6fc113ca /core/java/android | |
parent | 276677f2ac821e5eb8a7f6a4204242ee47501d6e (diff) | |
download | frameworks_base-d5188657dcde0f40a6954a00d569c0575bf6095a.zip frameworks_base-d5188657dcde0f40a6954a00d569c0575bf6095a.tar.gz frameworks_base-d5188657dcde0f40a6954a00d569c0575bf6095a.tar.bz2 |
Do a better job of lining up text with page text.
Bug:3085564
Bug:3196224
Bug:3321608
Remove Touch.getMaxScrollX(), which is incorrect for my
purpose, and is not used anywhere else. Instead use the
layout to determine the maximum horizontal scroll of a
textfield.
Now that textareas use layers, scroll the layer's picture
in the UI thread for vertical movement. When passing a
click to webcore, also pass a message to scroll the actual
textarea so the click will be in the correct place.
Lastly, do not override bringPointIntoView, which allows
moving the insertion handler beyond the edge of a field to
scroll it. Instead, override requestRectangleOnScreen to
do nothing, since my actual goal is to prevent the TextView
from changing the scroll of the WebView, which is done by
webkit.
Requires a change to external/webkit.
Change-Id: Ib91907599b792287c373d3678cb04e0cb5e34471
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/text/method/Touch.java | 18 | ||||
-rw-r--r-- | core/java/android/webkit/WebTextView.java | 29 | ||||
-rw-r--r-- | core/java/android/webkit/WebView.java | 52 | ||||
-rw-r--r-- | core/java/android/webkit/WebViewCore.java | 7 |
4 files changed, 62 insertions, 44 deletions
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java index 78cbdcf..a528044 100644 --- a/core/java/android/text/method/Touch.java +++ b/core/java/android/text/method/Touch.java @@ -77,24 +77,6 @@ public class Touch { } /** - * @hide - * Returns the maximum scroll value in x. - */ - public static int getMaxScrollX(TextView widget, Layout layout, int y) { - int top = layout.getLineForVertical(y); - int bottom = layout.getLineForVertical(y + widget.getHeight() - - widget.getTotalPaddingTop() -widget.getTotalPaddingBottom()); - int left = Integer.MAX_VALUE; - int right = 0; - for (int i = top; i <= bottom; i++) { - left = (int) Math.min(left, layout.getLineLeft(i)); - right = (int) Math.max(right, layout.getLineRight(i)); - } - return right - left - widget.getWidth() - widget.getTotalPaddingLeft() - - widget.getTotalPaddingRight(); - } - - /** * Handles touch events for dragging. You may want to do other actions * like moving the cursor on touch as well. */ diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java index 72b0023..59a239a 100644 --- a/core/java/android/webkit/WebTextView.java +++ b/core/java/android/webkit/WebTextView.java @@ -135,7 +135,6 @@ import junit.framework.Assert; // Used to determine whether onFocusChanged was called as a result of // calling remove(). private boolean mInsideRemove; - private boolean mInPassword; // Types used with setType. Keep in sync with CachedInput.h private static final int NORMAL_TEXT_FIELD = 0; @@ -374,18 +373,24 @@ import junit.framework.Assert; } /** - * Ensure that the underlying textfield is lined up with the WebTextView. + * Ensure that the underlying text field/area is lined up with the WebTextView. */ private void lineUpScroll() { Layout layout = getLayout(); if (mWebView != null && layout != null) { - float maxScrollX = Touch.getMaxScrollX(this, layout, mScrollY); - if (DebugFlags.WEB_TEXT_VIEW) { - Log.v(LOGTAG, "onTouchEvent x=" + mScrollX + " y=" - + mScrollY + " maxX=" + maxScrollX); + if (mSingle) { + // textfields only need to be lined up horizontally. + float maxScrollX = layout.getLineRight(0) - getWidth(); + if (DebugFlags.WEB_TEXT_VIEW) { + Log.v(LOGTAG, "onTouchEvent x=" + mScrollX + " y=" + + mScrollY + " maxX=" + maxScrollX); + } + mWebView.scrollFocusedTextInputX(maxScrollX > 0 ? + mScrollX / maxScrollX : 0); + } else { + // textareas only need to be lined up vertically. + mWebView.scrollFocusedTextInputY(mScrollY); } - mWebView.scrollFocusedTextInput(maxScrollX > 0 ? - mScrollX / maxScrollX : 0, mScrollY); } } @@ -414,6 +419,7 @@ import junit.framework.Assert; mLayout.getSpacingAdd(), false, null, ellipsisWidth, lineHeight); } + lineUpScroll(); } /** @@ -786,10 +792,8 @@ import junit.framework.Assert; } @Override - public boolean bringPointIntoView(int offset) { - if (mInPassword) { - return getLayout() != null && super.bringPointIntoView(offset); - } + public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) { + // Do nothing, since webkit will put the textfield on screen. return true; } @@ -904,7 +908,6 @@ import junit.framework.Assert; * @param inPassword True if the textfield is a password field. */ /* package */ void setInPassword(boolean inPassword) { - mInPassword = inPassword; if (inPassword) { setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo. TYPE_TEXT_VARIATION_WEB_PASSWORD); diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index f5ad6fe..c1fafa2 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -6616,23 +6616,34 @@ public class WebView extends AbsoluteLayout } /** - * Scroll the focused text field/area to match the WebTextView + * Scroll the focused text field to match the WebTextView * @param xPercent New x position of the WebTextView from 0 to 1. - * @param y New y position of the WebTextView in view coordinates */ - /*package*/ void scrollFocusedTextInput(float xPercent, int y) { + /*package*/ void scrollFocusedTextInputX(float xPercent) { if (!inEditingMode() || mWebViewCore == null) { return; } - mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, - // Since this position is relative to the top of the text input - // field, we do not need to take the title bar's height into - // consideration. - viewToContentDimension(y), + mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, 0, new Float(xPercent)); } /** + * Scroll the focused textarea vertically to match the WebTextView + * @param y New y position of the WebTextView in view coordinates + */ + /* package */ void scrollFocusedTextInputY(int y) { + if (!inEditingMode()) { + return; + } + int xPos = viewToContentX((mWebTextView.getLeft() + mWebTextView.getRight()) / 2); + int yPos = viewToContentY((mWebTextView.getTop() + mWebTextView.getBottom()) / 2); + int layer = nativeScrollableLayer(xPos, yPos, null, null); + if (layer != 0) { + nativeScrollLayer(layer, 0, viewToContentDimension(y)); + } + } + + /** * Set our starting point and time for a drag from the WebTextView. */ /*package*/ void initiateTextFieldDrag(float x, float y, long eventTime) { @@ -7967,15 +7978,27 @@ public class WebView extends AbsoluteLayout } } - // called by JNI + /** + * Called by JNI to send a message to the webcore thread that the user + * touched the webpage. + * @param touchGeneration Generation number of the touch, to ignore touches + * after a new one has been generated. + * @param frame Pointer to the frame holding the node that was touched. + * @param node Pointer to the node touched. + * @param x x-position of the touch. + * @param y y-position of the touch. + * @param scrollY Only used when touching on a textarea. Otherwise, use -1. + * Tells how much the textarea is scrolled. + */ private void sendMotionUp(int touchGeneration, - int frame, int node, int x, int y) { + int frame, int node, int x, int y, int scrollY) { WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData(); touchUpData.mMoveGeneration = touchGeneration; touchUpData.mFrame = frame; touchUpData.mNode = node; touchUpData.mX = x; touchUpData.mY = y; + touchUpData.mScrollY = scrollY; mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData); } @@ -8301,5 +8324,12 @@ public class WebView extends AbsoluteLayout // Returns a pointer to the scrollable LayerAndroid at the given point. private native int nativeScrollableLayer(int x, int y, Rect scrollRect, Rect scrollBounds); - private native boolean nativeScrollLayer(int layer, int dx, int dy); + /** + * Scroll the specified layer. + * @param layer Id of the layer to scroll, as determined by nativeScrollableLayer. + * @param newX Destination x position to which to scroll. + * @param newY Destination y position to which to scroll. + * @return True if the layer is successfully scrolled. + */ + private native boolean nativeScrollLayer(int layer, int newX, int newY); } diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 4fe1678..bb4441f 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -560,7 +560,7 @@ final class WebViewCore { private native String nativeRetrieveImageSource(int x, int y); private native void nativeTouchUp(int touchGeneration, - int framePtr, int nodePtr, int x, int y); + int framePtr, int nodePtr, int x, int y, int scrollY); private native boolean nativeHandleTouchEvent(int action, int[] idArray, int[] xArray, int[] yArray, int count, int metaState); @@ -790,6 +790,8 @@ final class WebViewCore { int mNode; int mX; int mY; + // Used in the case of a scrolled textarea + int mScrollY; } static class TouchHighlightData { @@ -1321,7 +1323,8 @@ final class WebViewCore { TouchUpData touchUpData = (TouchUpData) msg.obj; nativeTouchUp(touchUpData.mMoveGeneration, touchUpData.mFrame, touchUpData.mNode, - touchUpData.mX, touchUpData.mY); + touchUpData.mX, touchUpData.mY, + touchUpData.mScrollY); break; case TOUCH_EVENT: { |