package com.theta.glview; import android.content.Context; import android.opengl.GLSurfaceView; import android.os.Handler; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.widget.Scroller; import com.theta.model.Constants; import com.theta.model.Photo; import com.theta.model.RotateInertia; /** * View class for photo display */ public class GLPhotoView extends GLSurfaceView { private static final int ANIMATION_INTERVAL = 10; private GLRenderer mRenderer = null; private GestureDetector mGestureDetector; private ScaleGestureDetector mScaleGestureDetector; private Scroller mScroller = null; private float mPrevX, mPrevY; private RotateInertia mRotateInertia = RotateInertia.INERTIA_0; /** * Constructor * @param context Context */ public GLPhotoView(Context context) { this(context, null); } /** * Constructor * @param context Context * @param attrs Argument for resource */ public GLPhotoView(Context context, AttributeSet attrs) { super(context, attrs); initialize(context); } /** * onTouchEvent Event listener * @param event Event object * @return Process continuation judgment value */ @Override public boolean onTouchEvent(MotionEvent event) { boolean ret = false; mScaleGestureDetector.onTouchEvent(event); if (!mScaleGestureDetector.isInProgress()) { ret = mGestureDetector.onTouchEvent(event); if (!ret) { super.onTouchEvent(event); } } return ret; } private void initialize(Context context) { setEGLContextClientVersion(2); mRenderer = new GLRenderer(); setRenderer(mRenderer); setLongClickable(true); mGestureDetector = new GestureDetector(context, new GestureDetector.OnGestureListener() { private final int SWIPE_MAX_OF_PATH_X = 100; private final int SWIPE_MAX_OF_PATH_Y = 100; final Handler handler = new Handler(); @Override public boolean onSingleTapUp(MotionEvent e) { return false; } @Override public void onShowPress(MotionEvent e) { return; } @Override public void onLongPress(MotionEvent e) { return; } @Override public boolean onDown(MotionEvent e) { if (null != mScroller && !mScroller.isFinished()) { mScroller.abortAnimation(); handler.removeCallbacksAndMessages(null); } return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { boolean ret = false; if (null != mScroller && !mScroller.isFinished()) { mScroller.abortAnimation(); } if ((Math.abs(distanceX) > SWIPE_MAX_OF_PATH_X ) || (Math.abs(distanceY) > SWIPE_MAX_OF_PATH_Y )) { ret = false; } else { float diffX = distanceX / Constants.ON_SCROLL_DIVIDER_X; float diffY = distanceY / Constants.ON_SCROLL_DIVIDER_Y; if (Math.abs(diffX) < Constants.THRESHOLD_SCROLL_X) { diffX = 0.0f; } if (Math.abs(diffY) < Constants.THRESHOLD_SCROLL_Y) { diffY = 0.0f; } if (null != mRenderer) { mRenderer.rotate(diffX, -diffY); } ret = true; } return ret; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { mScroller.fling((int)e2.getX(), (int)e2.getY(), (int)velocityX, (int)velocityY, 0, getWidth(), 0, getHeight()); mPrevX = e2.getX(); mPrevY = e2.getY(); handler.post(new Runnable() { @Override public void run() { if (mRotateInertia == RotateInertia.INERTIA_0) { // do nothing } else { mScroller.computeScrollOffset(); float diffX = mScroller.getCurrX() - mPrevX; float diffY = mScroller.getCurrY() - mPrevY; mPrevX = mScroller.getCurrX(); mPrevY = mScroller.getCurrY(); if (mRotateInertia == RotateInertia.INERTIA_50) { diffX = diffX / Constants.ON_FLING_DIVIDER_X_FOR_INERTIA_50; diffY = diffY / Constants.ON_FLING_DIVIDER_Y_FOR_INERTIA_50; } else { diffX = diffX / Constants.ON_FLING_DIVIDER_X_FOR_INERTIA_100; diffY = diffY / Constants.ON_FLING_DIVIDER_Y_FOR_INERTIA_100; } mRenderer.rotate((float) -diffX, (float) diffY); if (!mScroller.isFinished()) { handler.postDelayed(this, ANIMATION_INTERVAL); } } } }); return true; } }); mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() { @Override public boolean onScale(ScaleGestureDetector detector) { float scale = detector.getScaleFactor(); if (null != mRenderer) { mRenderer.scale(scale); } return true; } }); mScroller = new Scroller(context); return; } /** * Texture setting method * @param thumbnail Photo object for texture */ public void setTexture(Photo thumbnail) { mRenderer.setTexture(thumbnail); return; } /** * Inertia setting method * @param mRotateInertia Setting inertia value */ public void setmRotateInertia(RotateInertia mRotateInertia) { this.mRotateInertia = mRotateInertia; return; } }