From bb83520a620919a8f19472ba4426585d007d1aba Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Wed, 15 Jul 2015 16:34:34 -0700 Subject: [PATCH] Refactor StylusEventHelper to provide onButtonPress/Release methods This will enable an easier migration to the new M APIs for identifying button presses from stylus / other tools. Bug: 20430722 Change-Id: I41cfa6eff8d76bb83cf1bdaf6623ec1092ed554c --- .../launcher3/WallpaperPickerActivity.java | 5 +- src/com/android/launcher3/BubbleTextView.java | 4 +- src/com/android/launcher3/CellLayout.java | 4 +- src/com/android/launcher3/FolderIcon.java | 4 +- .../launcher3/LauncherAppWidgetHostView.java | 4 +- .../SimpleOnStylusPressListener.java | 25 ++++++ .../android/launcher3/StylusEventHelper.java | 89 ++++++++++++------- .../android/launcher3/widget/WidgetCell.java | 5 +- 8 files changed, 97 insertions(+), 43 deletions(-) create mode 100644 src/com/android/launcher3/SimpleOnStylusPressListener.java diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java index e2c008b4bc..ceb51aa1c1 100644 --- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java +++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java @@ -913,11 +913,12 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { v.setOnLongClickListener(mLongClickListener); // Enable stylus button to also trigger long click. - final StylusEventHelper stylusEventHelper = new StylusEventHelper(v); + final StylusEventHelper stylusEventHelper = + new StylusEventHelper(new SimpleOnStylusPressListener(v), v); v.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { - return stylusEventHelper.checkAndPerformStylusEvent(event); + return stylusEventHelper.onMotionEvent(event); } }); } diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 5070878244..c8af600ba6 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -144,7 +144,7 @@ public class BubbleTextView extends TextView } mLongPressHelper = new CheckLongPressHelper(this); - mStylusEventHelper = new StylusEventHelper(this); + mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mOutlineHelper = HolographicOutlineHelper.obtain(getContext()); if (mCustomShadowsEnabled) { @@ -270,7 +270,7 @@ public class BubbleTextView extends TextView boolean result = super.onTouchEvent(event); // Check for a stylus button press, if it occurs cancel any long press checks. - if (mStylusEventHelper.checkAndPerformStylusEvent(event)) { + if (mStylusEventHelper.onMotionEvent(event)) { mLongPressHelper.cancelLongPress(); result = true; } diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 772bb7be22..b111beea39 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -277,7 +277,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap, mCountX, mCountY); - mStylusEventHelper = new StylusEventHelper(this); + mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mTouchFeedbackView = new ClickShadowView(context); addView(mTouchFeedbackView); @@ -339,7 +339,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { // enabled to allow rearranging the different home screens. So check what mode // the workspace is in, and only perform stylus button presses while in overview mode. if (mLauncher.mWorkspace.isInOverviewMode() - && mStylusEventHelper.checkAndPerformStylusEvent(ev)) { + && mStylusEventHelper.onMotionEvent(ev)) { return true; } return handled; diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java index a175d86920..c6b2f35c49 100644 --- a/src/com/android/launcher3/FolderIcon.java +++ b/src/com/android/launcher3/FolderIcon.java @@ -131,7 +131,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { private void init() { mLongPressHelper = new CheckLongPressHelper(this); - mStylusEventHelper = new StylusEventHelper(this); + mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate()); } @@ -725,7 +725,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { boolean result = super.onTouchEvent(event); // Check for a stylus button press, if it occurs cancel any long press checks. - if (mStylusEventHelper.checkAndPerformStylusEvent(event)) { + if (mStylusEventHelper.onMotionEvent(event)) { mLongPressHelper.cancelLongPress(); return true; } diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java index d8cb682074..01332fb9ed 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java @@ -48,7 +48,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc super(context); mContext = context; mLongPressHelper = new CheckLongPressHelper(this); - mStylusEventHelper = new StylusEventHelper(this); + mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mDragLayer = ((Launcher) context).getDragLayer(); setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate()); @@ -94,7 +94,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc // Watch for longpress or stylus button press events at this level to // make sure users can always pick up this widget - if (mStylusEventHelper.checkAndPerformStylusEvent(ev)) { + if (mStylusEventHelper.onMotionEvent(ev)) { mLongPressHelper.cancelLongPress(); return true; } diff --git a/src/com/android/launcher3/SimpleOnStylusPressListener.java b/src/com/android/launcher3/SimpleOnStylusPressListener.java new file mode 100644 index 0000000000..6b97dcee69 --- /dev/null +++ b/src/com/android/launcher3/SimpleOnStylusPressListener.java @@ -0,0 +1,25 @@ +package com.android.launcher3; + +import android.view.MotionEvent; +import android.view.View; + +import com.android.launcher3.StylusEventHelper.StylusButtonListener; + +/** + * Simple listener that performs a long click on the view after a stylus button press. + */ +public class SimpleOnStylusPressListener implements StylusButtonListener { + private View mView; + + public SimpleOnStylusPressListener(View view) { + mView = view; + } + + public boolean onPressed(MotionEvent event) { + return mView.isLongClickable() && mView.performLongClick(); + } + + public boolean onReleased(MotionEvent event) { + return false; + } +} \ No newline at end of file diff --git a/src/com/android/launcher3/StylusEventHelper.java b/src/com/android/launcher3/StylusEventHelper.java index 54c5509d90..d0e3188a46 100644 --- a/src/com/android/launcher3/StylusEventHelper.java +++ b/src/com/android/launcher3/StylusEventHelper.java @@ -6,55 +6,82 @@ import android.view.ViewConfiguration; /** * Helper for identifying when a stylus touches a view while the primary stylus button is pressed. - * This can occur in {@value MotionEvent#ACTION_DOWN} or {@value MotionEvent#ACTION_MOVE}. On a - * stylus button press this performs the view's {@link View#performLongClick()} method, if the view - * is long clickable. + * This can occur in {@value MotionEvent#ACTION_DOWN} or {@value MotionEvent#ACTION_MOVE}. */ public class StylusEventHelper { - private boolean mIsButtonPressed; - private View mView; - - public StylusEventHelper(View view) { - mView = view; - } /** - * Call this in onTouchEvent method of a view to identify a stylus button press and perform a - * long click (if the view is long clickable). - * - * @param event The event to check for a stylus button press. - * @return Whether a stylus event occurred and was handled. + * Implement this interface to receive callbacks for a stylus button press and release. */ - public boolean checkAndPerformStylusEvent(MotionEvent event) { - final float slop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop(); + public interface StylusButtonListener { + /** + * Called when the stylus button is pressed. + * + * @param event The MotionEvent that the button press occurred for. + * @return Whether the event was handled. + */ + public boolean onPressed(MotionEvent event); - if (!mView.isLongClickable()) { - // We don't do anything unless the view is long clickable. - return false; + /** + * Called when the stylus button is released after a button press. This is also called if + * the event is canceled or the stylus is lifted off the screen. + * + * @param event The MotionEvent the button release occurred for. + * @return Whether the event was handled. + */ + public boolean onReleased(MotionEvent event); + } + + private boolean mIsButtonPressed; + private View mView; + private StylusButtonListener mListener; + private final float mSlop; + + /** + * Constructs a helper for listening to stylus button presses and releases. Ensure that { + * {@link #onMotionEvent(MotionEvent)} and {@link #onGenericMotionEvent(MotionEvent)} are called on + * the helper to correctly identify stylus events. + * + * @param listener The listener to call for stylus events. + * @param view Optional view associated with the touch events. + */ + public StylusEventHelper(StylusButtonListener listener, View view) { + mListener = listener; + mView = view; + if (mView != null) { + mSlop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop(); + } else { + mSlop = ViewConfiguration.getTouchSlop(); } + } + public boolean onMotionEvent(MotionEvent event) { final boolean stylusButtonPressed = isStylusButtonPressed(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: - mIsButtonPressed = false; - if (stylusButtonPressed && mView.performLongClick()) { - mIsButtonPressed = true; - return true; + mIsButtonPressed = stylusButtonPressed; + if (mIsButtonPressed) { + return mListener.onPressed(event); } break; case MotionEvent.ACTION_MOVE: - if (Utilities.pointInView(mView, event.getX(), event.getY(), slop)) { - if (!mIsButtonPressed && stylusButtonPressed && mView.performLongClick()) { - mIsButtonPressed = true; - return true; - } else if (mIsButtonPressed && !stylusButtonPressed) { - mIsButtonPressed = false; - } + if (!Utilities.pointInView(mView, event.getX(), event.getY(), mSlop)) { + return false; + } + if (!mIsButtonPressed && stylusButtonPressed) { + mIsButtonPressed = true; + return mListener.onPressed(event); + } else if (mIsButtonPressed && !stylusButtonPressed) { + mIsButtonPressed = false; + return mListener.onReleased(event); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - mIsButtonPressed = false; + if (mIsButtonPressed) { + mIsButtonPressed = false; + return mListener.onReleased(event); + } break; } return false; diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index 94bbd929fb..70eceb9ce7 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -36,6 +36,7 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetProviderInfo; +import com.android.launcher3.SimpleOnStylusPressListener; import com.android.launcher3.R; import com.android.launcher3.StylusEventHelper; import com.android.launcher3.WidgetPreviewLoader; @@ -93,7 +94,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { final Resources r = context.getResources(); mLauncher = (Launcher) context; - mStylusEventHelper = new StylusEventHelper(this); + mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mDimensionsFormatString = r.getString(R.string.widget_dims_format); setContainerWidth(); @@ -211,7 +212,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { @Override public boolean onTouchEvent(MotionEvent ev) { boolean handled = super.onTouchEvent(ev); - if (mStylusEventHelper.checkAndPerformStylusEvent(ev)) { + if (mStylusEventHelper.onMotionEvent(ev)) { return true; } return handled;