View Javadoc

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 		// should not store two equal moves in succession
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 }