diff options
author | Grace Kloba <klobag@google.com> | 2010-01-13 18:02:09 -0800 |
---|---|---|
committer | Grace Kloba <klobag@google.com> | 2010-01-13 22:02:53 -0800 |
commit | 5f01d7e268167c5cfb3366ce08e20a66d9b6fa6f (patch) | |
tree | 2b957445e74ff11c63a39eb3fb1dc853a18a3a13 | |
parent | 56a17690b0b9dc2a2e15ef38a37cc4c403c614fe (diff) | |
download | frameworks_base-5f01d7e268167c5cfb3366ce08e20a66d9b6fa6f.zip frameworks_base-5f01d7e268167c5cfb3366ce08e20a66d9b6fa6f.tar.gz frameworks_base-5f01d7e268167c5cfb3366ce08e20a66d9b6fa6f.tar.bz2 |
DO NOT MERGE
Use the common ScaleGestureDetector to detect the
multi-touch motion.
Check both supportZoom and getBuiltInZoomControls
to decide whether enable the multi-touch behavior.
This should the new pinch behavior only replace the
old +/-.
Fix http://b/issue?id=2363260
Only update textWrapScale if it is different. This
should fix the performance decrease caused by initial
multi-touch code.
Fix http://b/issue?id=2371694
-rw-r--r-- | core/java/android/webkit/WebSettings.java | 2 | ||||
-rw-r--r-- | core/java/android/webkit/WebView.java | 112 |
2 files changed, 58 insertions, 56 deletions
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 6f3262a..093756d 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -411,6 +411,7 @@ public class WebSettings { */ public void setSupportZoom(boolean support) { mSupportZoom = support; + mWebView.updateMultiTouchSupport(mContext); } /** @@ -425,6 +426,7 @@ public class WebSettings { */ public void setBuiltInZoomControls(boolean enabled) { mBuiltInZoomControls = enabled; + mWebView.updateMultiTouchSupport(mContext); } /** diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index f6d6d22..7d0c53b 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -50,6 +50,7 @@ import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; +import android.view.ScaleGestureDetector; import android.view.SoundEffectConstants; import android.view.VelocityTracker; import android.view.View; @@ -430,6 +431,18 @@ public class WebView extends AbsoluteLayout private boolean mWrapContent; + // whether support multi-touch + private static boolean mSupportMultiTouch; + // use the framework's ScaleGestureDetector to handle multi-touch + private ScaleGestureDetector mScaleDetector; + // minimum scale change during multi-touch zoom + private static float PREVIEW_SCALE_INCREMENT = 0.01f; + + // the anchor point in the document space where VIEW_SIZE_CHANGED should + // apply to + private int mAnchorX; + private int mAnchorY; + /** * Private message ids */ @@ -747,9 +760,20 @@ public class WebView extends AbsoluteLayout params; frameParams.gravity = Gravity.RIGHT; } + updateMultiTouchSupport(context); + } + void updateMultiTouchSupport(Context context) { + WebSettings settings = getSettings(); mSupportMultiTouch = context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH); + PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH) + && settings.supportZoom() && settings.getBuiltInZoomControls(); + if (mSupportMultiTouch && (mScaleDetector == null)) { + mScaleDetector = new ScaleGestureDetector(context, + new ScaleDetectorListener()); + } else if (!mSupportMultiTouch && (mScaleDetector != null)) { + mScaleDetector = null; + } } private void updateZoomButtonsEnabled() { @@ -3699,21 +3723,10 @@ public class WebView extends AbsoluteLayout private static final float MAX_SLOPE_FOR_DIAG = 1.5f; private static final int MIN_BREAK_SNAP_CROSS_DISTANCE = 80; - // MultiTouch handling - private static boolean mSupportMultiTouch; - - private double mPinchDistance; - private float mLastPressure; - private int mAnchorX; - private int mAnchorY; - - private static float SCALE_INCREMENT = 0.01f; - private static float PRESSURE_THRESHOLD = 0.67f; - - private boolean doMultiTouch(MotionEvent ev) { - int action = ev.getAction(); + private class ScaleDetectorListener implements + ScaleGestureDetector.OnScaleGestureListener { - if ((action & 0xff) == MotionEvent.ACTION_POINTER_DOWN) { + public boolean onScaleBegin(ScaleGestureDetector detector) { // cancel the single touch handling cancelTouch(); // reset the zoom overview mode so that the page won't auto grow @@ -3723,14 +3736,10 @@ public class WebView extends AbsoluteLayout if (inEditingMode() && nativeFocusCandidateIsPassword()) { mWebTextView.setInPassword(false); } - // start multi (2-pointer) touch - float x0 = ev.getX(0); - float y0 = ev.getY(0); - float x1 = ev.getX(1); - float y1 = ev.getY(1); - mPinchDistance = Math.sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) - * (y0 - y1)); - } else if ((action & 0xff) == MotionEvent.ACTION_POINTER_UP) { + return true; + } + + public void onScaleEnd(ScaleGestureDetector detector) { if (mPreviewZoomOnly) { mPreviewZoomOnly = false; mAnchorX = viewToContentX((int) mZoomCenterX + mScrollX); @@ -3751,24 +3760,14 @@ public class WebView extends AbsoluteLayout // may trigger the unwanted click, can't use TOUCH_DRAG_MODE as it // may trigger the unwanted fling. mTouchMode = TOUCH_PINCH_DRAG; - // action indicates which pointer is UP. Use the other one as drag's - // starting position. - int id = (((action & MotionEvent.ACTION_POINTER_ID_MASK) - >> MotionEvent.ACTION_POINTER_ID_SHIFT) == 0) ? 1 : 0; - startTouch(ev.getX(id), ev.getY(id), ev.getEventTime()); - } else if (action == MotionEvent.ACTION_MOVE) { - float x0 = ev.getX(0); - float y0 = ev.getY(0); - float x1 = ev.getX(1); - float y1 = ev.getY(1); - double distance = Math.sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) - * (y0 - y1)); - float scale = (float) (Math.round(distance / mPinchDistance + startTouch(detector.getFocusX(), detector.getFocusY(), + mLastTouchTime); + } + + public boolean onScale(ScaleGestureDetector detector) { + float scale = (float) (Math.round(detector.getScaleFactor() * mActualScale * 100) / 100.0); - float pressure = ev.getPressure(0) + ev.getPressure(1); - if (Math.abs(scale - mActualScale) >= SCALE_INCREMENT - && (!mPreviewZoomOnly - || (pressure / mLastPressure) > PRESSURE_THRESHOLD)) { + if (Math.abs(scale - mActualScale) >= PREVIEW_SCALE_INCREMENT) { mPreviewZoomOnly = true; // limit the scale change per step if (scale > mActualScale) { @@ -3776,18 +3775,14 @@ public class WebView extends AbsoluteLayout } else { scale = Math.max(scale, mActualScale * 0.8f); } - mZoomCenterX = (x0 + x1) / 2; - mZoomCenterY = (y0 + y1) / 2; + mZoomCenterX = detector.getFocusX(); + mZoomCenterY = detector.getFocusY(); setNewZoomScale(scale, false, false); invalidate(); - mPinchDistance = distance; - mLastPressure = pressure; + return true; } - } else { - Log.w(LOGTAG, action + " should not happen during doMultiTouch"); return false; } - return true; } @Override @@ -3801,9 +3796,12 @@ public class WebView extends AbsoluteLayout + mTouchMode); } - if (mSupportMultiTouch && getSettings().supportZoom() - && mMinZoomScale < mMaxZoomScale && ev.getPointerCount() > 1) { - return doMultiTouch(ev); + // FIXME: we may consider to give WebKit an option to handle multi-touch + // events later. + if (mSupportMultiTouch && mMinZoomScale < mMaxZoomScale + && ev.getPointerCount() > 1) { + mLastTouchTime = ev.getEventTime(); + return mScaleDetector.onTouchEvent(ev); } int action = ev.getAction(); @@ -5150,7 +5148,8 @@ public class WebView extends AbsoluteLayout } if (mInitialScaleInPercent > 0) { setNewZoomScale(mInitialScaleInPercent / 100.0f, - true, false); + mInitialScaleInPercent != mTextWrapScale * 100, + false); } else if (restoreState.mViewScale > 0) { mTextWrapScale = restoreState.mTextWrapScale; setNewZoomScale(restoreState.mViewScale, false, @@ -5158,14 +5157,15 @@ public class WebView extends AbsoluteLayout } else { mInZoomOverview = useWideViewport && settings.getLoadWithOverviewMode(); + float scale; if (mInZoomOverview) { - setNewZoomScale((float) viewWidth - / WebViewCore.DEFAULT_VIEWPORT_WIDTH, - true, false); + scale = (float) viewWidth + / WebViewCore.DEFAULT_VIEWPORT_WIDTH; } else { - setNewZoomScale(restoreState.mTextWrapScale, - true, false); + scale = restoreState.mTextWrapScale; } + setNewZoomScale(scale, Math.abs(scale + - mTextWrapScale) >= 0.01f, false); } setContentScrollTo(restoreState.mScrollX, restoreState.mScrollY); |