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
00021 import java.util.concurrent.ExecutorService;
00022 import android.content.Context;
00023 import android.os.Handler;
00024 import android.view.GestureDetector;
00025 import android.view.MotionEvent;
00026 import android.view.ScaleGestureDetector;
00027 import android.view.View;
00028 import android.view.ViewGroup;
00029 import org.ros.android.view.RosImageView;
00030 import org.ros.android.view.visualization.Camera;
00031 import org.ros.android.view.visualization.RotateGestureDetector;
00032 import org.ros.android.view.visualization.VisualizationView;
00033 import org.ros.android.view.visualization.layer.CameraControlLayer;
00034 import org.ros.android.view.visualization.layer.CameraControlListener;
00035 import org.ros.concurrent.ListenerGroup;
00036 import org.ros.concurrent.SignalRunnable;
00037 import org.ros.node.ConnectedNode;
00038 import org.ros.rosjava_geometry.FrameTransformTree;
00039
00043 public class ViewControlLayer extends CameraControlLayer {
00044
00045 private static final String ROBOT_FRAME = "base_link";
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 mapViewGestureAvaiable;
00058
00059
00060 private enum ViewMode {
00061 CAMERA, MAP
00062 };
00063 private ViewMode viewMode;
00064
00065
00066 public ViewControlLayer(Context context,
00067 ExecutorService executorService,
00068 RosImageView<sensor_msgs.CompressedImage> cameraView,
00069 VisualizationView mapView,
00070 ViewGroup mainLayout,
00071 ViewGroup sideLayout){
00072 super(context,executorService);
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 mapViewGestureAvaiable = false;
00094 }
00095
00096
00097 @Override
00098 public boolean onTouchEvent(VisualizationView view,MotionEvent event){
00099
00100 if(event.getAction()==MotionEvent.ACTION_UP){
00101 mapViewGestureAvaiable = true;
00102 }
00103 if(viewMode == ViewMode.CAMERA){
00104 swapViews();
00105 return true;
00106 }
00107 else {
00108 if (translateGestureDetector == null || rotateGestureDetector == null
00109 || zoomGestureDetector == null) {
00110 return false;
00111 }
00112 return translateGestureDetector.onTouchEvent(event)
00113 || rotateGestureDetector.onTouchEvent(event) || zoomGestureDetector.onTouchEvent(event);
00114 }
00115 }
00116
00117
00118
00122 private void swapViews() {
00123
00124 ViewGroup mapViewParent;
00125 ViewGroup cameraViewParent;
00126
00127 if (viewMode == ViewMode.CAMERA) {
00128
00129 mapViewParent = sideLayout;
00130 cameraViewParent = mainLayout;
00131 } else {
00132
00133 mapViewParent = mainLayout;
00134 cameraViewParent = sideLayout;
00135 }
00136 int mapViewIndex = mapViewParent.indexOfChild(mapView);
00137 int cameraViewIndex = cameraViewParent.indexOfChild(cameraView);
00138
00139
00140 mapViewParent.removeView(mapView);
00141 cameraViewParent.removeView(cameraView);
00142
00143
00144 mapViewParent.addView(cameraView, mapViewIndex);
00145 cameraViewParent.addView(mapView , cameraViewIndex);
00146
00147
00148 if (viewMode == ViewMode.CAMERA) {
00149 viewMode = ViewMode.MAP;
00150 mapViewGestureAvaiable = false;
00151 } else {
00152 viewMode = ViewMode.CAMERA;
00153 }
00154 mapView.getCamera().jumpToFrame(ROBOT_FRAME);
00155 mapView.setClickable(viewMode != ViewMode.MAP);
00156 cameraView.setClickable(viewMode != ViewMode.CAMERA);
00157
00158 }
00159
00160 @Override
00161 public void onStart(ConnectedNode connectedNode, Handler handler,
00162 FrameTransformTree frameTransformTree, final Camera camera) {
00163 handler.post(new Runnable() {
00164 @Override
00165 public void run() {
00166 translateGestureDetector =
00167 new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
00168 @Override
00169 public boolean onScroll(MotionEvent event1, MotionEvent event2,
00170 final float distanceX, final float distanceY) {
00171 if (mapViewGestureAvaiable) {
00172 camera.translate(-distanceX, distanceY);
00173 listeners.signal(new SignalRunnable<CameraControlListener>() {
00174 @Override
00175 public void run(CameraControlListener listener) {
00176 listener.onTranslate(-distanceX, distanceY);
00177 }
00178 });
00179 return true;
00180 }
00181
00182 return false;
00183 }
00184 });
00185 rotateGestureDetector =
00186 new RotateGestureDetector(new RotateGestureDetector.OnRotateGestureListener() {
00187 @Override
00188 public boolean onRotate(MotionEvent event1, MotionEvent event2,
00189 final double deltaAngle) {
00190 if (mapViewGestureAvaiable) {
00191 final double focusX = (event1.getX(0) + event1.getX(1)) / 2;
00192 final double focusY = (event1.getY(0) + event1.getY(1)) / 2;
00193 camera.rotate(focusX, focusY, deltaAngle);
00194 listeners.signal(new SignalRunnable<CameraControlListener>() {
00195 @Override
00196 public void run(CameraControlListener listener) {
00197 listener.onRotate(focusX, focusY, deltaAngle);
00198 }
00199 });
00200
00201
00202 return false;
00203 }
00204
00205 return true;
00206 }
00207 });
00208 zoomGestureDetector =
00209 new ScaleGestureDetector(context,
00210 new ScaleGestureDetector.SimpleOnScaleGestureListener() {
00211 @Override
00212 public boolean onScale(ScaleGestureDetector detector) {
00213 if (!detector.isInProgress()) {
00214 return false;
00215 }
00216 if (mapViewGestureAvaiable) {
00217 final float focusX = detector.getFocusX();
00218 final float focusY = detector.getFocusY();
00219 final float factor = detector.getScaleFactor();
00220 camera.zoom(focusX, focusY, factor);
00221 listeners.signal(new SignalRunnable<CameraControlListener>() {
00222 @Override
00223 public void run(CameraControlListener listener) {
00224 listener.onZoom(focusX, focusY, factor);
00225 }
00226 });
00227 return true;
00228 }
00229
00230 return false;
00231 }
00232 });
00233 }
00234 });
00235 }
00236 }