package org.microemu.android.device.ui; import android.view.GestureDetector; import android.widget.Scroller; import jimmui.view.base.NativeCanvas; import jimmui.view.base.TouchControl; import jimmui.view.base.touch.TouchState; import org.microemu.DisplayAccess; import org.microemu.MIDletAccess; import org.microemu.MIDletBridge; import org.microemu.android.device.AndroidDeviceDisplay; import org.microemu.android.device.AndroidDisplayGraphics; import org.microemu.app.ui.DisplayRepaintListener; import org.microemu.device.DeviceFactory; import android.content.Context; import android.graphics.Rect; import android.text.InputType; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; /** * Created with IntelliJ IDEA. * <p/> * Date: 21.02.13 23:46 * * @author vladimir */ public class CanvasView extends View implements DisplayRepaintListener { private AndroidDisplayGraphics graphics = null; private final static int FIRST_DRAG_SENSITIVITY_X = 5; private final static int FIRST_DRAG_SENSITIVITY_Y = 5; private AndroidCanvasUI ui; private AndroidKeyListener keyListener = null; private int inputType = InputType.TYPE_CLASS_TEXT; private GestureDetector gestureDetector; private Scroller scroller; private TouchState state = new TouchState(); public CanvasView(final Context context, AndroidCanvasUI ui, int id) { super(context); this.ui = ui; setFocusable(false); setFocusableInTouchMode(false); setId(id); scroller = new Scroller(context); gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { if (!scroller.isFinished()) { scroller.abortAnimation(); } state.fromX = (int) e.getX(); state.fromY = (int) e.getY(); state.x = (int) e.getX(); state.y = (int) e.getY(); state.region = null; getNativeCanvas().androidPointerPressed(state); return true; } @Override public void onShowPress(MotionEvent e) { // TODO } @Override public boolean onSingleTapUp(MotionEvent e) { state.x = (int) e.getX(); state.y = (int) e.getY(); state.isLong = false; getNativeCanvas().androidPointerTap(state); return true; } @Override public void onLongPress(MotionEvent e) { state.x = (int) e.getX(); state.y = (int) e.getY(); state.isLong = true; getNativeCanvas().androidPointerTap(state); } @Override public boolean onScroll(MotionEvent e, MotionEvent e2, float distanceX, float distanceY) { state.x = (int) e2.getX(); state.y = (int) e2.getY(); state.isLong = false; state.type = TouchControl.DRAGGING; getNativeCanvas().androidPointerMoving(state, (int) distanceX, (int) distanceY); return true; } @Override public boolean onFling(MotionEvent e, MotionEvent e2, float vX, float vY) { state.x = (int) e2.getX(); state.y = (int) e2.getY(); state.isLong = false; state.type = TouchControl.DRAGGED; scroller.fling(state.x, state.y, 0, (int)vY, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE); beginScrolling(); if (state.fromY != state.y) { getNativeCanvas().androidPointerMoved(state, state.x - state.fromX, state.y - state.fromY); } return true; } }); gestureDetector.setIsLongpressEnabled(true); } private void beginScrolling() { new Thread(new Runnable() { @Override public void run() { while (scroller.computeScrollOffset()) { state.x = (int) scroller.getCurrX(); state.y = (int) scroller.getCurrY(); state.type = TouchControl.KINETIC; getNativeCanvas().androidPointerMoving(state, 0, 1); try { Thread.sleep(50);} catch (Exception e) {} } } }).start(); } private NativeCanvas getNativeCanvas() { return (NativeCanvas) ui.getDisplayable(); } private void initGraphics() { if (graphics == null) { graphics = new AndroidDisplayGraphics(); } } public void flushGraphics(int x, int y, int width, int height) { postInvalidate(); } public void setKeyListener(AndroidKeyListener keyListener, int inputType) { this.keyListener = keyListener; this.inputType = inputType; } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE; outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI; outAttrs.inputType = inputType; return new BaseInputConnection(this, false) { @Override public boolean performEditorAction(int actionCode) { if (actionCode == EditorInfo.IME_ACTION_DONE) { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(CanvasView.this.getWindowToken(), 0); return true; } else { return super.performEditorAction(actionCode); } } @Override public boolean commitText(CharSequence text, int newCursorPosition) { if (keyListener != null) { keyListener.insert(keyListener.getCaretPosition(), text); } return true; } @Override public boolean deleteSurroundingText(int leftLength, int rightLength) { if (keyListener != null) { int caret = keyListener.getCaretPosition(); keyListener.delete(caret - leftLength, caret + rightLength); } return true; } @Override public boolean sendKeyEvent(KeyEvent event) { return super.sendKeyEvent(event); } }; } // // View // @Override public void onDraw(android.graphics.Canvas androidCanvas) { super.onDraw(androidCanvas); MIDletAccess ma = MIDletBridge.getMIDletAccess(); if (ma == null) { return; } initGraphics(); graphics.reset(androidCanvas); ma.getDisplayAccess().paint(graphics); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); AndroidDeviceDisplay deviceDisplay = (AndroidDeviceDisplay) DeviceFactory.getDevice().getDeviceDisplay(); deviceDisplay.displayRectangleWidth = w; deviceDisplay.displayRectangleHeight = h; MIDletAccess ma = MIDletBridge.getMIDletAccess(); if (ma == null) { return; } DisplayAccess da = ma.getDisplayAccess(); if (da != null) { da.sizeChanged(); } } public void resetScrolling() { scroller.abortAnimation(); } @Override public boolean onTouchEvent(MotionEvent event) { boolean result = gestureDetector.onTouchEvent(event); if (MotionEvent.ACTION_UP == event.getAction()) { getNativeCanvas().androidPointerReleased(); } return result; } // // DisplayRepaintListener // public void repaintInvoked(Object repaintObject) { Rect r = (Rect) repaintObject; flushGraphics(r.left, r.top, r.width(), r.height()); } }