11 package com.freerdp.freerdpcore.presentation;
13 import android.content.Context;
14 import android.graphics.Matrix;
15 import android.graphics.RectF;
16 import android.os.Handler;
17 import android.os.Message;
18 import android.util.AttributeSet;
19 import android.view.MotionEvent;
20 import android.widget.ImageView;
22 import com.freerdp.freerdpcore.R;
23 import com.freerdp.freerdpcore.utils.GestureDetector;
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 RectF pointerAreaRects[] =
new RectF[9];
56 private Matrix translationMatrix;
57 private boolean pointerMoving =
false;
58 private boolean pointerScrolling =
false;
60 private UIHandler uiHandler =
new UIHandler();
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 if (transRect.contains(event.getX(), event.getY()))
182 private boolean pointerTouched(MotionEvent event)
184 RectF transRect =
new RectF(pointerRect);
185 translationMatrix.mapRect(transRect);
186 if (transRect.contains(event.getX(), event.getY()))
191 @Override
public boolean onTouchEvent(MotionEvent event)
194 if (!pointerMoving && !pointerScrolling && !pointerTouched(event))
199 @Override
protected void onLayout(
boolean changed,
int left,
int top,
int right,
int bottom)
203 ensureVisibility(right - left, bottom - top);
208 abstract void onTouchPointerClose();
210 abstract void onTouchPointerLeftClick(
int x,
int y,
boolean down);
212 abstract void onTouchPointerRightClick(
int x,
int y,
boolean down);
214 abstract void onTouchPointerMove(
int x,
int y);
216 abstract void onTouchPointerScroll(
boolean down);
218 abstract void onTouchPointerToggleKeyboard();
220 abstract void onTouchPointerToggleExtKeyboard();
222 abstract void onTouchPointerResetScrollZoom();
225 private class UIHandler
extends Handler
233 @Override
public void handleMessage(Message msg)
235 setPointerImage(R.drawable.touch_pointer_default);
239 private class TouchPointerGestureListener
extends GestureDetector.SimpleOnGestureListener
242 private MotionEvent prevEvent =
null;
244 public boolean onDown(MotionEvent e)
246 if (pointerAreaTouched(e, POINTER_ACTION_MOVE))
248 prevEvent = MotionEvent.obtain(e);
249 pointerMoving =
true;
251 else if (pointerAreaTouched(e, POINTER_ACTION_SCROLL))
253 prevEvent = MotionEvent.obtain(e);
254 pointerScrolling =
true;
255 setPointerImage(R.drawable.touch_pointer_scroll);
261 public boolean onUp(MotionEvent e)
263 if (prevEvent !=
null)
269 if (pointerScrolling)
270 setPointerImage(R.drawable.touch_pointer_default);
272 pointerMoving =
false;
273 pointerScrolling =
false;
277 public void onLongPress(MotionEvent e)
279 if (pointerAreaTouched(e, POINTER_ACTION_LCLICK))
281 setPointerImage(R.drawable.touch_pointer_active);
282 pointerMoving =
true;
283 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
284 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
288 public void onLongPressUp(MotionEvent e)
292 setPointerImage(R.drawable.touch_pointer_default);
293 pointerMoving =
false;
294 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
295 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
false);
299 public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX,
float distanceY)
304 movePointer((
int)(e2.getX() - prevEvent.getX()),
305 (
int)(e2.getY() - prevEvent.getY()));
307 prevEvent = MotionEvent.obtain(e2);
310 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
311 listener.onTouchPointerMove((
int)rect.centerX(), (
int)rect.centerY());
314 else if (pointerScrolling)
317 float deltaY = e2.getY() - prevEvent.getY();
318 if (deltaY > SCROLL_DELTA)
320 listener.onTouchPointerScroll(
true);
322 prevEvent = MotionEvent.obtain(e2);
324 else if (deltaY < -SCROLL_DELTA)
326 listener.onTouchPointerScroll(
false);
328 prevEvent = MotionEvent.obtain(e2);
335 public boolean onSingleTapUp(MotionEvent e)
338 if (pointerAreaTouched(e, POINTER_ACTION_CLOSE))
339 listener.onTouchPointerClose();
340 else if (pointerAreaTouched(e, POINTER_ACTION_LCLICK))
342 displayPointerImageAction(R.drawable.touch_pointer_lclick);
343 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
344 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
345 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
false);
347 else if (pointerAreaTouched(e, POINTER_ACTION_RCLICK))
349 displayPointerImageAction(R.drawable.touch_pointer_rclick);
350 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
351 listener.onTouchPointerRightClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
352 listener.onTouchPointerRightClick((
int)rect.centerX(), (
int)rect.centerY(),
false);
354 else if (pointerAreaTouched(e, POINTER_ACTION_KEYBOARD))
356 displayPointerImageAction(R.drawable.touch_pointer_keyboard);
357 listener.onTouchPointerToggleKeyboard();
359 else if (pointerAreaTouched(e, POINTER_ACTION_EXTKEYBOARD))
361 displayPointerImageAction(R.drawable.touch_pointer_extkeyboard);
362 listener.onTouchPointerToggleExtKeyboard();
364 else if (pointerAreaTouched(e, POINTER_ACTION_RESET))
366 displayPointerImageAction(R.drawable.touch_pointer_reset);
367 listener.onTouchPointerResetScrollZoom();
373 public boolean onDoubleTap(MotionEvent e)
376 if (pointerAreaTouched(e, POINTER_ACTION_LCLICK))
378 RectF rect = getCurrentPointerArea(POINTER_ACTION_CURSOR);
379 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
true);
380 listener.onTouchPointerLeftClick((
int)rect.centerX(), (
int)rect.centerY(),
false);
boolean onTouchEvent(MotionEvent ev)