Skip to content

Commit 54e1553

Browse files
George MountAndroid (Google) Code Review
authored andcommitted
Merge "Enable scrolling page while editing text."
2 parents 0c1c1eb + fcff68f commit 54e1553

File tree

1 file changed

+97
-92
lines changed

1 file changed

+97
-92
lines changed

core/java/android/webkit/WebViewClassic.java

Lines changed: 97 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@
7070
import android.util.EventLog;
7171
import android.util.Log;
7272
import android.view.Display;
73-
import android.view.GestureDetector;
74-
import android.view.GestureDetector.SimpleOnGestureListener;
7573
import android.view.Gravity;
7674
import android.view.HapticFeedbackConstants;
7775
import android.view.HardwareCanvas;
@@ -820,51 +818,6 @@ protected void measureContent() {
820818
}
821819
}
822820

823-
private class TextScrollListener extends SimpleOnGestureListener {
824-
@Override
825-
public boolean onFling(MotionEvent e1, MotionEvent e2,
826-
float velocityX, float velocityY) {
827-
int maxScrollX = mEditTextContent.width() -
828-
mEditTextBounds.width();
829-
int maxScrollY = mEditTextContent.height() -
830-
mEditTextBounds.height();
831-
832-
int contentVelocityX = viewToContentDimension((int)-velocityX);
833-
int contentVelocityY = viewToContentDimension((int)-velocityY);
834-
mEditTextScroller.fling(-mEditTextContent.left,
835-
-mEditTextContent.top,
836-
contentVelocityX, contentVelocityY,
837-
0, maxScrollX, 0, maxScrollY);
838-
return true;
839-
}
840-
841-
@Override
842-
public boolean onScroll(MotionEvent e1, MotionEvent e2,
843-
float distanceX, float distanceY) {
844-
// Scrollable edit text. Scroll it.
845-
int newScrollX = deltaToTextScroll(
846-
-mEditTextContent.left, mEditTextContent.width(),
847-
mEditTextBounds.width(),
848-
(int) distanceX);
849-
int newScrollY = deltaToTextScroll(
850-
-mEditTextContent.top, mEditTextContent.height(),
851-
mEditTextBounds.height(),
852-
(int) distanceY);
853-
scrollEditText(newScrollX, newScrollY);
854-
return true;
855-
}
856-
857-
private int deltaToTextScroll(int oldScroll, int contentSize,
858-
int boundsSize, int delta) {
859-
int newScroll = oldScroll +
860-
viewToContentDimension(delta);
861-
int maxScroll = contentSize - boundsSize;
862-
newScroll = Math.min(maxScroll, newScroll);
863-
newScroll = Math.max(0, newScroll);
864-
return newScroll;
865-
}
866-
}
867-
868821
// The listener to capture global layout change event.
869822
private InnerGlobalLayoutListener mGlobalLayoutListener = null;
870823

@@ -893,7 +846,6 @@ private int deltaToTextScroll(int oldScroll, int contentSize,
893846
private int mFieldPointer;
894847
private PastePopupWindow mPasteWindow;
895848
private AutoCompletePopup mAutoCompletePopup;
896-
private GestureDetector mGestureDetector;
897849
Rect mEditTextBounds = new Rect();
898850
Rect mEditTextContent = new Rect();
899851
int mEditTextLayerId;
@@ -1037,6 +989,7 @@ public void onTrimMemory(int level) {
1037989
private static final int TOUCH_DONE_MODE = 7;
1038990
private static final int TOUCH_PINCH_DRAG = 8;
1039991
private static final int TOUCH_DRAG_LAYER_MODE = 9;
992+
private static final int TOUCH_DRAG_TEXT_MODE = 10;
1040993

1041994
// Whether to forward the touch events to WebCore
1042995
// Can only be set by WebKit via JNI.
@@ -1514,7 +1467,6 @@ public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsi
15141467
}
15151468

15161469
mAutoFillData = new WebViewCore.AutoFillData();
1517-
mGestureDetector = new GestureDetector(mContext, new TextScrollListener());
15181470
mEditTextScroller = new Scroller(context);
15191471
}
15201472

