org.ros.android.view.visualization.layer.CameraControlLayer.java Source code

Java tutorial

Introduction

Here is the source code for org.ros.android.view.visualization.layer.CameraControlLayer.java

Source

/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.ros.android.view.visualization.layer;

import com.google.common.base.Preconditions;

import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;

import org.ros.android.view.visualization.RotateGestureDetector;
import org.ros.android.view.visualization.VisualizationView;
import org.ros.concurrent.ListenerGroup;
import org.ros.concurrent.SignalRunnable;
import org.ros.node.ConnectedNode;
import org.ros.node.NodeMainExecutor;

/**
 * Provides gesture control of the camera for translate, rotate, and zoom.
 *
 * @author damonkohler@google.com (Damon Kohler)
 * @author moesenle@google.com (Lorenz Moesenlechner)
 */
public class CameraControlLayer extends DefaultLayer {

    private ListenerGroup<CameraControlListener> listeners;
    private GestureDetectorCompat translateGestureDetector;
    private RotateGestureDetector rotateGestureDetector;
    private ScaleGestureDetector zoomGestureDetector;

    @Override
    public void init(NodeMainExecutor nodeMainExecutor) {
        listeners = new ListenerGroup<CameraControlListener>(nodeMainExecutor.getScheduledExecutorService());
    }

    public void addListener(CameraControlListener listener) {
        Preconditions.checkNotNull(listeners);
        listeners.add(listener);
    }

    @Override
    public boolean onTouchEvent(VisualizationView view, MotionEvent event) {
        if (translateGestureDetector == null || rotateGestureDetector == null || zoomGestureDetector == null) {
            return false;
        }
        final boolean translateGestureHandled = translateGestureDetector.onTouchEvent(event);
        final boolean rotateGestureHandled = rotateGestureDetector.onTouchEvent(event);
        final boolean zoomGestureHandled = zoomGestureDetector.onTouchEvent(event);
        return translateGestureHandled || rotateGestureHandled || zoomGestureHandled
                || super.onTouchEvent(view, event);
    }

    @Override
    public void onStart(final VisualizationView view, ConnectedNode connectedNode) {
        view.post(new Runnable() {
            @Override
            public void run() {
                translateGestureDetector = new GestureDetectorCompat(view.getContext(),
                        new GestureDetector.SimpleOnGestureListener() {
                            @Override
                            public boolean onDown(MotionEvent e) {
                                // This must return true in order for onScroll() to trigger.
                                return true;
                            }

                            @Override
                            public boolean onScroll(MotionEvent event1, MotionEvent event2, final float distanceX,
                                    final float distanceY) {
                                view.getCamera().translate(-distanceX, distanceY);
                                listeners.signal(new SignalRunnable<CameraControlListener>() {
                                    @Override
                                    public void run(CameraControlListener listener) {
                                        listener.onTranslate(-distanceX, distanceY);
                                    }
                                });
                                return true;
                            }

                            @Override
                            public boolean onDoubleTap(final MotionEvent e) {
                                listeners.signal(new SignalRunnable<CameraControlListener>() {
                                    @Override
                                    public void run(CameraControlListener listener) {
                                        listener.onDoubleTap(e.getX(), e.getY());
                                    }
                                });
                                return true;
                            }
                        });
                rotateGestureDetector = new RotateGestureDetector(
                        new RotateGestureDetector.OnRotateGestureListener() {
                            @Override
                            public boolean onRotate(MotionEvent event1, MotionEvent event2,
                                    final double deltaAngle) {
                                final float focusX = (event1.getX(0) + event1.getX(1)) / 2;
                                final float focusY = (event1.getY(0) + event1.getY(1)) / 2;
                                view.getCamera().rotate(focusX, focusY, deltaAngle);
                                listeners.signal(new SignalRunnable<CameraControlListener>() {
                                    @Override
                                    public void run(CameraControlListener listener) {
                                        listener.onRotate(focusX, focusY, deltaAngle);
                                    }
                                });
                                return true;
                            }
                        });
                zoomGestureDetector = new ScaleGestureDetector(view.getContext(),
                        new ScaleGestureDetector.SimpleOnScaleGestureListener() {
                            @Override
                            public boolean onScale(ScaleGestureDetector detector) {
                                if (!detector.isInProgress()) {
                                    return false;
                                }
                                final float focusX = detector.getFocusX();
                                final float focusY = detector.getFocusY();
                                final float factor = detector.getScaleFactor();
                                view.getCamera().zoom(focusX, focusY, factor);
                                listeners.signal(new SignalRunnable<CameraControlListener>() {
                                    @Override
                                    public void run(CameraControlListener listener) {
                                        listener.onZoom(focusX, focusY, factor);
                                    }
                                });
                                return true;
                            }
                        });
            }
        });
    }
}