Android Open Source - webots-remote-control Camera Touch Handler V2






From Project

Back to project page webots-remote-control.

License

The source code is released under:

GNU Lesser General Public License

If you think the Android project webots-remote-control listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.black_mesa.webots_remote_control.utils;
//from w w w . j  a  v a 2 s . c o  m
import java.util.Timer;
import java.util.TimerTask;

import org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV2;

import android.os.SystemClock;
import android.view.MotionEvent;

/**
 * Handles the touch events on a CameraView. Interaction mode: 2 virtual joysticks.
 * 
 * @author Ilja Kroonen
 */
public class CameraTouchHandlerV2 {
  private static final int TIMER_TICK = 32;
  private static final float LEFT_JOYSTICK_CENTER_X = .25f;
  private static final float LEFT_JOYSTICK_CENTER_Y = .5f;
  private static final float LEFT_JOYSTICK_RADIUS = .2f;
  private static final float RIGHT_JOYSTICK_CENTER_X = .75f;
  private static final float RIGHT_JOYSTICK_CENTER_Y = .5f;
  private static final float RIGHT_JOYSTICK_RADIUS = .2f;

  /*
   * Right joystick pointer id, coordinates and last timestamp. Valid if mRightValid is true.
   */
  private boolean mRightValid = false;
  private int mRightPointerId;
  private float mRightPointerX;
  private float mRightPointerY;
  private long mRightTimeStamp;

  /*
   * Left joystick pointer id, coordinates. Valid if mLeftValid is true.
   */
  private boolean mLeftValid = false;
  private int mLeftPointerId;
  private float mLeftPointerX;
  private float mLeftPointerY;

  /*
   * Timer used in state DOUBLE and ONLY_RIGHT.
   */
  private Timer mTimer = new Timer();

  /*
   * Information about the touching surface.
   */
  private final float mXMin;
  private final float mYMin;
  private final float mXMax;
  private final float mYMax;
  private final float mLeftCenterX;
  private final float mLeftCenterY;
  private final float mLeftRadius;
  private final float mRightCenterX;
  private final float mRightCenterY;
  private final float mRightRadius;

  /*
   * Listener for the generated events
   */
  private CameraTouchListenerV2 mListener;

  /**
   * Instantiates the CameraTouchHandler.
   * 
   * @param xMin
   *            Start of the x axis of the window.
   * @param yMin
   *            Start of the y axis of the window.
   * @param xMax
   *            End of the x axis of the window.
   * @param yMax
   *            End of the y axis of the window.
   * @param l
   *            Listener that will be notified of the actions that need to be performed on the camera.
   */
  public CameraTouchHandlerV2(final float xMin, final float yMin, final float xMax, final float yMax,
      final CameraTouchListenerV2 l) {
    // TODO
    // Coordinate problem ?
    mXMin = 0;
    mYMin = 0;
    mXMax = xMax;
    mYMax = yMax;
    mLeftCenterX = LEFT_JOYSTICK_CENTER_X * (mXMax - mXMin) + mXMin;
    mLeftCenterY = LEFT_JOYSTICK_CENTER_Y * (mYMax - mYMin) + mYMin;
    mLeftRadius = LEFT_JOYSTICK_RADIUS * (mXMax - mXMin) + mXMin;
    mRightCenterX = RIGHT_JOYSTICK_CENTER_X * (mXMax - mXMin) + mXMin;
    mRightCenterY = RIGHT_JOYSTICK_CENTER_Y * (mYMax - mYMin) + mYMin;
    mRightRadius = RIGHT_JOYSTICK_RADIUS * (mXMax - mXMin) + mXMin;
    mListener = l;
    
    mListener.onJoystickLeftCoordinateChanged(mLeftCenterX, mLeftCenterY, 50);
    mListener.onJoystickRightCoordinateChanged(mRightCenterX, mRightCenterY, 50);
  }

