/** * Copyright (C) 2012 Iordan Iordanov * Copyright (C) 2010 Michael A. MacDonald * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ package com.iiordanov.bVNC.input; import com.iiordanov.bVNC.RemoteCanvas; import com.iiordanov.bVNC.RemoteCanvasActivity; import android.graphics.PointF; import android.os.Handler; import android.view.KeyEvent; import android.view.MotionEvent; /** * Input handlers delegate to this class to handle keystrokes; this detects keystrokes * from the DPad and uses them to perform mouse actions; other keystrokes are passed to * RemoteCanvasActivity.defaultKeyXXXHandler * * @author Iordan Iordanov * @author Michael A. MacDonald * */ class DPadMouseKeyHandler { private MouseMover mouseMover; private boolean mouseDown; private RemoteCanvas canvas; private boolean isMoving; private boolean useDpadAsArrows = false; private boolean rotateDpad = false; RemoteKeyboard keyboard; RemotePointer pointer; DPadMouseKeyHandler(RemoteCanvasActivity activity, Handler handler, boolean arrows, boolean rotate) { canvas = activity.getCanvas(); mouseMover = new MouseMover(activity, handler); useDpadAsArrows = arrows; rotateDpad = rotate; } public boolean onKeyDown(int keyCode, KeyEvent evt) { int xv = 0; int yv = 0; boolean result = true; keyboard = canvas.getKeyboard(); pointer = canvas.getPointer(); boolean cameraButtonDown = keyboard.getCameraButtonDown(); // If we are instructed to rotate the Dpad at 90 degrees, reassign KeyCodes. if (rotateDpad) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_LEFT: keyCode = KeyEvent.KEYCODE_DPAD_UP; break; case KeyEvent.KEYCODE_DPAD_RIGHT: keyCode = KeyEvent.KEYCODE_DPAD_DOWN; break; case KeyEvent.KEYCODE_DPAD_UP: keyCode = KeyEvent.KEYCODE_DPAD_RIGHT; break; case KeyEvent.KEYCODE_DPAD_DOWN: keyCode = KeyEvent.KEYCODE_DPAD_LEFT; break; } } // If we are supposed to use the Dpad as arrows, pass the event to the default handler. if (useDpadAsArrows) { return keyboard.processLocalKeyEvent(keyCode, evt); // Otherwise, control the mouse. } else { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_LEFT: xv = -1; break; case KeyEvent.KEYCODE_DPAD_RIGHT: xv = 1; break; case KeyEvent.KEYCODE_DPAD_UP: yv = -1; break; case KeyEvent.KEYCODE_DPAD_DOWN: yv = 1; break; case KeyEvent.KEYCODE_DPAD_CENTER: if (!mouseDown) { mouseDown = true; result = pointer.processPointerEvent(pointer.getX(), pointer.getY(), MotionEvent.ACTION_DOWN, evt.getMetaState(), mouseDown, cameraButtonDown); } break; default: result = keyboard.processLocalKeyEvent(keyCode, evt); break; } } if ((xv != 0 || yv != 0) && !isMoving) { final int x = xv; final int y = yv; isMoving = true; mouseMover.start(x, y, new Panner.VelocityUpdater() { /* * (non-Javadoc) * * @see com.iiordanov.bVNC.Panner.VelocityUpdater#updateVelocity(android.graphics.Point, * long) */ @Override public boolean updateVelocity(PointF p, long interval) { double scale = (1.2 * (double) interval / 50.0); if (Math.abs(p.x) < 500) p.x += (int) (scale * x); if (Math.abs(p.y) < 500) p.y += (int) (scale * y); return true; } }); pointer.processPointerEvent(pointer.getX() + x, pointer.getY() + y, MotionEvent.ACTION_MOVE, evt.getMetaState(), mouseDown, cameraButtonDown); } return result; } public boolean onKeyUp(int keyCode, KeyEvent evt) { boolean cameraButtonDown = keyboard.getCameraButtonDown(); pointer = canvas.getPointer(); // Pass the event on if we are not controlling the mouse. if (useDpadAsArrows) return keyboard.processLocalKeyEvent(keyCode, evt); boolean result = false; switch (keyCode) { case KeyEvent.KEYCODE_DPAD_LEFT: case KeyEvent.KEYCODE_DPAD_RIGHT: case KeyEvent.KEYCODE_DPAD_UP: case KeyEvent.KEYCODE_DPAD_DOWN: mouseMover.stop(); isMoving = false; result = true; break; case KeyEvent.KEYCODE_DPAD_CENTER: if (mouseDown) { mouseDown = false; result = pointer.processPointerEvent(pointer.getX(), pointer.getY(), MotionEvent.ACTION_UP, evt.getMetaState(), mouseDown, cameraButtonDown); } else { result = true; } break; default: result = keyboard.processLocalKeyEvent(keyCode, evt); break; } return result; } }