@@ -3404,6 +3356,10 @@ public void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
34043356
boolean clampedY) {
34053357
// Special-case layer scrolling so that we do not trigger normal scroll
34063358
// updating.
3359+
if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
3360+
scrollEditText(scrollX, scrollY);
3361+
return;
3362+
}
34073363
if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
34083364
scrollLayerTo(scrollX, scrollY);
34093365
return;
@@ -3876,6 +3832,12 @@ public void computeScroll() {
38763832
rangeY = mScrollingLayerRect.bottom;
38773833
// No overscrolling for layers.
38783834
overflingDistance = 0;
3835+
} else if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
3836+
oldX = getTextScrollX();
3837+
oldY = getTextScrollY();
3838+
rangeX = getMaxTextScrollX();
3839+
rangeY = getMaxTextScrollY();
3840+
overflingDistance = 0;
38793841
}
38803842

38813843
mWebViewPrivate.overScrollBy(x - oldX, y - oldY, oldX, oldY,
@@ -3886,12 +3848,14 @@ public void computeScroll() {
38863848
mOverScrollGlow.absorbGlow(x, y, oldX, oldY, rangeX, rangeY);
38873849
}
38883850
} else {
3889-
if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
3890-
setScrollXRaw(x);
3891-
setScrollYRaw(y);
3892-
} else {
3851+
if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
38933852
// Update the layer position instead of WebView.
38943853
scrollLayerTo(x, y);
3854+
} else if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
3855+
scrollEditText(x, y);
3856+
} else {
3857+
setScrollXRaw(x);
3858+
setScrollYRaw(y);
38953859
}
38963860
abortAnimation();
38973861
nativeSetIsScrolling(false);
@@ -6177,7 +6141,6 @@ public void run() {
61776141
startTouch(x, y, eventTime);
61786142
if (mIsEditingText) {
61796143
mTouchInEditText = mEditTextBounds.contains(contentX, contentY);
6180-
mGestureDetector.onTouchEvent(ev);
61816144
}
61826145
break;
61836146
}
@@ -6210,13 +6173,6 @@ public void run() {
62106173
invalidate();
62116174
}
62126175
break;
6213-
} else if (mConfirmMove && mTouchInEditText) {
6214-
ViewParent parent = mWebView.getParent();
6215-
if (parent != null) {
6216-
parent.requestDisallowInterceptTouchEvent(true);
6217-
}
6218-
mGestureDetector.onTouchEvent(ev);
6219-
break;
62206176
}
62216177

62226178
// pass the touch events from UI thread to WebCore thread
@@ -6264,7 +6220,8 @@ public void run() {
62646220
}
62656221

62666222
if (mTouchMode != TOUCH_DRAG_MODE &&
6267-
mTouchMode != TOUCH_DRAG_LAYER_MODE) {
6223+
mTouchMode != TOUCH_DRAG_LAYER_MODE &&
6224+
mTouchMode != TOUCH_DRAG_TEXT_MODE) {
62686225

62696226
if (!mConfirmMove) {
62706227
break;
@@ -6347,9 +6304,6 @@ public void run() {
63476304
deltaX = 0;
63486305
}
63496306
}
6350-
mLastTouchX = x;
6351-
mLastTouchY = y;
6352-
63536307
if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare) {
63546308
mHeldMotionless = MOTIONLESS_FALSE;
63556309
nativeSetIsScrolling(true);
@@ -6360,13 +6314,24 @@ public void run() {
63606314
}
63616315

63626316
mLastTouchTime = eventTime;
6317+
boolean allDrag = doDrag(deltaX, deltaY);
6318+
if (allDrag) {
6319+
mLastTouchX = x;
6320+
mLastTouchY = y;
6321+
} else {
6322+
int contentDeltaX = (int)Math.floor(deltaX * mZoomManager.getInvScale());
6323+
int roundedDeltaX = contentToViewDimension(contentDeltaX);
6324+
int contentDeltaY = (int)Math.floor(deltaY * mZoomManager.getInvScale());
6325+
int roundedDeltaY = contentToViewDimension(contentDeltaY);
6326+
mLastTouchX -= roundedDeltaX;
6327+
mLastTouchY -= roundedDeltaY;
6328+
}
63636329
}
63646330

