blob: a98fc6cef2a8131451066d98093b71e095cd759d [file] [log] [blame]
/*
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.android.gallery3d.app.dualcam3d;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.Surface;
public class GLView extends GLSurfaceView {
private static final String TAG = "GLView";
private final com.android.gallery3d.app.dualcam3d.gl.Renderer mRenderer;
private Bitmap mBitmap;
private Bitmap mDepthMap;
private int mRotation;
public GLView(Context context) {
this(context, null);
}
public GLView(Context context, AttributeSet attrs) {
super(context, attrs);
setEGLContextClientVersion(2);
mRenderer = new com.android.gallery3d.app.dualcam3d.gl.Renderer();
setRenderer(mRenderer);
}
@Override
public void onResume() {
super.onResume();
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mRenderer.setImageBitmap(mBitmap);
mRenderer.setDepthMap(mDepthMap);
requestRender();
}
@Override
public void onPause() {
super.onPause();
mRenderer.setImageBitmap(null);
mRenderer.setDepthMap(null);
}
public void setImageBitmap(Bitmap bitmap) {
mBitmap = bitmap;
mRenderer.setImageBitmap(bitmap);
mRenderer.setDepthMap(null);
requestRender();
}
public void setDepthMap(Bitmap map) {
mDepthMap = map;
mRenderer.setDepthMap(map);
requestRender();
}
public void setOffset(float x, float y) {
mRenderer.setOffset(x, y);
requestRender();
}
public void setOffsetWithRotation(float x, float y) {
if (mRotation == Surface.ROTATION_0 || mRotation == Surface.ROTATION_180) {
//noinspection SuspiciousNameCombination
setOffset(y, x);
} else {
setOffset(x, y);
}
}
public void setOffsetDelta(float deltaX, float deltaY) {
mRenderer.setOffsetDelta(deltaX, deltaY);
requestRender();
}
public void recycle() {
mListener = null;
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
}
public void setRotation(int rotation) {
mRotation = rotation;
}
private static final float MOVE_THRESHOLD = 1.0f;
private PointF mLastPoint;
private int mLastAction = MotionEvent.ACTION_DOWN;
private Listener mListener;
public interface Listener {
void onMove(float deltaX, float deltaY);
void onClick(float x, float y);
void onLayout(int width, int height);
}
public void setListener(Listener listener) {
mListener = listener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Matrix invertMatrix = mRenderer.getImageInvertMatrix();
if (invertMatrix == null) {
return true;
}
float[] point = new float[]{event.getX(), event.getY()};
invertMatrix.mapPoints(point);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastPoint = new PointF(point[0], point[1]);
mLastAction = MotionEvent.ACTION_DOWN;
break;
case MotionEvent.ACTION_MOVE:
if (mLastPoint != null) {
float deltaX = point[0] - mLastPoint.x,
deltaY = point[1] - mLastPoint.y;
if (mLastAction == MotionEvent.ACTION_MOVE || (Math.abs(deltaX) > MOVE_THRESHOLD
&& Math.abs(deltaY) > MOVE_THRESHOLD)) {
if (mListener != null) {
mListener.onMove(deltaX, deltaY);
}
mLastPoint.set(point[0], point[1]);
mLastAction = MotionEvent.ACTION_MOVE;
}
}
break;
case MotionEvent.ACTION_UP:
if (mLastAction != MotionEvent.ACTION_MOVE && mListener != null) {
mListener.onClick(point[0], point[1]);
}
mLastPoint = null;
mLastAction = MotionEvent.ACTION_UP;
break;
}
return true;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed && mListener != null) {
// if the loyout is changed by rotation not by reLayoutGLView,
// then save width and heigh of the view for caculating.
if (left == 0 && top == 0) {
mListener.onLayout(right - left, bottom - top);
}
}
}
}