  /**
   * Has to be called at each touch event on the view.
   * 
   * @param event
   *            MotionEvent that was generated by Android.
   */
  public final void onTouch(final MotionEvent event) {
    switch (event.getActionMasked()) {
    case MotionEvent.ACTION_DOWN:
      downHandler(event);
      break;
    case MotionEvent.ACTION_CANCEL:
      cancelHandler(event);
      break;
    case MotionEvent.ACTION_UP:
      upHandler(event);
      break;
    case MotionEvent.ACTION_POINTER_DOWN:
      pointerDownHandler(event);
      break;
    case MotionEvent.ACTION_POINTER_UP:
      pointerUpHandler(event);
      break;
    case MotionEvent.ACTION_MOVE:
      moveHandler(event);
      break;
    }
  }

  private void moveHandler(final MotionEvent event) {
    updateState(event);
    if (mLeftValid) {
      onOrientationChange(event);
    }
    updateAttributes(event);
  }

  private void pointerUpHandler(final MotionEvent event) {
    int id = event.getPointerId(event.getActionIndex());
    if (id == mRightPointerId) {
      changeRightState(false);
    }
    if (id == mLeftPointerId) {
      changeLeftState(false);
    }
  }

  private void pointerDownHandler(final MotionEvent event) {
    updateState(event);
    updateAttributes(event);
  }

  private void upHandler(final MotionEvent event) {
    changeLeftState(false);
    changeRightState(false);
  }

  private void cancelHandler(final MotionEvent event) {
    changeLeftState(false);
    changeRightState(false);
  }

  private void downHandler(final MotionEvent event) {
    updateState(event);
    updateAttributes(event);
  }

  private void timerHandler() {
    if (mRightValid) {
      onPositionChange();
    }
  }

  private void updateAttributes(final MotionEvent event) {
    if (mRightValid) {
      int i = event.findPointerIndex(mRightPointerId);
      mRightPointerX = event.getX(i);
      mRightPointerY = event.getY(i);
      mRightTimeStamp = event.getEventTime();
      mListener.onJoystickRightCoordinateChanged(mRightPointerX, mRightPointerY, 50);
    }
    if (mLeftValid) {
      int i = event.findPointerIndex(mLeftPointerId);
      mLeftPointerX = event.getX(i);
      mLeftPointerY = event.getY(i);
      mListener.onJoystickLeftCoordinateChanged(mLeftPointerX, mLeftPointerY, 50);
    }
  }

  private void updateState(final MotionEvent event) {
    boolean leftValid = mLeftValid;
    if (leftValid) {
      int index = event.findPointerIndex(mLeftPointerId);
      if (!isOnLeftJoystick(event, index)) {
        leftValid = false;
      }
    }
    if (!leftValid) {
      int index = findLeftJoystickPointerIndex(event);
      if (index != -1) {
        mLeftPointerId = event.getPointerId(index);
        leftValid = true;
      }
    }
    changeLeftState(leftValid);

    boolean rightValid = mRightValid;
    if (rightValid) {
      int index = event.findPointerIndex(mRightPointerId);
      if (!isOnRightJoystick(event, index)) {
        rightValid = false;
      }
    }
    if (!rightValid) {
      int index = findRightJoystickPointerIndex(event);
      if (index != -1) {
        mRightPointerId = event.getPointerId(index);
        rightValid = true;
      }
    }
    changeRightState(rightValid);
  }

  private void changeLeftState(final boolean newState) {
    mLeftValid = newState;
    if (!mLeftValid) {
      mListener.onJoystickLeftCoordinateChanged(mLeftCenterX, mLeftCenterY, 50);
    }
  }

  private void changeRightState(final boolean newState) {
    if (newState == mRightValid) {
      return;
    }
    if (!newState) {
      mTimer.cancel();
    }
    if (newState) {
      mTimer = new Timer();
      mTimer.schedule(makeTask(), 0, TIMER_TICK);
    }
    mRightValid = newState;
    if (!mRightValid) {
      mListener.onJoystickRightCoordinateChanged(mRightCenterX, mRightCenterY, 50);
    }
  }

  private boolean isOnLeftJoystick(final MotionEvent event, final int pointerIndex) {
    float x = event.getX(pointerIndex);
    float y = event.getY(pointerIndex);
    float d = distance(x, y, mLeftCenterX, mLeftCenterY);
    return d < mLeftRadius;
  }

