1 /***
2 * Ambient - A music player for the Android platform
3 Copyright (C) 2007 Martin Vysny
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 package sk.baka.ambient.views.gesturelist;
19
20 import sk.baka.ambient.views.ViewUtils;
21 import android.view.MotionEvent;
22
23 /***
24 * Responsible for processing mouse events and recognition of mouse movements.
25 * Thread unsafe, should be called from the UI thread only.
26 *
27 * @author Martin Vysny
28 */
29 public final class MouseGesturesRecognizer {
30 /***
31 * String representation of left movement.
32 */
33 public static final char LEFT_MOVE = 'L';
34
35 /***
36 * String representation of right movement.
37 */
38 public static final char RIGHT_MOVE = 'R';
39
40 /***
41 * String representation of up movement.
42 */
43 public static final char UP_MOVE = 'U';
44
45 /***
46 * String representation of down movement.
47 */
48 public static final char DOWN_MOVE = 'D';
49
50 /***
51 * Grid size. Default is 15.
52 */
53 public int gridSize = 15;
54
55 /***
56 * Start point x for current movement.
57 */
58 private int startPointX;
59
60 /***
61 * Start point y for current movement.
62 */
63 private int startPointY;
64
65 /***
66 * String representation of gesture.
67 */
68 private StringBuilder gesture = new StringBuilder();
69
70 /***
71 * The gesture event type.
72 *
73 * @author Martin Vysny
74 */
75 public static enum GestureEnum {
76 /***
77 * The gesture was started.
78 */
79 NewGesture,
80 /***
81 * The gesture was started and a new gesture was added.
82 */
83 ContinuingGesture,
84 /***
85 * Gesture was finished.
86 */
87 GestureFinished;
88 }
89
90 /***
91 * Processes mouse event.
92 *
93 * @param mouseEvent
94 * MouseEvent
95 * @return the gesture event, may be <code>null</code> if no new gesture
96 * occured as a result of the event.
97 */
98 public GestureEnum processMouseEvent(final MotionEvent mouseEvent) {
99 if (ViewUtils.isPenUp(mouseEvent)) {
100 return GestureEnum.GestureFinished;
101 }
102 final int x = (int) mouseEvent.getX();
103 final int y = (int) mouseEvent.getY();
104 if (mouseEvent.getAction() == MotionEvent.ACTION_DOWN) {
105 gesture.delete(0, gesture.length());
106 startPointX = x;
107 startPointY = y;
108 return null;
109 }
110 final int deltaX = x - startPointX;
111 final int deltaY = y - startPointY;
112 final int absDeltaX = Math.abs(deltaX);
113 final int absDeltaY = Math.abs(deltaY);
114 if ((absDeltaX < gridSize) && (absDeltaY < gridSize))
115 return null;
116 final char move;
117 if (absDeltaX < absDeltaY) {
118 if (deltaY < 0)
119 move = UP_MOVE;
120 else
121 move = DOWN_MOVE;
122 } else {
123 if (deltaX < 0)
124 move = LEFT_MOVE;
125 else
126 move = RIGHT_MOVE;
127 }
128 startPointX = x;
129 startPointY = y;
130 if (saveMove(move)) {
131 if (gesture.length() == 1)
132 return GestureEnum.NewGesture;
133 return GestureEnum.ContinuingGesture;
134 }
135 return null;
136 }
137
138 /***
139 * Adds movement to the buffer.
140 *
141 * @param move
142 * String representation of recognized movement
143 * @return <code>true</code> if new gesture was added to the
144 * {@link #gesture} list.
145 */
146 private boolean saveMove(char move) {
147
148 if ((gesture.length() > 0)
149 && (gesture.charAt(gesture.length() - 1) == move))
150 return false;
151 gesture.append(move);
152 return true;
153 }
154
155 /***
156 * Returns string representation of mouse gesture.
157 *
158 * @return String representation of mouse gesture. "L" for left, "R" for
159 * right, "U" for up, "D" for down movements. For example: "ULD".
160 */
161 public String getGesture() {
162 return gesture.toString();
163 }
164
165 /***
166 * Indicates whether any movements were recognized.
167 *
168 * @return <code>true</code> if there are recognized movements;
169 * <code>false</code> otherwise
170 */
171 public boolean isGestureRecognized() {
172 return gesture.length() > 0;
173 }
174
175 /***
176 * Returns last gesture.
177 *
178 * @return last gesture or zero char if no gesture was made.
179 */
180 public char getLastGesture() {
181 if (gesture.length() == 0)
182 return 0;
183 return gesture.charAt(gesture.length() - 1);
184 }
185 }