summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorLeon Scroggins <scroggo@google.com>2011-01-19 17:01:55 -0500
committerLeon Scroggins <scroggo@google.com>2011-01-21 15:42:03 -0500
commitd5188657dcde0f40a6954a00d569c0575bf6095a (patch)
treea9212df979cf5b5a8d4ed7d676a15bfc6fc113ca /core/java/android
parent276677f2ac821e5eb8a7f6a4204242ee47501d6e (diff)
downloadframeworks_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.java18
-rw-r--r--core/java/android/webkit/WebTextView.java29
-rw-r--r--core/java/android/webkit/WebView.java52
-rw-r--r--core/java/android/webkit/WebViewCore.java7
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: {