  private boolean isOnRightJoystick(final MotionEvent event, final int pointerIndex) {
    float x = event.getX(pointerIndex);
    float y = event.getY(pointerIndex);
    float d = distance(x, y, mRightCenterX, mRightCenterY);
    return d < mRightRadius;
  }

  private float distance(final float x1, final float y1, final float x2, final float y2) {
    return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  }

  private int findLeftJoystickPointerIndex(final MotionEvent event) {
    for (int i = 0; i < event.getPointerCount(); i++) {
      if (isOnLeftJoystick(event, i)) {
        return i;
      }
    }
    return -1;
  }

  private int findRightJoystickPointerIndex(final MotionEvent event) {
    for (int i = 0; i < event.getPointerCount(); i++) {
      if (isOnRightJoystick(event, i)) {
        return i;
      }
    }
    return -1;
  }

  private TimerTask makeTask() {
    return new TimerTask() {
      @Override
      public void run() {
        timerHandler();
      }
    };
  }

  private void onOrientationChange(final MotionEvent event) {
    int index = event.findPointerIndex(mLeftPointerId);
    float dx = (event.getX(index) - mLeftPointerX) / (mXMax - mXMin);
    float dy = (event.getY(index) - mLeftPointerY) / (mYMax - mYMin);
    mListener.turnPitch(dx, dy);
  }

  private void onPositionChange() {
    float x = (mRightPointerX - mRightCenterX) / (mXMax - mXMin);
    float y = (mRightPointerY - mRightCenterY) / (mYMax - mYMin);
    long now = SystemClock.uptimeMillis();
    long time = now - mRightTimeStamp;
    mRightTimeStamp = now;
    mListener.moveRightForward(x, y, time);
  }
}




Java Source Code List

org.black_mesa.webots_remote_control.activities.AboutFragment.java
org.black_mesa.webots_remote_control.activities.AddServerActivity.java
org.black_mesa.webots_remote_control.activities.CameraFragment.java
org.black_mesa.webots_remote_control.activities.ConnectionFragment.java
org.black_mesa.webots_remote_control.activities.MainActivity.java
org.black_mesa.webots_remote_control.client.CamerasManager.java
org.black_mesa.webots_remote_control.client.Client.java
org.black_mesa.webots_remote_control.client.ConnectionManager.java
org.black_mesa.webots_remote_control.client.ConnectionState.java
org.black_mesa.webots_remote_control.client.package-info.java
org.black_mesa.webots_remote_control.communication_structures.CameraInstructionQueue.java
org.black_mesa.webots_remote_control.communication_structures.CameraInstruction.java
org.black_mesa.webots_remote_control.communication_structures.CommunicationStructure.java
org.black_mesa.webots_remote_control.communication_structures.package-info.java
org.black_mesa.webots_remote_control.database.DataBaseContract.java
org.black_mesa.webots_remote_control.database.DataBaseHelper.java
org.black_mesa.webots_remote_control.database.DataSource.java
org.black_mesa.webots_remote_control.database.ServerListAdapter.java
org.black_mesa.webots_remote_control.database.Server.java
org.black_mesa.webots_remote_control.listeners.CameraJoysticksViewListener.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV1.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV2.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV3.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV4.java
org.black_mesa.webots_remote_control.listeners.CameraTouchListenerV5.java
org.black_mesa.webots_remote_control.listeners.ClientListener.java
org.black_mesa.webots_remote_control.listeners.ConnectionManagerListener.java
org.black_mesa.webots_remote_control.listeners.OnListEventsListener.java
org.black_mesa.webots_remote_control.listeners.package-info.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV1.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV2.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV3.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV4.java
org.black_mesa.webots_remote_control.utils.CameraTouchHandlerV5.java
org.black_mesa.webots_remote_control.utils.package-info.java
org.black_mesa.webots_remote_control.views.CameraJoysticksView.java
org.black_mesa.webots_remote_control.views.CameraView.java