1 package com.android.launcher3; 2 3 import android.view.MotionEvent; 4 import android.view.View; 5 import android.view.ViewConfiguration; 6 7 /** 8 * Helper for identifying when a stylus touches a view while the primary stylus button is pressed. 9 * This can occur in {@value MotionEvent#ACTION_DOWN} or {@value MotionEvent#ACTION_MOVE}. On a 10 * stylus button press this performs the view's {@link View#performLongClick()} method, if the view 11 * is long clickable. 12 */ 13 public class StylusEventHelper { 14 private boolean mIsButtonPressed; 15 private View mView; 16 17 public StylusEventHelper(View view) { 18 mView = view; 19 } 20 21 /** 22 * Call this in onTouchEvent method of a view to identify a stylus button press and perform a 23 * long click (if the view is long clickable). 24 * 25 * @param event The event to check for a stylus button press. 26 * @return Whether a stylus event occurred and was handled. 27 */ 28 public boolean checkAndPerformStylusEvent(MotionEvent event) { 29 final float slop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop(); 30 31 if (!mView.isLongClickable()) { 32 // We don't do anything unless the view is long clickable. 33 return false; 34 } 35 36 final boolean stylusButtonPressed = isStylusButtonPressed(event); 37 switch (event.getAction()) { 38 case MotionEvent.ACTION_DOWN: 39 mIsButtonPressed = false; 40 if (stylusButtonPressed && mView.performLongClick()) { 41 mIsButtonPressed = true; 42 return true; 43 } 44 break; 45 case MotionEvent.ACTION_MOVE: 46 if (Utilities.pointInView(mView, event.getX(), event.getY(), slop)) { 47 if (!mIsButtonPressed && stylusButtonPressed && mView.performLongClick()) { 48 mIsButtonPressed = true; 49 return true; 50 } else if (mIsButtonPressed && !stylusButtonPressed) { 51 mIsButtonPressed = false; 52 } 53 } 54 break; 55 case MotionEvent.ACTION_UP: 56 case MotionEvent.ACTION_CANCEL: 57 mIsButtonPressed = false; 58 break; 59 } 60 return false; 61 } 62 63 /** 64 * Whether a stylus button press is occurring. 65 */ 66 public boolean inStylusButtonPressed() { 67 return mIsButtonPressed; 68 } 69 70 /** 71 * Identifies if the provided {@link MotionEvent} is a stylus with the primary stylus button 72 * pressed. 73 * 74 * @param event The event to check. 75 * @return Whether a stylus button press occurred. 76 */ 77 private static boolean isStylusButtonPressed(MotionEvent event) { 78 return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS 79 && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) 80 == MotionEvent.BUTTON_SECONDARY); 81 } 82 }