6365-
doDrag(deltaX, deltaY);
6366-
63676331
// Turn off scrollbars when dragging a layer.
63686332
if (keepScrollBarsVisible &&
6369-
mTouchMode != TOUCH_DRAG_LAYER_MODE) {
6333+
mTouchMode != TOUCH_DRAG_LAYER_MODE &&
6334+
mTouchMode != TOUCH_DRAG_TEXT_MODE) {
63706335
if (mHeldMotionless != MOTIONLESS_TRUE) {
63716336
mHeldMotionless = MOTIONLESS_TRUE;
63726337
invalidate();
@@ -6387,11 +6352,6 @@ public void run() {
63876352
break;
63886353
}
63896354
case MotionEvent.ACTION_UP: {
6390-
mGestureDetector.onTouchEvent(ev);
6391-
if (mTouchInEditText && mConfirmMove) {
6392-
stopTouch();
6393-
break; // We've been scrolling the edit text.
6394-
}
63956355
if (!mConfirmMove && mIsEditingText && mSelectionStarted &&
63966356
mIsCaretSelection) {
63976357
showPasteWindow();
@@ -6505,6 +6465,7 @@ public void run() {
65056465
}
65066466
case TOUCH_DRAG_MODE:
65076467
case TOUCH_DRAG_LAYER_MODE:
6468+
case TOUCH_DRAG_TEXT_MODE:
65086469
mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
65096470
mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
65106471
// if the user waits a while w/o moving before the
@@ -6701,20 +6662,31 @@ private void startDrag() {
67016662
}
67026663
}
67036664

6704-
private void doDrag(int deltaX, int deltaY) {
6665+
private boolean doDrag(int deltaX, int deltaY) {
6666+
boolean allDrag = true;
67056667
if ((deltaX | deltaY) != 0) {
67066668
int oldX = getScrollX();
67076669
int oldY = getScrollY();
67086670
int rangeX = computeMaxScrollX();
67096671
int rangeY = computeMaxScrollY();
6710-
// Check for the original scrolling layer in case we change
6711-
// directions. mTouchMode might be TOUCH_DRAG_MODE if we have
6712-
// reached the edge of a layer but mScrollingLayer will be non-zero
6713-
// if we initiated the drag on a layer.
6714-
if (mCurrentScrollingLayerId != 0) {
6715-
final int contentX = viewToContentDimension(deltaX);
6716-
final int contentY = viewToContentDimension(deltaY);
6717-
6672+
final int contentX = (int)Math.floor(deltaX * mZoomManager.getInvScale());
6673+
final int contentY = (int)Math.floor(deltaY * mZoomManager.getInvScale());
6674+
6675+
// Assume page scrolling and change below if we're wrong
6676+
mTouchMode = TOUCH_DRAG_MODE;
6677+
6678+
// Check special scrolling before going to main page scrolling.
6679+
if (mIsEditingText && mTouchInEditText && canTextScroll(deltaX, deltaY)) {
6680+
// Edit text scrolling
6681+
oldX = getTextScrollX();
6682+
rangeX = getMaxTextScrollX();
6683+
deltaX = contentX;
6684+
oldY = getTextScrollY();
6685+
rangeY = getMaxTextScrollY();
6686+
deltaY = contentY;
6687+
mTouchMode = TOUCH_DRAG_TEXT_MODE;
6688+
allDrag = false;
6689+
} else if (mCurrentScrollingLayerId != 0) {
67186690
// Check the scrolling bounds to see if we will actually do any
67196691
// scrolling. The rectangle is in document coordinates.
67206692
final int maxX = mScrollingLayerRect.right;
@@ -6734,12 +6706,7 @@ private void doDrag(int deltaX, int deltaY) {
67346706
oldY = mScrollingLayerRect.top;
67356707
rangeX = maxX;
67366708
rangeY = maxY;
6737-
} else {
6738-
// Scroll the main page if we are not going to scroll the
6739-
// layer. This does not reset mScrollingLayer in case the
6740-
// user changes directions and the layer can scroll the
6741-
// other way.
6742-
mTouchMode = TOUCH_DRAG_MODE;
6709+
allDrag = false;
67436710
}
67446711
}
67456712

@@ -6755,11 +6722,13 @@ private void doDrag(int deltaX, int deltaY) {
67556722
}
67566723
}
67576724
mZoomManager.keepZoomPickerVisible();
6725+
return allDrag;
67586726
}
67596727

67606728
private void stopTouch() {
67616729
if (mScroller.isFinished() && !mSelectingText
6762-
&& (mTouchMode == TOUCH_DRAG_MODE || mTouchMode == TOUCH_DRAG_LAYER_MODE)) {
6730+
&& (mTouchMode == TOUCH_DRAG_MODE
6731+
|| mTouchMode == TOUCH_DRAG_LAYER_MODE)) {
67636732
WebViewCore.resumePriority();
67646733
WebViewCore.resumeUpdatePicture(mWebViewCore);
67656734
nativeSetIsScrolling(false);
@@ -7153,6 +7122,13 @@ private void doFling() {
71537122
maxY = mScrollingLayerRect.bottom;
71547123
// No overscrolling for layers.
71557124
overscrollDistance = overflingDistance = 0;
7125+
} else if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
7126+
scrollX = getTextScrollX();
7127+
scrollY = getTextScrollY();
7128+
maxX = getMaxTextScrollX();
7129+
maxY = getMaxTextScrollY();
7130+
// No overscrolling for edit text.
7131+
overscrollDistance = overflingDistance = 0;
71567132
}
71577133

71587134
if (mSnapScrollMode != SNAP_NONE) {
@@ -7232,7 +7208,7 @@ private void doFling() {
72327208
final int time = mScroller.getDuration();
72337209

72347210
// Suppress scrollbars for layer scrolling.
7235-
if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
7211+
if (mTouchMode != TOUCH_DRAG_LAYER_MODE && mTouchMode != TOUCH_DRAG_TEXT_MODE) {
72367212
mWebViewPrivate.awakenScrollBars(time);
72377213
}
72387214

@@ -7590,6 +7566,36 @@ public synchronized WebViewCore getWebViewCore() {
75907566
return mWebViewCore;
75917567
}
75927568

7569+
private boolean canTextScroll(int directionX, int directionY) {
7570+
int scrollX = getTextScrollX();
7571+
int scrollY = getTextScrollY();
7572+
int maxScrollX = getMaxTextScrollX();
7573+
int maxScrollY = getMaxTextScrollY();
7574+
boolean canScrollX = (directionX > 0)
7575+
? (scrollX < maxScrollX)
7576+
: (scrollX > 0);
7577+
boolean canScrollY = (directionY > 0)
7578+
? (scrollY < maxScrollY)
7579+
: (scrollY > 0);
7580+
return canScrollX || canScrollY;
7581+
}
7582+
7583+
private int getTextScrollX() {
7584+
return -mEditTextContent.left;
7585+
}
7586+
7587+
private int getTextScrollY() {
7588+
return -mEditTextContent.top;
7589+
}
7590+
7591+
private int getMaxTextScrollX() {
7592+
return Math.max(0, mEditTextContent.width() - mEditTextBounds.width());
7593+
}
7594+
7595+
private int getMaxTextScrollY() {
7596+
return Math.max(0, mEditTextContent.height() - mEditTextBounds.height());
7597+
}
7598+
75937599
/**
75947600
* Used only by TouchEventQueue to store pending touch events.
75957601
*/
@@ -8909,8 +8915,7 @@ private void computeEditTextScroll() {
89098915

89108916
private void scrollEditText(int scrollX, int scrollY) {
89118917
// Scrollable edit text. Scroll it.
8912-
float maxScrollX = (float)(mEditTextContent.width() -
8913-
mEditTextBounds.width());
8918+
float maxScrollX = getMaxTextScrollX();
89148919
float scrollPercentX = ((float)scrollX)/maxScrollX;
89158920
mEditTextContent.offsetTo(-scrollX, -scrollY);
89168921
mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SCROLL_TEXT_INPUT, 0,

0 commit comments

Comments
 (0)