diff options
author | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-22 00:00:05 +0000 |
---|---|---|
committer | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-22 00:00:05 +0000 |
commit | a25b5f3225996f4195689e18d9ff2ae0a113db2b (patch) | |
tree | 6187a8eea4d8f1be9f135d3b6869043c20558c3c /content/public | |
parent | bfc6fd78360d47d8ede19942cc6f94c4f4803295 (diff) | |
download | chromium_src-a25b5f3225996f4195689e18d9ff2ae0a113db2b.zip chromium_src-a25b5f3225996f4195689e18d9ff2ae0a113db2b.tar.gz chromium_src-a25b5f3225996f4195689e18d9ff2ae0a113db2b.tar.bz2 |
Merge 183384
> Hide text handles when scrolling/zooming
>
> Hide the text handles when initiating a scroll or zoom or when the
> scroll offsets/page scale are updated. The handles will fade in shortly
> after movement/scroll/zoom ends.
>
> Also, we no longer need to hide the handles on rotate.
>
> NOTRY=true
>
> BUG=176265,174665,135759
>
>
> Review URL: https://chromiumcodereview.appspot.com/12271012
TBR=cjhopman@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/branches/1410/src@183912 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/public')
5 files changed, 144 insertions, 10 deletions
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 3a14de5..384220d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java @@ -77,6 +77,9 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient { private static final int IS_LONG_PRESS = 1; private static final int IS_LONG_TAP = 2; + // Length of the delay (in ms) before fading in handles after the last page movement. + private static final int TEXT_HANDLE_FADE_IN_DELAY = 300; + // Personality of the ContentView. private final int mPersonality; @@ -218,6 +221,8 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient { private SelectionHandleController mSelectionHandleController; private InsertionHandleController mInsertionHandleController; + private Runnable mDeferredHandleFadeInRunnable; + /** * Handles conversion of a point from window (physical pixel) to document (absolute CSS) space * and vice versa. @@ -1030,6 +1035,7 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient { @Override public boolean sendGesture(int type, long timeMs, int x, int y, Bundle b) { if (mNativeContentViewCore == 0) return false; + updateTextHandlesForGesture(type); switch (type) { case ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE: nativeShowPressState(mNativeContentViewCore, timeMs, x, y); @@ -1317,12 +1323,6 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient { } if (mNeedUpdateOrientationChanged) { - // TODO(cjhopman): Once selection bounds are received from the renderer as absolute - // positions, we will no longer need to unselect before rotation (though we may decide - // it is the correct behavior). - // http://crbug.com/174665 - mImeAdapter.unselect(); - sendOrientationChangeEvent(); mNeedUpdateOrientationChanged = false; } @@ -1738,12 +1738,12 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient { mStartHandlePoint.updateWindowFromDocument(); mEndHandlePoint.updateWindowFromDocument(); mInsertionHandlePoint.updateWindowFromDocument(); - if (mSelectionHandleController != null && mSelectionHandleController.isShowing()) { + if (isSelectionHandleShowing()) { mSelectionHandleController.setStartHandlePosition(mStartHandlePoint.screen); mSelectionHandleController.setEndHandlePosition(mEndHandlePoint.screen); } - if (mInsertionHandleController != null && mInsertionHandleController.isShowing()) { + if (isInsertionHandleShowing()) { mInsertionHandleController.setHandlePosition(mInsertionHandlePoint.screen); } } @@ -1864,6 +1864,67 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient { } } + private boolean isSelectionHandleShowing() { + return mSelectionHandleController != null && mSelectionHandleController.isShowing(); + } + + private boolean isInsertionHandleShowing() { + return mInsertionHandleController != null && mInsertionHandleController.isShowing(); + } + + private void updateTextHandlesForGesture(int type) { + switch(type) { + case ContentViewGestureHandler.GESTURE_DOUBLE_TAP: + case ContentViewGestureHandler.GESTURE_SCROLL_START: + case ContentViewGestureHandler.GESTURE_FLING_START: + case ContentViewGestureHandler.GESTURE_PINCH_BEGIN: + temporarilyHideTextHandles(); + break; + + default: + break; + } + } + + // Makes the insertion/selection handles invisible. They will fade back in shortly after the + // last call to scheduleTextHandleFadeIn (or temporarilyHideTextHandles). + private void temporarilyHideTextHandles() { + if (isSelectionHandleShowing()) { + mSelectionHandleController.setHandleVisibility(HandleView.INVISIBLE); + } + if (isInsertionHandleShowing()) { + mInsertionHandleController.setHandleVisibility(HandleView.INVISIBLE); + } + scheduleTextHandleFadeIn(); + } + + // Cancels any pending fade in and schedules a new one. + private void scheduleTextHandleFadeIn() { + if (!isInsertionHandleShowing() && !isSelectionHandleShowing()) return; + + if (mDeferredHandleFadeInRunnable == null) { + mDeferredHandleFadeInRunnable = new Runnable() { + public void run() { + if (mContentViewGestureHandler.isNativeScrolling() || + mContentViewGestureHandler.isNativePinching()) { + // Delay fade in until no longer scrolling or pinching. + scheduleTextHandleFadeIn(); + } else { + if (isSelectionHandleShowing()) { + mSelectionHandleController.beginHandleFadeIn(); + } + if (isInsertionHandleShowing()) { + mInsertionHandleController.beginHandleFadeIn(); + } + } + } + }; + } + + mContainerView.removeCallbacks(mDeferredHandleFadeInRunnable); + mContainerView.postDelayed(mDeferredHandleFadeInRunnable, TEXT_HANDLE_FADE_IN_DELAY); + } + @SuppressWarnings("unused") @CalledByNative private void updateScrollOffsetAndPageScaleFactor(int x, int y, float scale) { @@ -1884,9 +1945,9 @@ public class ContentViewCore implements MotionEventDelegate, NavigationClient { mNativePageScaleFactor = scale; mPopupZoomer.hide(true); - updateHandleScreenPositions(); - mZoomManager.updateZoomControls(); + + temporarilyHideTextHandles(); } @SuppressWarnings("unused") diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java index eac7492..1c39b0e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java @@ -554,6 +554,22 @@ class ContentViewGestureHandler implements LongPressDelegate { } /** + * @return Whether native is tracking a scroll (i.e. between sending GESTURE_SCROLL_START and + * GESTURE_SCROLL_END, or during a fling before sending GESTURE_FLING_CANCEL). + */ + boolean isNativeScrolling() { + return mNativeScrolling; + } + + /** + * @return Whether native is tracking a pinch (i.e. between sending GESTURE_PINCH_BEGIN and + * GESTURE_PINCH_END). + */ + boolean isNativePinching() { + return mPinchInProgress; + } + + /** * Starts a pinch gesture. * @param timeMs The time in ms for the event initiating this gesture. * @param x The x coordinate for the event initiating this gesture. diff --git a/content/public/android/java/src/org/chromium/content/browser/HandleView.java b/content/public/android/java/src/org/chromium/content/browser/HandleView.java index d952f3f..f90bbf1 100644 --- a/content/public/android/java/src/org/chromium/content/browser/HandleView.java +++ b/content/public/android/java/src/org/chromium/content/browser/HandleView.java @@ -28,6 +28,8 @@ import android.widget.TextView; * View that displays a selection or insertion handle for text editing. */ class HandleView extends View { + private static final float FADE_DURATION = 200.f; + private Drawable mDrawable; private final PopupWindow mContainer; private int mPositionX; @@ -45,6 +47,8 @@ class HandleView extends View { private int mContainerPositionX, mContainerPositionY; private long mTouchTimer; private boolean mIsInsertionHandle = false; + private float mAlpha; + private long mFadeStartTime; private View mParent; private InsertionHandleController.PastePopupMenu mPastePopupWindow; @@ -95,6 +99,8 @@ class HandleView extends View { // Convert line offset dips to pixels. mLineOffsetY = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, LINE_OFFSET_Y_DIP, context.getResources().getDisplayMetrics()); + + mAlpha = 1.f; } void setOrientation(int pos) { @@ -253,6 +259,7 @@ class HandleView extends View { @Override protected void onDraw(Canvas c) { + updateAlpha(); mDrawable.setBounds(0, 0, getRight() - getLeft(), getBottom() - getTop()); mDrawable.draw(c); } @@ -353,6 +360,23 @@ class HandleView extends View { return mDrawable; } + private void updateAlpha() { + if (mAlpha == 1.f) return; + mAlpha = Math.min(1.f, (System.currentTimeMillis() - mFadeStartTime) / FADE_DURATION); + mDrawable.setAlpha((int) (255 * mAlpha)); + invalidate(); + } + + /** + * If the handle is not visible, sets its visibility to View.VISIBLE and begins fading it in. + */ + void beginFadeIn() { + if (getVisibility() == VISIBLE) return; + mAlpha = 0.f; + mFadeStartTime = System.currentTimeMillis(); + setVisibility(VISIBLE); + } + void showPastePopupWindow() { InsertionHandleController ihc = (InsertionHandleController) mController; if (mIsInsertionHandle && ihc.canPaste()) { diff --git a/content/public/android/java/src/org/chromium/content/browser/InsertionHandleController.java b/content/public/android/java/src/org/chromium/content/browser/InsertionHandleController.java index aca49ee..5a457b6 100644 --- a/content/public/android/java/src/org/chromium/content/browser/InsertionHandleController.java +++ b/content/public/android/java/src/org/chromium/content/browser/InsertionHandleController.java @@ -91,6 +91,20 @@ abstract class InsertionHandleController implements CursorController { setHandlePosition((int)point.x, (int)point.y); } + /** + * If the handle is not visible, sets its visibility to View.VISIBLE and begins fading it in. + */ + void beginHandleFadeIn() { + mHandle.beginFadeIn(); + } + + /** + * Sets the handle to the given visibility. + */ + void setHandleVisibility(int visibility) { + mHandle.setVisibility(visibility); + } + int getHandleX() { return mHandle.getAdjustedPositionX(); } @@ -162,6 +176,7 @@ abstract class InsertionHandleController implements CursorController { if (!mIsShowing) { mIsShowing = true; mHandle.show(); + setHandleVisibility(HandleView.VISIBLE); } } diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionHandleController.java b/content/public/android/java/src/org/chromium/content/browser/SelectionHandleController.java index 2de0359..ce3b244 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SelectionHandleController.java +++ b/content/public/android/java/src/org/chromium/content/browser/SelectionHandleController.java @@ -139,6 +139,23 @@ abstract class SelectionHandleController implements CursorController { } /** + * If the handles are not visible, sets their visibility to View.VISIBLE and begins fading them + * in. + */ + void beginHandleFadeIn() { + mStartHandle.beginFadeIn(); + mEndHandle.beginFadeIn(); + } + + /** + * Sets the start and end handles to the given visibility. + */ + void setHandleVisibility(int visibility) { + mStartHandle.setVisibility(visibility); + mEndHandle.setVisibility(visibility); + } + + /** * Shows the handles if allowed. * * @param startDir Direction (left/right) of start handle. @@ -179,6 +196,7 @@ abstract class SelectionHandleController implements CursorController { mIsShowing = true; mStartHandle.show(); mEndHandle.show(); + setHandleVisibility(HandleView.VISIBLE); } } } |