blob: d0e3188a46584cada0c108ff10453910ee68da91 [file] [log] [blame]
Mady Melloref044dd2015-06-02 15:35:07 -07001package com.android.launcher3;
2
Mady Melloref044dd2015-06-02 15:35:07 -07003import android.view.MotionEvent;
4import android.view.View;
5import android.view.ViewConfiguration;
6
7/**
8 * Helper for identifying when a stylus touches a view while the primary stylus button is pressed.
Mady Mellorbb835202015-07-15 16:34:34 -07009 * This can occur in {@value MotionEvent#ACTION_DOWN} or {@value MotionEvent#ACTION_MOVE}.
Mady Melloref044dd2015-06-02 15:35:07 -070010 */
11public class StylusEventHelper {
Mady Melloref044dd2015-06-02 15:35:07 -070012
13 /**
Mady Mellorbb835202015-07-15 16:34:34 -070014 * Implement this interface to receive callbacks for a stylus button press and release.
Mady Melloref044dd2015-06-02 15:35:07 -070015 */
Mady Mellorbb835202015-07-15 16:34:34 -070016 public interface StylusButtonListener {
17 /**
18 * Called when the stylus button is pressed.
19 *
20 * @param event The MotionEvent that the button press occurred for.
21 * @return Whether the event was handled.
22 */
23 public boolean onPressed(MotionEvent event);
Mady Melloref044dd2015-06-02 15:35:07 -070024
Mady Mellorbb835202015-07-15 16:34:34 -070025 /**
26 * Called when the stylus button is released after a button press. This is also called if
27 * the event is canceled or the stylus is lifted off the screen.
28 *
29 * @param event The MotionEvent the button release occurred for.
30 * @return Whether the event was handled.
31 */
32 public boolean onReleased(MotionEvent event);
33 }
34
35 private boolean mIsButtonPressed;
36 private View mView;
37 private StylusButtonListener mListener;
38 private final float mSlop;
39
40 /**
41 * Constructs a helper for listening to stylus button presses and releases. Ensure that {
42 * {@link #onMotionEvent(MotionEvent)} and {@link #onGenericMotionEvent(MotionEvent)} are called on
43 * the helper to correctly identify stylus events.
44 *
45 * @param listener The listener to call for stylus events.
46 * @param view Optional view associated with the touch events.
47 */
48 public StylusEventHelper(StylusButtonListener listener, View view) {
49 mListener = listener;
50 mView = view;
51 if (mView != null) {
52 mSlop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop();
53 } else {
54 mSlop = ViewConfiguration.getTouchSlop();
Mady Melloref044dd2015-06-02 15:35:07 -070055 }
Mady Mellorbb835202015-07-15 16:34:34 -070056 }
Mady Melloref044dd2015-06-02 15:35:07 -070057
Mady Mellorbb835202015-07-15 16:34:34 -070058 public boolean onMotionEvent(MotionEvent event) {
Mady Melloref044dd2015-06-02 15:35:07 -070059 final boolean stylusButtonPressed = isStylusButtonPressed(event);
60 switch (event.getAction()) {
61 case MotionEvent.ACTION_DOWN:
Mady Mellorbb835202015-07-15 16:34:34 -070062 mIsButtonPressed = stylusButtonPressed;
63 if (mIsButtonPressed) {
64 return mListener.onPressed(event);
Mady Melloref044dd2015-06-02 15:35:07 -070065 }
66 break;
67 case MotionEvent.ACTION_MOVE:
Mady Mellorbb835202015-07-15 16:34:34 -070068 if (!Utilities.pointInView(mView, event.getX(), event.getY(), mSlop)) {
69 return false;
70 }
71 if (!mIsButtonPressed && stylusButtonPressed) {
72 mIsButtonPressed = true;
73 return mListener.onPressed(event);
74 } else if (mIsButtonPressed && !stylusButtonPressed) {
75 mIsButtonPressed = false;
76 return mListener.onReleased(event);
Mady Melloref044dd2015-06-02 15:35:07 -070077 }
78 break;
79 case MotionEvent.ACTION_UP:
80 case MotionEvent.ACTION_CANCEL:
Mady Mellorbb835202015-07-15 16:34:34 -070081 if (mIsButtonPressed) {
82 mIsButtonPressed = false;
83 return mListener.onReleased(event);
84 }
Mady Melloref044dd2015-06-02 15:35:07 -070085 break;
86 }
87 return false;
88 }
89
90 /**
91 * Whether a stylus button press is occurring.
92 */
93 public boolean inStylusButtonPressed() {
94 return mIsButtonPressed;
95 }
96
97 /**
98 * Identifies if the provided {@link MotionEvent} is a stylus with the primary stylus button
99 * pressed.
100 *
101 * @param event The event to check.
102 * @return Whether a stylus button press occurred.
103 */
104 public static boolean isStylusButtonPressed(MotionEvent event) {
105 return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
106 && event.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
107 }
108}