ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

ResidualVMEvents.java

Go to the documentation of this file.
00001 package org.residualvm.residualvm;
00002 
00003 import android.os.Handler;
00004 import android.os.Message;
00005 import android.util.DisplayMetrics;
00006 import android.util.Log;
00007 import android.content.Context;
00008 import android.view.InputDevice;
00009 import android.view.KeyEvent;
00010 import android.view.KeyCharacterMap;
00011 import android.view.MotionEvent;
00012 import android.view.View;
00013 import android.view.ViewConfiguration;
00014 import android.view.GestureDetector;
00015 import android.view.inputmethod.InputMethodManager;
00016 
00017 import tv.ouya.console.api.OuyaController;
00018 
00019 public class ResidualVMEvents implements
00020         android.view.View.OnKeyListener,
00021         android.view.View.OnGenericMotionListener,
00022         android.view.GestureDetector.OnGestureListener,
00023         android.view.GestureDetector.OnDoubleTapListener {
00024 
00025     public static final int JE_SYS_KEY = 0;
00026     public static final int JE_KEY = 1;
00027     public static final int JE_DPAD = 2;
00028     public static final int JE_DOWN = 3;
00029     public static final int JE_SCROLL = 4;
00030     public static final int JE_TAP = 5;
00031     public static final int JE_DOUBLE_TAP = 6;
00032     public static final int JE_MULTI = 7;
00033     public static final int JE_BALL = 8;
00034     public static final int JE_TOUCH = 9;
00035     public static final int JE_LONG = 10;
00036     public static final int JE_FLING = 11;
00037     public static final int JE_QUIT = 0x1000;
00038     
00039     private final int REL_SWIPE_MIN_DISTANCE;
00040     private final int REL_SWIPE_THRESHOLD_VELOCITY;
00041 
00042     final protected Context _context;
00043     final protected ResidualVM _residualvm;
00044     final protected GestureDetector _gd;
00045     final protected int _longPress;
00046     final protected int _width;
00047 
00048     public ResidualVMEvents(Context context, ResidualVM residualvm) {
00049         _context = context;
00050         _residualvm = residualvm;
00051 
00052         _gd = new GestureDetector(context, this);
00053         _gd.setOnDoubleTapListener(this);
00054         //_gd.setIsLongpressEnabled(false);
00055 
00056         _longPress = ViewConfiguration.getLongPressTimeout();
00057         
00058         DisplayMetrics dm = context.getResources().getDisplayMetrics();
00059         REL_SWIPE_MIN_DISTANCE       = (int)(120 * dm.densityDpi / 160.0f);
00060         REL_SWIPE_THRESHOLD_VELOCITY = (int)(100 * dm.densityDpi / 160.0f);
00061         _width = dm.widthPixels;
00062     }
00063 
00064     final public void sendQuitEvent() {
00065         _residualvm.pushEvent(JE_QUIT, 0, 0, 0, 0, 0, 0);
00066     }
00067 
00068     public boolean onTrackballEvent(MotionEvent e) {
00069         _residualvm.pushEvent(JE_BALL, e.getAction(),
00070                             (int)(e.getX() * e.getXPrecision() * 100),
00071                             (int)(e.getY() * e.getYPrecision() * 100),
00072                             0, 0, 0);
00073         return true;
00074     }
00075 
00076     final static int MSG_MENU_LONG_PRESS = 1;
00077 
00078     final private Handler keyHandler = new Handler() {
00079         @Override
00080         public void handleMessage(Message msg) {
00081             if (msg.what == MSG_MENU_LONG_PRESS) {
00082                 InputMethodManager imm = (InputMethodManager)
00083                     _context.getSystemService(_context.INPUT_METHOD_SERVICE);
00084 
00085                 if (imm != null)
00086                     imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
00087             }
00088         }
00089     };
00090 
00091 
00092     // OnKeyListener
00093     final public boolean onKey(View v, int keyCode, KeyEvent e) {
00094         final int action = e.getAction();
00095 
00096         if (e.isSystem()) {
00097             // filter what we handle
00098             switch (keyCode) {
00099             case KeyEvent.KEYCODE_BACK:
00100             case KeyEvent.KEYCODE_MENU:
00101             case KeyEvent.KEYCODE_CAMERA:
00102             case KeyEvent.KEYCODE_SEARCH:
00103                 break;
00104 
00105             default:
00106                 return false;
00107             }
00108 
00109             // no repeats for system keys
00110             if (e.getRepeatCount() > 0)
00111                 return false;
00112 
00113             // Have to reimplement hold-down-menu-brings-up-softkeybd
00114             // ourselves, since we are otherwise hijacking the menu key :(
00115             // See com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel()
00116             // for the usual Android implementation of this feature.
00117             if (keyCode == KeyEvent.KEYCODE_MENU) {
00118                 final boolean fired =
00119                     !keyHandler.hasMessages(MSG_MENU_LONG_PRESS);
00120 
00121                 keyHandler.removeMessages(MSG_MENU_LONG_PRESS);
00122 
00123                 if (action == KeyEvent.ACTION_DOWN) {
00124                     keyHandler.sendMessageDelayed(keyHandler.obtainMessage(
00125                                     MSG_MENU_LONG_PRESS), _longPress);
00126                     return true;
00127                 }
00128 
00129                 if (fired)
00130                     return true;
00131 
00132                 // only send up events of the menu button to the native side
00133                 if (action != KeyEvent.ACTION_UP)
00134                     return true;
00135             }
00136 
00137             _residualvm.pushEvent(JE_SYS_KEY, action, keyCode, 0, 0, 0, 0);
00138 
00139             return true;
00140         }
00141 
00142         // sequence of characters
00143         if (action == KeyEvent.ACTION_MULTIPLE &&
00144                 keyCode == KeyEvent.KEYCODE_UNKNOWN) {
00145             final KeyCharacterMap m = KeyCharacterMap.load(e.getDeviceId());
00146             final KeyEvent[] es = m.getEvents(e.getCharacters().toCharArray());
00147 
00148             if (es == null)
00149                 return true;
00150 
00151             for (KeyEvent s : es) {
00152                 _residualvm.pushEvent(JE_KEY, s.getAction(), s.getKeyCode(),
00153                     s.getUnicodeChar() & KeyCharacterMap.COMBINING_ACCENT_MASK,
00154                     s.getMetaState(), s.getRepeatCount(), 0);
00155             }
00156 
00157             return true;
00158         }
00159 
00160         switch (keyCode) {
00161         case KeyEvent.KEYCODE_DPAD_UP:
00162         case KeyEvent.KEYCODE_DPAD_DOWN:
00163         case KeyEvent.KEYCODE_DPAD_LEFT:
00164         case KeyEvent.KEYCODE_DPAD_RIGHT:
00165         case KeyEvent.KEYCODE_DPAD_CENTER:
00166             _residualvm.pushEvent(JE_DPAD, action, keyCode,
00167                                 (int)(e.getEventTime() - e.getDownTime()),
00168                                 e.getRepeatCount(), 0, 0);
00169             return true;
00170         }
00171 
00172         _residualvm.pushEvent(JE_KEY, action, keyCode,
00173                     e.getUnicodeChar() & KeyCharacterMap.COMBINING_ACCENT_MASK,
00174                     e.getMetaState(), e.getRepeatCount(), 0);
00175 
00176         return true;
00177     }
00178 
00179     final public boolean onTouchEvent(MotionEvent e) {
00180         
00181         _gd.onTouchEvent(e);
00182         
00183         final int action = e.getActionMasked();
00184 
00185         // ACTION_MOVE always returns the first pointer as the "active" one.
00186         if (action == MotionEvent.ACTION_MOVE) {
00187             for (int idx = 0; idx < e.getPointerCount(); ++idx) {
00188                 final int pointer = e.getPointerId(idx);
00189                 
00190                 final int x = (int)e.getX(idx);
00191                 final int y = (int)e.getY(idx);
00192                 
00193                 _residualvm.pushEvent(JE_TOUCH, pointer, action, x, y, 0, 0);   
00194             }
00195         } else {
00196             final int idx = e.getActionIndex();
00197             final int pointer = e.getPointerId(idx);
00198             
00199             final int x = (int)e.getX(idx);
00200             final int y = (int)e.getY(idx);
00201             
00202             _residualvm.pushEvent(JE_TOUCH, pointer, action, x, y, 0, 0);   
00203         }
00204         
00205         
00206         return true;
00207     }
00208 
00209     // OnGestureListener
00210     final public boolean onDown(MotionEvent e) {
00211         _residualvm.pushEvent(JE_DOWN, (int)e.getX(), (int)e.getY(), 0, 0, 0, 0);
00212         return true;
00213     }
00214 
00215     final public boolean onFling(MotionEvent e1, MotionEvent e2,
00216                                     float velocityX, float velocityY) {
00217         return false;
00218 //      if (e1.getX() < 0.4 * _width
00219 //          || Math.abs(e1.getX() - e2.getX()) < REL_SWIPE_MIN_DISTANCE
00220 //          || velocityX < REL_SWIPE_THRESHOLD_VELOCITY
00221 //          || Math.abs(e1.getY() - e2.getY()) < REL_SWIPE_MIN_DISTANCE
00222 //          || velocityY < REL_SWIPE_THRESHOLD_VELOCITY)
00223 //        return false;
00224 //      
00225 //      _residualvm.pushEvent(JE_FLING, (int)e1.getX(), (int)e1.getY(),
00226 //                          (int)e2.getX(), (int)e2.getY(), 0, 0);
00227     }
00228 
00229     final public void onLongPress(MotionEvent e) {
00230         _residualvm.pushEvent(JE_LONG, (int)e.getX(), (int)e.getY(),
00231                 0, 0, 0, 0);
00232     }
00233 
00234     final public boolean onScroll(MotionEvent e1, MotionEvent e2,
00235                                     float distanceX, float distanceY) {
00236         _residualvm.pushEvent(JE_SCROLL, (int)e1.getX(), (int)e1.getY(),
00237                             (int)e2.getX(), (int)e2.getY(), 0, 0);
00238         return true;
00239     }
00240 
00241     final public void onShowPress(MotionEvent e) {
00242     }
00243 
00244     final public boolean onSingleTapUp(MotionEvent e) {
00245         return false;
00246     }
00247 
00248     // OnDoubleTapListener
00249     final public boolean onDoubleTap(MotionEvent e) {
00250         return false;
00251     }
00252 
00253     final public boolean onDoubleTapEvent(MotionEvent e) {
00254         _residualvm.pushEvent(JE_DOUBLE_TAP, (int)e.getX(), (int)e.getY(),
00255                             e.getAction(), 0, 0, 0);
00256 
00257         return true;
00258     }
00259 
00260     final public boolean onSingleTapConfirmed(MotionEvent e) {
00261         _residualvm.pushEvent(JE_TAP, (int)e.getX(), (int)e.getY(),
00262                 (int)(e.getEventTime() - e.getDownTime()), 0, 0, 0);
00263         return true;
00264     }
00265 
00266     private static boolean rightJoystickHeld = false;
00267     private static int rightJoystickKeyCode = -1;
00268 
00269     public boolean onGenericMotion(View v, final MotionEvent event) {
00270         if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
00271             float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
00272             if (Math.abs(RS_Y) > OuyaController.STICK_DEADZONE && !rightJoystickHeld) {
00273                 rightJoystickHeld = true;
00274                 rightJoystickKeyCode = RS_Y > 0 ? KeyEvent.KEYCODE_PAGE_DOWN : KeyEvent.KEYCODE_PAGE_UP;
00275                 _residualvm.pushEvent(JE_KEY, KeyEvent.ACTION_DOWN, rightJoystickKeyCode, 0, 0, 0, 0);
00276                 return true;
00277             } else if (Math.abs(RS_Y) <= OuyaController.STICK_DEADZONE && rightJoystickHeld) {
00278                 rightJoystickHeld = false;
00279                 _residualvm.pushEvent(JE_KEY, KeyEvent.ACTION_UP, rightJoystickKeyCode, 0, 0, 0, 0);
00280                 rightJoystickKeyCode = -1;
00281                 return true;
00282             } else {
00283                 return false;
00284             }
00285         }
00286         return false;
00287     }
00288 }


Generated on Sat Feb 23 2019 05:01:15 for ResidualVM by doxygen 1.7.1
curved edge   curved edge