diff options
| author | 2012-09-11 16:56:35 -0400 | |
|---|---|---|
| committer | 2012-09-11 22:20:12 -0700 | |
| commit | de3debd9f57ba5c3313d7c785094dc81c16304bf (patch) | |
| tree | 747b4afb8b6f7b9e77c3594a9b67dfd0463381f1 | |
| parent | 40c6ae4d22967379ba4793ac8060b38ddfcf84c2 (diff) | |
Fix notification gestures.
Broken by recent changes to ScaleGestureDetector, which we
were using incorrectly.
Change-Id: Ie5a7981cc14873d34de9041f59b5de442c948a61
| -rw-r--r-- | packages/SystemUI/res/values/config.xml | 2 | ||||
| -rw-r--r-- | packages/SystemUI/res/values/dimens.xml | 5 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/ExpandHelper.java | 240 |
3 files changed, 144 insertions, 103 deletions
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 66add1aacb08..fd5ef4ecbee4 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -67,6 +67,6 @@ <integer translatable="false" name="config_search_panel_view_vibration_duration">20</integer> <!-- The length of the vibration when the notificaiotn pops open. --> - <integer name="one_finger_pop_duration_ms">10</integer> + <integer name="blinds_pop_duration_ms">10</integer> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 6fc79c59bd5f..c6fd66abbec4 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -152,5 +152,8 @@ <dimen name="carrier_label_height">24dp</dimen> <!-- The distance you can pull a notificaiton before it pops open --> - <dimen name="one_finger_pop_limit">32dp</dimen> + <dimen name="blinds_pop_threshold">32dp</dimen> + + <!-- The size of the gesture span needed to activate the "pull" notification expansion --> + <dimen name="pull_span_min">25dp</dimen> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index 674d9a3e0aac..dcfd0b346bdf 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -50,7 +50,7 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { private static final long EXPAND_DURATION = 250; private static final long GLOW_DURATION = 150; - // Set to false to disable focus-based gestures (two-finger pull). + // Set to false to disable focus-based gestures (spread-finger vertical pull). private static final boolean USE_DRAG = true; // Set to false to disable scale-based gestures (both horizontal and vertical). private static final boolean USE_SPAN = true; @@ -69,8 +69,12 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { @SuppressWarnings("unused") private Context mContext; - private boolean mStretching; - private boolean mPullingWithOneFinger; + private boolean mExpanding; + private static final int NONE = 0; + private static final int BLINDS = 1<<0; + private static final int PULL = 1<<1; + private static final int STRETCH = 1<<2; + private int mExpansionStyle = NONE; private boolean mWatchingForPull; private boolean mHasPopped; private View mEventSource; @@ -86,8 +90,9 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { private int mLastMotionY; private float mPopLimit; private int mPopDuration; + private float mPullGestureMinXSpan; private Callback mCallback; - private ScaleGestureDetector mDetector; + private ScaleGestureDetector mSGD; private ViewScaler mScaler; private ObjectAnimator mScaleAnimation; private AnimatorSet mGlowAnimationSet; @@ -122,7 +127,7 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { if (height < 0) { height = mView.getMeasuredHeight(); } - return (float) height; + return height; } public int getNaturalHeight(int maximum) { ViewGroup.LayoutParams lp = mView.getLayoutParams(); @@ -161,8 +166,9 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { mGravity = Gravity.TOP; mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f); mScaleAnimation.setDuration(EXPAND_DURATION); - mPopLimit = mContext.getResources().getDimension(R.dimen.one_finger_pop_limit); - mPopDuration = mContext.getResources().getInteger(R.integer.one_finger_pop_duration_ms); + mPopLimit = mContext.getResources().getDimension(R.dimen.blinds_pop_threshold); + mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms); + mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min); AnimatorListenerAdapter glowVisibilityController = new AnimatorListenerAdapter() { @Override @@ -193,41 +199,30 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { final ViewConfiguration configuration = ViewConfiguration.get(mContext); mTouchSlop = configuration.getScaledTouchSlop(); - mDetector = - new ScaleGestureDetector(context, + mSGD = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() { @Override public boolean onScaleBegin(ScaleGestureDetector detector) { if (DEBUG_SCALE) Slog.v(TAG, "onscalebegin()"); - float x = detector.getFocusX(); - float y = detector.getFocusY(); + float focusX = detector.getFocusX(); + float focusY = detector.getFocusY(); // your fingers have to be somewhat close to the bounds of the view in question - mInitialTouchFocusY = detector.getFocusY(); + mInitialTouchFocusY = focusY; mInitialTouchSpan = Math.abs(detector.getCurrentSpan()); if (DEBUG_SCALE) Slog.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")"); - mStretching = initScale(findView(x, y)); - return mStretching; + final View underFocus = findView(focusX, focusY); + if (underFocus != null) { + startExpanding(underFocus, STRETCH); + } + return mExpanding; } @Override public boolean onScale(ScaleGestureDetector detector) { if (DEBUG_SCALE) Slog.v(TAG, "onscale() on " + mCurrView); - - // are we scaling or dragging? - float span = Math.abs(detector.getCurrentSpan()) - mInitialTouchSpan; - span *= USE_SPAN ? 1f : 0f; - float drag = detector.getFocusY() - mInitialTouchFocusY; - drag *= USE_DRAG ? 1f : 0f; - drag *= mGravity == Gravity.BOTTOM ? -1f : 1f; - float pull = Math.abs(drag) + Math.abs(span) + 1f; - float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull; - float target = hand + mOldHeight; - float newHeight = clamp(target); - mScaler.setHeight(newHeight); - - setGlow(calculateGlow(target, newHeight)); + updateExpansion(); return true; } @@ -236,13 +231,28 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { if (DEBUG_SCALE) Slog.v(TAG, "onscaleend()"); // I guess we're alone now if (DEBUG_SCALE) Slog.d(TAG, "scale end"); - finishScale(false); + finishExpanding(false); clearView(); - mStretching = false; } }); } + private void updateExpansion() { + // are we scaling or dragging? + float span = Math.abs(mSGD.getCurrentSpan()) - mInitialTouchSpan; + span *= USE_SPAN ? 1f : 0f; + float drag = mSGD.getFocusY() - mInitialTouchFocusY; + drag *= USE_DRAG ? 1f : 0f; + drag *= mGravity == Gravity.BOTTOM ? -1f : 1f; + float pull = Math.abs(drag) + Math.abs(span) + 1f; + float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull; + float target = hand + mOldHeight; + float newHeight = clamp(target); + mScaler.setHeight(newHeight); + + setGlow(calculateGlow(target, newHeight)); + } + private float clamp(float target) { float out = target; out = out < mSmallSize ? mSmallSize : (out > mLargeSize ? mLargeSize : out); @@ -255,8 +265,8 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { if (mEventSource != null) { int[] location = new int[2]; mEventSource.getLocationOnScreen(location); - x += (float) location[0]; - y += (float) location[1]; + x += location[0]; + y += location[1]; v = mCallback.getChildAtRawPosition(x, y); } else { v = mCallback.getChildAtPosition(x, y); @@ -274,14 +284,14 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { if (mEventSource != null) { int[] location = new int[2]; mEventSource.getLocationOnScreen(location); - x += (float) location[0]; - y += (float) location[1]; + x += location[0]; + y += location[1]; if (DEBUG) Slog.d(TAG, " to global (" + x + ", " + y + ")"); } int[] location = new int[2]; v.getLocationOnScreen(location); - x -= (float) location[0]; - y -= (float) location[1]; + x -= location[0]; + y -= location[1]; if (DEBUG) Slog.d(TAG, " to local (" + x + ", " + y + ")"); if (DEBUG) Slog.d(TAG, " inside (" + v.getWidth() + ", " + v.getHeight() + ")"); boolean inside = (x > 0f && y > 0f && x < v.getWidth() & y < v.getHeight()); @@ -303,7 +313,7 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { private float calculateGlow(float target, float actual) { // glow if overscale if (DEBUG_GLOW) Slog.d(TAG, "target: " + target + " actual: " + actual); - float stretch = (float) Math.abs((target - actual) / mMaximumStretch); + float stretch = Math.abs((target - actual) / mMaximumStretch); float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f))); if (DEBUG_GLOW) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength); return (GLOW_BASE + strength * (1f - GLOW_BASE)); @@ -340,32 +350,54 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { View.INVISIBLE : View.VISIBLE); } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (DEBUG) Slog.d(TAG, "interceptTouch: act=" + (ev.getAction()) + - " stretching=" + mStretching + - " onefinger=" + mPullingWithOneFinger); - // check for a two-finger gesture - mDetector.onTouchEvent(ev); - if (mStretching) { + final int action = ev.getAction(); + if (DEBUG_SCALE) Slog.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) + + " expanding=" + mExpanding + + (0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") + + (0 != (mExpansionStyle & PULL) ? " (pull)" : "") + + (0 != (mExpansionStyle & STRETCH) ? " (stretch)" : "")); + // check for a spread-finger vertical pull gesture + mSGD.onTouchEvent(ev); + final int x = (int) mSGD.getFocusX(); + final int y = (int) mSGD.getFocusY(); + if (mExpanding) { return true; } else { - final int action = ev.getAction(); - if ((action == MotionEvent.ACTION_MOVE) && mPullingWithOneFinger) { + if ((action == MotionEvent.ACTION_MOVE) && 0 != (mExpansionStyle & BLINDS)) { + // we've begun Venetian blinds style expansion + return true; + } + final float xspan = mSGD.getCurrentSpanX(); + if ((action == MotionEvent.ACTION_MOVE && + xspan > mPullGestureMinXSpan && + xspan > mSGD.getCurrentSpanY())) { + // detect a vertical pulling gesture with fingers somewhat separated + if (DEBUG_SCALE) Slog.v(TAG, "got pull gesture (xspan=" + xspan + "px)"); + + mInitialTouchFocusY = y; + + final View underFocus = findView(x, y); + if (underFocus != null) { + startExpanding(underFocus, PULL); + } return true; } if (mScrollView != null && mScrollView.getScrollY() > 0) { return false; } + // Now look for other gestures switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_MOVE: { if (mWatchingForPull) { - final int x = (int) ev.getX(); - final int y = (int) ev.getY(); final int yDiff = y - mLastMotionY; if (yDiff > mTouchSlop) { + if (DEBUG) Slog.v(TAG, "got venetian gesture (dy=" + yDiff + "px)"); mLastMotionY = y; - mPullingWithOneFinger = initScale(findView(x, y)); - if (mPullingWithOneFinger) { + final View underFocus = findView(x, y); + if (underFocus != null) { + startExpanding(underFocus, BLINDS); mInitialTouchY = mLastMotionY; mHasPopped = false; } @@ -375,35 +407,35 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { } case MotionEvent.ACTION_DOWN: - mWatchingForPull = isInside(mScrollView, ev.getX(), ev.getY()); - mLastMotionY = (int) ev.getY(); + mWatchingForPull = isInside(mScrollView, x, y); + mLastMotionY = y; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - if (mPullingWithOneFinger) { - finishScale(false); - clearView(); - } - mPullingWithOneFinger = false; - mWatchingForPull = false; + if (DEBUG) Slog.d(TAG, "up/cancel"); + finishExpanding(false); + clearView(); break; } - return mPullingWithOneFinger; + return mExpanding; } } + @Override public boolean onTouchEvent(MotionEvent ev) { final int action = ev.getAction(); - if (DEBUG_SCALE) Slog.d(TAG, "touch: act=" + (action) + - " stretching=" + mStretching + - " onefinger=" + mPullingWithOneFinger); - if (mStretching) { - mDetector.onTouchEvent(ev); - } + if (DEBUG_SCALE) Slog.d(TAG, "touch: act=" + MotionEvent.actionToString(action) + + " expanding=" + mExpanding + + (0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") + + (0 != (mExpansionStyle & PULL) ? " (pull)" : "") + + (0 != (mExpansionStyle & STRETCH) ? " (stretch)" : "")); + + mSGD.onTouchEvent(ev); + switch (action) { case MotionEvent.ACTION_MOVE: { - if (mPullingWithOneFinger) { + if (0 != (mExpansionStyle & BLINDS)) { final float rawHeight = ev.getY() - mInitialTouchY + mOldHeight; final float newHeight = clamp(rawHeight); final boolean wasClosed = (mOldHeight == mSmallSize); @@ -430,57 +462,59 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { setGlow(calculateGlow(4f * pull, 0f)); } - final int x = (int) ev.getX(); - final int y = (int) ev.getY(); - View underPointer = findView(x, y); - if (isFinished && underPointer != null && underPointer != mCurrView) { - finishScale(false); - initScale(underPointer); - mInitialTouchY = ev.getY(); + final int x = (int) mSGD.getFocusX(); + final int y = (int) mSGD.getFocusY(); + View underFocus = findView(x, y); + if (isFinished && underFocus != null && underFocus != mCurrView) { + finishExpanding(false); // @@@ needed? + startExpanding(underFocus, BLINDS); + mInitialTouchY = y; mHasPopped = false; } return true; } + + if (mExpanding) { + updateExpansion(); + return true; + } + break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - if (DEBUG) Slog.d(TAG, "cancel"); - mStretching = false; - if (mPullingWithOneFinger) { - finishScale(false); - mPullingWithOneFinger = false; - } + if (DEBUG) Slog.d(TAG, "up/cancel"); + finishExpanding(false); clearView(); break; } return true; } - private boolean initScale(View v) { - if (v != null) { - if (DEBUG) Slog.d(TAG, "scale begins on view: " + v); - mCallback.setUserLockedChild(v, true); - setView(v); - setGlow(GLOW_BASE); - mScaler.setView(v); - mOldHeight = mScaler.getHeight(); - if (mCallback.canChildBeExpanded(v)) { - if (DEBUG) Slog.d(TAG, "working on an expandable child"); - mNaturalHeight = mScaler.getNaturalHeight(mLargeSize); - } else { - if (DEBUG) Slog.d(TAG, "working on a non-expandable child"); - mNaturalHeight = mOldHeight; - } - if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight + - " mNaturalHeight: " + mNaturalHeight); - v.getParent().requestDisallowInterceptTouchEvent(true); - return true; + + private void startExpanding(View v, int expandType) { + mExpanding = true; + mExpansionStyle = expandType; + if (DEBUG) Slog.d(TAG, "scale type " + expandType + " beginning on view: " + v); + mCallback.setUserLockedChild(v, true); + setView(v); + setGlow(GLOW_BASE); + mScaler.setView(v); + mOldHeight = mScaler.getHeight(); + if (mCallback.canChildBeExpanded(v)) { + if (DEBUG) Slog.d(TAG, "working on an expandable child"); + mNaturalHeight = mScaler.getNaturalHeight(mLargeSize); } else { - return false; + if (DEBUG) Slog.d(TAG, "working on a non-expandable child"); + mNaturalHeight = mOldHeight; } + if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight + + " mNaturalHeight: " + mNaturalHeight); + v.getParent().requestDisallowInterceptTouchEvent(true); } - private void finishScale(boolean force) { + private void finishExpanding(boolean force) { + if (!mExpanding) return; + float currentHeight = mScaler.getHeight(); float targetHeight = mSmallSize; float h = mScaler.getHeight(); @@ -501,6 +535,10 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { mScaleAnimation.start(); } mCallback.setUserLockedChild(mCurrView, false); + + mExpanding = false; + mExpansionStyle = NONE; + if (DEBUG) Slog.d(TAG, "scale was finished on view: " + mCurrView); } @@ -527,8 +565,8 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener { @Override public void onClick(View v) { - initScale(v); - finishScale(true); + startExpanding(v, STRETCH); + finishExpanding(true); clearView(); } |