Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package com.github.rosjava.android_apps.map_nav;
00018
00019
00020 import java.util.concurrent.ExecutorService;
00021
00022 import android.content.Context;
00023 import android.view.GestureDetector;
00024 import android.view.MotionEvent;
00025 import android.view.ScaleGestureDetector;
00026 import android.view.View;
00027 import android.view.ViewGroup;
00028
00029 import com.github.rosjava.android_remocons.common_tools.apps.AppParameters;
00030
00031 import org.ros.android.view.RosImageView;
00032 import org.ros.android.view.visualization.RotateGestureDetector;
00033 import org.ros.android.view.visualization.VisualizationView;
00034 import org.ros.android.view.visualization.layer.CameraControlLayer;
00035 import org.ros.android.view.visualization.layer.CameraControlListener;
00036 import org.ros.concurrent.ListenerGroup;
00037 import org.ros.concurrent.SignalRunnable;
00038 import org.ros.node.ConnectedNode;
00039 import org.ros.rosjava_geometry.FrameTransformTree;
00040
00044 public class ViewControlLayer extends CameraControlLayer {
00045
00046 private final Context context;
00047 private final ListenerGroup<CameraControlListener> listeners;
00048
00049 private GestureDetector translateGestureDetector;
00050 private RotateGestureDetector rotateGestureDetector;
00051 private ScaleGestureDetector zoomGestureDetector;
00052
00053 private RosImageView<sensor_msgs.CompressedImage> cameraView;
00054 private VisualizationView mapView;
00055 private ViewGroup mainLayout;
00056 private ViewGroup sideLayout;
00057 private boolean mapViewGestureAvailable;
00058 private String robotFrame;
00059
00060 private enum ViewMode {
00061 CAMERA, MAP
00062 };
00063 private ViewMode viewMode;
00064
00065
00066 public ViewControlLayer(final Context context,
00067 final ExecutorService executorService,
00068 final RosImageView<sensor_msgs.CompressedImage> cameraView,
00069 final VisualizationView mapView,
00070 final ViewGroup mainLayout,
00071 final ViewGroup sideLayout,
00072 final AppParameters params) {
00073
00074 this.context = context;
00075
00076 listeners = new ListenerGroup<CameraControlListener>(executorService);
00077
00078 this.cameraView = cameraView;
00079 this.mapView = mapView;
00080 this.mainLayout = mainLayout;
00081 this.sideLayout = sideLayout;
00082
00083 viewMode = ViewMode.CAMERA;
00084 this.cameraView.setOnClickListener(new View.OnClickListener() {
00085 @Override
00086 public void onClick(View v) {
00087 swapViews();
00088 }
00089 });
00090
00091 this.mapView.setClickable(true);
00092 this.cameraView.setClickable(false);
00093 this.robotFrame = (String) params.get("robot_frame", context.getString(R.string.robot_frame));
00094 mapViewGestureAvailable = false;
00095 }
00096
00097 @Override
00098 public boolean onTouchEvent(VisualizationView view, MotionEvent event) {
00099
00100 if (event.getAction() == MotionEvent.ACTION_UP) {
00101 mapViewGestureAvailable = true;
00102 }
00103 if (viewMode == ViewMode.CAMERA) {
00104 swapViews();
00105 return true;
00106 } else {
00107 if (translateGestureDetector == null ||
00108 rotateGestureDetector == null ||
00109 zoomGestureDetector == null) {
00110 return false;
00111 }
00112 return translateGestureDetector.onTouchEvent(event) ||
00113 rotateGestureDetector.onTouchEvent(event) ||
00114 zoomGestureDetector.onTouchEvent(event);
00115 }
00116 }
00117
00121 private void swapViews() {
00122
00123 ViewGroup mapViewParent;
00124 ViewGroup cameraViewParent;
00125
00126 if (viewMode == ViewMode.CAMERA) {
00127
00128 mapViewParent = sideLayout;
00129 cameraViewParent = mainLayout;
00130 } else {
00131
00132 mapViewParent = mainLayout;
00133 cameraViewParent = sideLayout;
00134 }
00135 int mapViewIndex = mapViewParent.indexOfChild(mapView);
00136 int cameraViewIndex = cameraViewParent.indexOfChild(cameraView);
00137
00138
00139 mapViewParent.removeView(mapView);
00140 cameraViewParent.removeView(cameraView);
00141
00142
00143 mapViewParent.addView(cameraView, mapViewIndex);
00144 cameraViewParent.addView(mapView, cameraViewIndex);
00145
00146
00147 if (viewMode == ViewMode.CAMERA) {
00148 viewMode = ViewMode.MAP;
00149 mapViewGestureAvailable = false;
00150 } else {
00151 viewMode = ViewMode.CAMERA;
00152 }
00153 mapView.getCamera().jumpToFrame(robotFrame);
00154 mapView.setClickable(viewMode != ViewMode.MAP);
00155 cameraView.setClickable(viewMode != ViewMode.CAMERA);
00156 }
00157
00158 @Override
00159 public void onStart(final VisualizationView view, ConnectedNode connectedNode) {
00160 view.post(new Runnable() {
00161 @Override
00162 public void run() {
00163 translateGestureDetector =
00164 new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
00165 @Override
00166 public boolean onScroll(MotionEvent event1, MotionEvent event2,
00167 final float distanceX, final float distanceY) {
00168 if (mapViewGestureAvailable) {
00169 view.getCamera().translate(-distanceX, distanceY);
00170 listeners.signal(new SignalRunnable<CameraControlListener>() {
00171 @Override
00172 public void run(CameraControlListener listener) {
00173 listener.onTranslate(-distanceX, distanceY);
00174 }
00175 });
00176 return true;
00177 }
00178
00179 return false;
00180 }
00181 });
00182 rotateGestureDetector =
00183 new RotateGestureDetector(new RotateGestureDetector.OnRotateGestureListener() {
00184 @Override
00185 public boolean onRotate(MotionEvent event1, MotionEvent event2,
00186 final double deltaAngle) {
00187 if (mapViewGestureAvailable) {
00188 final float focusX = (event1.getX(0) + event1.getX(1)) / 2;
00189 final float focusY = (event1.getY(0) + event1.getY(1)) / 2;
00190 view.getCamera().rotate(focusX, focusY, deltaAngle);
00191 listeners.signal(new SignalRunnable<CameraControlListener>() {
00192 @Override
00193 public void run(CameraControlListener listener) {
00194 listener.onRotate(focusX, focusY, deltaAngle);
00195 }
00196 });
00197
00198
00199 return false;
00200 }
00201
00202 return true;
00203 }
00204 });
00205 zoomGestureDetector =
00206 new ScaleGestureDetector(context,
00207 new ScaleGestureDetector.SimpleOnScaleGestureListener() {
00208 @Override
00209 public boolean onScale(ScaleGestureDetector detector) {
00210 if (!detector.isInProgress()) {
00211 return false;
00212 }
00213 if (mapViewGestureAvailable) {
00214 final float focusX = detector.getFocusX();
00215 final float focusY = detector.getFocusY();
00216 final float factor = detector.getScaleFactor();
00217 view.getCamera().zoom(focusX, focusY, factor);
00218 listeners.signal(new SignalRunnable<CameraControlListener>() {
00219 @Override
00220 public void run(CameraControlListener listener) {
00221 listener.onZoom(focusX, focusY, factor);
00222 }
00223 });
00224 return true;
00225 }
00226
00227 return false;
00228 }
00229 });
00230 }
00231 });
00232 }
00233 }