28 private static final int POINTER_ACTION_CURSOR = 0;
29 private static final int POINTER_ACTION_CLOSE = 3;
45 private static final int POINTER_ACTION_RCLICK = 2;
46 private static final int POINTER_ACTION_LCLICK = 4;
47 private static final int POINTER_ACTION_MOVE = 4;
48 private static final int POINTER_ACTION_SCROLL = 5;
49 private static final int POINTER_ACTION_RESET = 6;
50 private static final int POINTER_ACTION_KEYBOARD = 7;
51 private static final int POINTER_ACTION_EXTKEYBOARD = 8;
52 private static final float SCROLL_DELTA = 10.0f;
53 private static final int DEFAULT_TOUCH_POINTER_RESTORE_DELAY = 150;
54 private RectF pointerRect;
55 private final RectF[] pointerAreaRects =
new RectF[9];
56 private Matrix translationMatrix;
57 private boolean pointerMoving =
false;
58 private boolean pointerScrolling =
false;
60 private final UIHandler uiHandler =
new UIHandler();
62 private GestureDetector gestureDetector;
66 initTouchPointer(context);
71 super(context, attrs);
72 initTouchPointer(context);
77 super(context, attrs, defStyle);
78 initTouchPointer(context);
81 private void initTouchPointer(Context context)
84 new GestureDetector(context,
new TouchPointerGestureListener(),
null,
true);
85 gestureDetector.setLongPressTimeout(500);
86 translationMatrix =
new Matrix();
87 setScaleType(ScaleType.MATRIX);
88 setImageMatrix(translationMatrix);
91 final float rectSizeWidth = (float)getDrawable().getIntrinsicWidth() / 3.0f;
92 final float rectSizeHeight = (float)getDrawable().getIntrinsicWidth() / 3.0f;
93 for (
int i = 0; i < 3; i++)
95 for (
int j = 0; j < 3; j++)
97 int left = (int)(j * rectSizeWidth);
98 int top = (int)(i * rectSizeHeight);
99 int right = left + (int)rectSizeWidth;
100 int bottom = top + (int)rectSizeHeight;
101 pointerAreaRects[i * 3 + j] =
new RectF(left, top, right, bottom);
105 new RectF(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
110 this.listener = listener;
113 public int getPointerWidth()
115 return getDrawable().getIntrinsicWidth();
118 public int getPointerHeight()
120 return getDrawable().getIntrinsicHeight();
123 public float[] getPointerPosition()
125 float[] curPos =
new float[2];
126 translationMatrix.mapPoints(curPos);
130 private void movePointer(
float deltaX,
float deltaY)
132 translationMatrix.postTranslate(deltaX, deltaY);
133 setImageMatrix(translationMatrix);
136 private void ensureVisibility(
int screen_width,
int screen_height)
138 float[] curPos =
new float[2];
139 translationMatrix.mapPoints(curPos);
141 if (curPos[0] > (screen_width - pointerRect.width()))
142 curPos[0] = screen_width - pointerRect.width();
145 if (curPos[1] > (screen_height - pointerRect.height()))
146 curPos[1] = screen_height - pointerRect.height();
150 translationMatrix.setTranslate(curPos[0], curPos[1]);
151 setImageMatrix(translationMatrix);
154 private void displayPointerImageAction(
int resId)
156 setPointerImage(resId);
157 uiHandler.sendEmptyMessageDelayed(0, DEFAULT_TOUCH_POINTER_RESTORE_DELAY);
160 private void setPointerImage(
int resId)
162 setImageResource(resId);
166 private RectF getCurrentPointerArea(
int area)
168 RectF transRect =
new RectF(pointerAreaRects[area]);
169 translationMatrix.mapRect(transRect);
173 private boolean pointerAreaTouched(MotionEvent event,
int area)
175 RectF transRect =
new RectF(pointerAreaRects[area]);
176 translationMatrix.mapRect(transRect);
177 return transRect.contains(event.getX(), event.getY());
180 private boolean pointerTouched(MotionEvent event)
182 RectF transRect =
new RectF(pointerRect);
183 translationMatrix.mapRect(transRect);
184 return transRect.contains(event.getX(), event.getY());
187 @Override
public boolean onTouchEvent(MotionEvent event)
190 if (!pointerMoving && !pointerScrolling && !pointerTouched(event))
192 return gestureDetector.onTouchEvent(event);
195 @Override
protected void onLayout(
boolean changed,
int left,
int top,
int right,
int bottom)
199 ensureVisibility(right - left, bottom - top);
204 void onTouchPointerClose();
206 void onTouchPointerLeftClick(
int x,
int y,
boolean down);
208 void onTouchPointerRightClick(
int x,
int y,
boolean down);
210 void onTouchPointerMove(
int x,
int y);
212 void onTouchPointerScroll(
boolean down);
214 void onTouchPointerToggleKeyboard();
216 void onTouchPointerToggleExtKeyboard();
218 void onTouchPointerResetScrollZoom();
221 private class UIHandler
extends Handler
229 @Override
public void handleMessage(Message msg)
231 setPointerImage(R.drawable.touch_pointer_default);
235 private class TouchPointerGestureListener
extends GestureDetector.SimpleOnGestureListener
238 private MotionEvent prevEvent =
null;
240 public boolean onDown(MotionEvent e)
242 if (pointerAreaTouched(e, POINTER_ACTION_MOVE))
244 prevEvent = MotionEvent.obtain(e);
245 pointerMoving =
true;
247 else if (pointerAreaTouched(e, POINTER_ACTION_SCROLL))
249 prevEvent = MotionEvent.obtain(e);
250 pointerScrolling =
true;
251 setPointerImage(R.drawable.touch_pointer_scroll);
257 public boolean onUp(MotionEvent e)
259 if (prevEvent !=
null)
265 if (pointerScrolling)
266 setPointerImage(R.drawable.touch_pointer_default);
268 pointerMoving =
false;
269 pointerScrolling =
false;
273 public void onLongPress(MotionEvent e)
275 if (pointerAreaTouched(e, POINTER_ACTION_LCLICK))
277 setPointerImage(R.drawable.touch_pointer_active);
278 pointerMoving =
true;
279 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
280 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
284 public void onLongPressUp(MotionEvent e)
288 setPointerImage(R.drawable.touch_pointer_default);
289 pointerMoving =
false;
290 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
291 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
false);
295 public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX,
float distanceY)
300 movePointer((
int)(e2.getX() - prevEvent.getX()),
301 (
int)(e2.getY() - prevEvent.getY()));
303 prevEvent = MotionEvent.obtain(e2);
306 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
307 listener.onTouchPointerMove((
int)rect.centerX(), (
int)rect.centerY());
310 else if (pointerScrolling)
313 float deltaY = e2.getY() - prevEvent.getY();
314 if (deltaY > SCROLL_DELTA)
316 listener.onTouchPointerScroll(
true);
318 prevEvent = MotionEvent.obtain(e2);
320 else if (deltaY < -SCROLL_DELTA)
322 listener.onTouchPointerScroll(
false);
324 prevEvent = MotionEvent.obtain(e2);
331 public boolean onSingleTapUp(MotionEvent e)
334 if (pointerAreaTouched(e, POINTER_ACTION_CLOSE))
335 listener.onTouchPointerClose();
336 else if (pointerAreaTouched(e, POINTER_ACTION_LCLICK))
338 displayPointerImageAction(R.drawable.touch_pointer_lclick);
339 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
340 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
341 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
false);
343 else if (pointerAreaTouched(e, POINTER_ACTION_RCLICK))
345 displayPointerImageAction(R.drawable.touch_pointer_rclick);
346 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
347 listener.onTouchPointerRightClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
348 listener.onTouchPointerRightClick((
int)rect.centerX(), (
int)rect.centerY(),
false);
350 else if (pointerAreaTouched(e, POINTER_ACTION_KEYBOARD))
352 displayPointerImageAction(R.drawable.touch_pointer_keyboard);
353 listener.onTouchPointerToggleKeyboard();
355 else if (pointerAreaTouched(e, POINTER_ACTION_EXTKEYBOARD))
357 displayPointerImageAction(R.drawable.touch_pointer_extkeyboard);
358 listener.onTouchPointerToggleExtKeyboard();
360 else if (pointerAreaTouched(e, POINTER_ACTION_RESET))
362 displayPointerImageAction(R.drawable.touch_pointer_reset);
363 listener.onTouchPointerResetScrollZoom();
369 public boolean onDoubleTap(MotionEvent e)
372 if (pointerAreaTouched(e, POINTER_ACTION_LCLICK))
374 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
375 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
376 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
false);