package gl;
import gui.CustomGestureListener;
import java.util.ArrayList;
import java.util.List;
import listeners.eventManagerListeners.TouchMoveListener;
import system.EventManager;
import system.Setup;
import system.TouchEventInterface;
import util.Log;
import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.Surface;
import commands.Command;
/**
* This is the custom {@link GLSurfaceView} which is used to render the OpenGL
* content.
*
* @author Spobo
*
*/
public class CustomGLSurfaceView extends GLSurfaceView implements
TouchEventInterface {
private static final long TOUCH_INPUT_SLEEP_TIME = 20;
/**
* enables the opengl es debug output but reduces the frame-rate a lot!
*/
private static final boolean DEBUG_OUTPUT_ENABLED = false;
private static final String LOG_TAG = "CustomGLSurfaceView";
private float viewWidth = 320;
private float viewHeight = 320;
private List<TouchMoveListener> onTouchListeners;
private GestureDetector myGestureDetector;
private int startPosOnScreenWidth;
private int startPosOnScreenHeigth;
private boolean LANDSCAPE_MODE = true;
public CustomGLSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initGLSurfaceView(context);
}
public CustomGLSurfaceView(Context context) {
super(context);
initGLSurfaceView(context);
}
private void initGLSurfaceView(Context context) {
if (DEBUG_OUTPUT_ENABLED) {
// Turn on error-checking and logging
setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
}
int screenOrientation = Setup.getScreenOrientation();
if (screenOrientation == Surface.ROTATION_90
|| screenOrientation == Surface.ROTATION_270) {
LANDSCAPE_MODE = true;
} else {
LANDSCAPE_MODE = false;
}
this.setFocusableInTouchMode(true);
myGestureDetector = new GestureDetector(context,
new CustomGestureListener(this));
// Set 8888 pixel format because that's required for
// a translucent window:
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
// Use a surface format with an Alpha channel:
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
this.setZOrderMediaOverlay(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int[] startPosOnScreen = { 0, 0 };
this.getLocationInWindow(startPosOnScreen);
if (LANDSCAPE_MODE) {
viewHeight = w;
viewWidth = h;
startPosOnScreenWidth = startPosOnScreen[1];
startPosOnScreenHeigth = startPosOnScreen[0];
} else {
viewHeight = h;
viewWidth = w;
startPosOnScreenWidth = startPosOnScreen[0];
startPosOnScreenHeigth = startPosOnScreen[1];
}
Log.i(LOG_TAG, "OpenGL view size:");
Log.i(LOG_TAG, " > startPosOnScreenx=" + startPosOnScreenWidth);
Log.i(LOG_TAG, " > startPosOnScreeny=" + startPosOnScreenHeigth);
Log.i(LOG_TAG, " > viewHeight=" + viewHeight);
Log.i(LOG_TAG, " > viewWidth=" + viewWidth);
}
public void addOnTouchMoveListener(TouchMoveListener onTouchListener) {
if (onTouchListeners == null) {
this.onTouchListeners = new ArrayList<TouchMoveListener>();
}
this.onTouchListeners.add(onTouchListener);
}
@Override
public boolean dispatchTrackballEvent(MotionEvent event) {
if (EventManager.getInstance().onTrackballEvent(event)) {
return true;
}
return super.onTrackballEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
myGestureDetector.onTouchEvent(event);
requestFocus();
try {
// Sleep 20ms to not flood the thread
Thread.sleep(TOUCH_INPUT_SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (event.getAction() == MotionEvent.ACTION_UP) {
if (onTouchListeners != null) {
for (int i = 0; i < onTouchListeners.size(); i++) {
onTouchListeners.get(i).onReleaseTouchMove();
}
}
}
return true;
}
@Override
public Command getOnDoubleTabCommand() {
return null;
}
@Override
public Command getOnLongPressCommand() {
return null;
}
@Override
public Command getOnTabCommand() {
return null;
}
private float getOpenGlY(float y) {
// first invert y values because the 0,0 point of the opengl view is
// upper left and the 0,0 point of the sensor event ist lower left
if (LANDSCAPE_MODE) {
Log.i(LOG_TAG, "y=" + (viewWidth - y));
return viewWidth - y;
} else {
Log.i(LOG_TAG, "y=" + (viewHeight - y));
return viewHeight - y;
}
}
private float getOpenGlX(float x) {
Log.i(LOG_TAG, "x=" + x);
return x;
}
@Override
public void onDoubleTap(MotionEvent e) {
ObjectPicker.getInstance().setDoubleClickPosition(getOpenGlX(e.getX()),
getOpenGlY(e.getY()));
}
@Override
public void onLongPress(MotionEvent e) {
ObjectPicker.getInstance().setLongClickPosition(getOpenGlX(e.getX()),
getOpenGlY(e.getY()));
}
@Override
public void onSingleTab(MotionEvent e) {
ObjectPicker.getInstance().setClickPosition(getOpenGlX(e.getX()),
getOpenGlY(e.getY()));
}
@Override
public void setOnDoubleTabCommand(Command c) {
}
@Override
public void setOnLongPressCommand(Command c) {
}
@Override
public void setOnTabCommand(Command c) {
}
@Deprecated
public void addOnTouchMoveAction(TouchMoveListener action) {
Log.d("EventManager", "Adding onTouchMoveAction");
addOnTouchMoveListener(action);
}
@Override
public void onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
if (onTouchListeners != null) {
for (int i = 0; i < onTouchListeners.size(); i++) {
onTouchListeners.get(i).onTouchMove(e1, e2, distanceX,
distanceY);
}
}
}
}