1 package osg.AndroidExample;
2 
3 import android.app.Activity;
4 import android.app.AlertDialog;
5 import android.content.Context;
6 import android.content.DialogInterface;
7 import android.content.res.Resources;
8 import android.graphics.Color;
9 import android.graphics.PointF;
10 import android.os.Bundle;
11 import android.util.FloatMath;
12 import android.util.Log;
13 import android.view.KeyEvent;
14 import android.view.LayoutInflater;
15 import android.view.MenuItem;
16 import android.view.MotionEvent;
17 import android.view.View;
18 import android.view.Menu;
19 import android.view.MenuInflater;
20 import android.view.WindowManager;
21 import android.view.View.OnClickListener;
22 import android.view.inputmethod.InputMethodManager;
23 import android.widget.Button;
24 import android.widget.EditText;
25 import android.widget.TextView;
26 import android.widget.Toast;
27 import android.widget.ImageButton;
28 
29 import java.io.File;
30 
31 public class osgViewer extends Activity implements View.OnTouchListener, View.OnKeyListener, ColorPickerDialog.OnColorChangeListener {
32 	enum moveTypes { NONE , DRAG, MDRAG, ZOOM ,ACTUALIZE}
33 	enum navType { PRINCIPAL , SECONDARY }
34 	enum lightType { ON , OFF }
35 
36 	moveTypes mode=moveTypes.NONE;
37 	navType navMode = navType.PRINCIPAL;
38 	lightType lightMode = lightType.ON;
39 
40 	PointF oneFingerOrigin = new PointF(0,0);
41 	long timeOneFinger=0;
42 	PointF twoFingerOrigin = new PointF(0,0);
43 	long timeTwoFinger=0;
44 	float distanceOrigin;
45 
46 	int backgroundColor;
47 
48 	private static final String TAG = "OSG Activity";
49 	//Ui elements
50     EGLview mView;
51     Button uiCenterViewButton;
52     Button uiNavigationChangeButton;
53     ImageButton uiNavigationLeft;
54     ImageButton uiNavigationRight;
55     Button uiLightChangeButton;
56 
57     //Toasts
58     Toast msgUiNavPrincipal;
59     Toast msgUiNavSecondary;
60     Toast msgUiLightOn;
61     Toast msgUiLightOff;
62 
63     //Dialogs
64     AlertDialog removeLayerDialog;
65     AlertDialog loadLayerAddress;
66 
67     //Main Android Activity life cycle
onCreate(Bundle icicle)68     @Override protected void onCreate(Bundle icicle) {
69         super.onCreate(icicle);
70         setContentView(R.layout.ui_layout_gles);
71         //Obtain every Ui element
72 	        mView= (EGLview) findViewById(R.id.surfaceGLES);
73 		        mView.setOnTouchListener(this);
74 		        mView.setOnKeyListener(this);
75 
76 	        uiCenterViewButton = (Button) findViewById(R.id.uiButtonCenter);
77 	        	uiCenterViewButton.setOnClickListener(uiListenerCenterView);
78 	        uiNavigationChangeButton = (Button) findViewById(R.id.uiButtonChangeNavigation);
79 	        	uiNavigationChangeButton.setOnClickListener(uiListenerChangeNavigation);
80 	        uiLightChangeButton = (Button) findViewById(R.id.uiButtonLight);
81 	        	uiLightChangeButton.setOnClickListener(uiListenerChangeLight);
82 
83 	    //Creating Toasts
84        	msgUiNavPrincipal = Toast.makeText(getApplicationContext(), R.string.uiToastNavPrincipal, Toast.LENGTH_SHORT);
85        	msgUiNavSecondary = Toast.makeText(getApplicationContext(), R.string.uiToastNavSecond, Toast.LENGTH_SHORT);
86        	msgUiLightOn  = Toast.makeText(getApplicationContext(), R.string.uiToastLightOn, Toast.LENGTH_SHORT);
87        	msgUiLightOff  = Toast.makeText(getApplicationContext(), R.string.uiToastLightOff, Toast.LENGTH_SHORT);
88 
89        	//Creating Dialogs
90 
91        	LayoutInflater factory = LayoutInflater.from(getApplicationContext());
92 		final View textEntryView = factory.inflate(R.layout.dialog_text_entry, null);
93 		AlertDialog.Builder loadLayerDialogBuilder = new AlertDialog.Builder(this);
94 		loadLayerDialogBuilder.setIcon(R.drawable.web_browser);
95 		loadLayerDialogBuilder.setTitle(R.string.uiDialogTextAddress);
96 		loadLayerDialogBuilder.setView(textEntryView);
97 		loadLayerDialogBuilder.setPositiveButton(R.string.uiDialogOk, new DialogInterface.OnClickListener() {
98 
99 			@Override
100 			public void onClick(DialogInterface dialog, int which) {
101 				// TODO Auto-generated method stub
102 				EditText address;
103 				address = (EditText) textEntryView.findViewById(R.id.uiEditTextInput);
104 				osgNativeLib.loadObject(address.getText().toString());
105 			}
106 		});
107 		loadLayerDialogBuilder.setNegativeButton(R.string.uiDialogCancel, new DialogInterface.OnClickListener() {
108 
109 			@Override
110 			public void onClick(DialogInterface dialog, int which) {
111 				// TODO Auto-generated method stub
112 
113 			}
114 		});
115 
116 		loadLayerAddress = loadLayerDialogBuilder.create();
117     }
onPause()118     @Override protected void onPause() {
119         super.onPause();
120         mView.onPause();
121     }
onResume()122     @Override protected void onResume() {
123         super.onResume();
124         mView.onResume();
125     }
126 
127     //Main view event processing
128     @Override
onKey(View v, int keyCode, KeyEvent event)129 	public boolean onKey(View v, int keyCode, KeyEvent event) {
130 
131 		return true;
132 	}
133     @Override
onKeyDown(int keyCode, KeyEvent event)134     public boolean onKeyDown(int keyCode, KeyEvent event){
135     	//DO NOTHING this will render useless every menu key except Home
136     	int keyChar= event.getUnicodeChar();
137     	osgNativeLib.keyboardDown(keyChar);
138     	return true;
139     }
140     @Override
onKeyUp(int keyCode, KeyEvent event)141     public boolean onKeyUp(int keyCode, KeyEvent event){
142     	switch (keyCode){
143     	case KeyEvent.KEYCODE_BACK:
144     		super.onDestroy();
145     		this.finish();
146     		break;
147     	case KeyEvent.KEYCODE_SEARCH:
148     		break;
149     	case KeyEvent.KEYCODE_MENU:
150     		this.openOptionsMenu();
151     		break;
152     	default:
153     		int keyChar= event.getUnicodeChar();
154     		osgNativeLib.keyboardUp(keyChar);
155     	}
156 
157     	return true;
158     }
159     @Override
onTouch(View v, MotionEvent event)160     public boolean onTouch(View v, MotionEvent event) {
161 
162     	//dumpEvent(event);
163 
164     	long time_arrival = event.getEventTime();
165     	int n_points = event.getPointerCount();
166     	int action = event.getAction() & MotionEvent.ACTION_MASK;
167 
168     	switch(n_points){
169     	case 1:
170     		switch(action){
171     		case MotionEvent.ACTION_DOWN:
172 	    		mode = moveTypes.DRAG;
173 
174 	    		osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
175 	    		if(navMode==navType.PRINCIPAL)
176 	    			osgNativeLib.mouseButtonPressEvent(event.getX(0), event.getY(0), 2);
177 	    		else
178 	    			osgNativeLib.mouseButtonPressEvent(event.getX(0), event.getY(0), 1);
179 
180 	    		oneFingerOrigin.x=event.getX(0);
181 	    		oneFingerOrigin.y=event.getY(0);
182     			break;
183     		case MotionEvent.ACTION_CANCEL:
184     			switch(mode){
185     			case DRAG:
186     				osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
187     				if(navMode==navType.PRINCIPAL)
188     					osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
189     				else
190     					osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
191     				break;
192     			default :
193     				Log.e(TAG,"There has been an anomaly in touch input 1point/action");
194     			}
195     			mode = moveTypes.NONE;
196     			break;
197     		case MotionEvent.ACTION_MOVE:
198 
199     			osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
200 
201     			oneFingerOrigin.x=event.getX(0);
202 	    		oneFingerOrigin.y=event.getY(0);
203 
204     			break;
205     		case MotionEvent.ACTION_UP:
206     			switch(mode){
207     			case DRAG:
208     				if(navMode==navType.PRINCIPAL)
209     					osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
210     				else
211     					osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
212     				break;
213     			default :
214     				Log.e(TAG,"There has been an anomaly in touch input 1 point/action");
215     			}
216     			mode = moveTypes.NONE;
217     			break;
218     		default :
219     			Log.e(TAG,"1 point Action not captured");
220     		}
221     		break;
222     	case 2:
223     		switch (action){
224     		case MotionEvent.ACTION_POINTER_DOWN:
225     			//Free previous Action
226     			switch(mode){
227     			case DRAG:
228     				if(navMode==navType.PRINCIPAL)
229     					osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
230     				else
231     					osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
232     				break;
233     			}
234     			mode = moveTypes.ZOOM;
235     			distanceOrigin = sqrDistance(event);
236     			twoFingerOrigin.x=event.getX(1);
237     			twoFingerOrigin.y=event.getY(1);
238     			oneFingerOrigin.x=event.getX(0);
239 	    		oneFingerOrigin.y=event.getY(0);
240 
241     			osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
242     			osgNativeLib.mouseButtonPressEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
243     			osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
244 
245     		case MotionEvent.ACTION_MOVE:
246     			float distance = sqrDistance(event);
247     			float result = distance-distanceOrigin;
248     			distanceOrigin=distance;
249 
250     			if(result>1||result<-1){
251     	    		oneFingerOrigin.y=oneFingerOrigin.y+result;
252     				osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
253     			}
254 
255     			break;
256     		case MotionEvent.ACTION_POINTER_UP:
257     			mode =moveTypes.NONE;
258     			osgNativeLib.mouseButtonReleaseEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
259     			break;
260     		case MotionEvent.ACTION_UP:
261     			mode =moveTypes.NONE;
262     			osgNativeLib.mouseButtonReleaseEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
263     			break;
264     		default :
265     			Log.e(TAG,"2 point Action not captured");
266     		}
267     		break;
268     	}
269 
270 		return true;
271 	}
272 
273     //Ui Listeners
274     OnClickListener uiListenerCenterView = new OnClickListener() {
275         public void onClick(View v) {
276         	//Log.d(TAG, "Center View");
277         	osgNativeLib.keyboardDown(32);
278         	osgNativeLib.keyboardUp(32);
279         }
280     };
281     OnClickListener uiListenerChangeNavigation = new OnClickListener() {
282         public void onClick(View v) {
283         	//Log.d(TAG, "Change Navigation");
284         	if(navMode==navType.PRINCIPAL){
285         		msgUiNavSecondary.show();
286         		navMode=navType.SECONDARY;
287         	}
288         	else{
289         		msgUiNavPrincipal.show();
290         		navMode=navType.PRINCIPAL;
291         	}
292         }
293     };
294     OnClickListener uiListenerChangeLight = new OnClickListener() {
295         public void onClick(View v) {
296         	//Log.d(TAG, "Change Light");
297         	if(lightMode==lightType.ON){
298         		msgUiLightOff.show();
299         		lightMode=lightType.OFF;
300         		osgNativeLib.keyboardDown(108);
301             	osgNativeLib.keyboardUp(108);
302         	}
303         	else{
304         		msgUiLightOn.show();
305         		lightMode=lightType.ON;
306         		osgNativeLib.keyboardDown(108);
307             	osgNativeLib.keyboardUp(108);
308         	}
309         }
310     };
311 
312     //Menu
313 
314     @Override
colorChange(int color)315 	public void colorChange(int color) {
316 		// TODO Auto-generated method stub
317 		// Do nothing
318     	int red = Color.red(color);
319     	int green = Color.green(color);
320     	int blue = Color.blue(color);
321     	//Log.d(TAG,"BACK color "+red+" "+green+" "+blue+" ");
322     	osgNativeLib.setClearColor(red,green,blue);
323 	}
324 
325     //Android Life Cycle Menu
326     @Override
onCreateOptionsMenu(Menu menu)327     public boolean onCreateOptionsMenu(Menu menu) {
328         MenuInflater inflater = getMenuInflater();
329         inflater.inflate(R.menu.appmenu, menu);
330         return super.onCreateOptionsMenu(menu);
331     }
332     @Override
onOptionsItemSelected(MenuItem item)333     public boolean onOptionsItemSelected(MenuItem item) {
334         // Handle item selection
335         switch (item.getItemId()) {
336         case R.id.menuLoadObject:
337         	Log.d(TAG,"Load Object");
338         	loadLayerAddress.show();
339             return true;
340         case R.id.menuCleanScene:
341         	Log.d(TAG,"Clean Scene");
342         	osgNativeLib.clearContents();
343             return true;
344         case R.id.menuDeleteObject:
345         	Log.d(TAG,"Delete a object");
346         	String vNames[] = osgNativeLib.getObjectNames();
347 
348         	//Remove Layer Dialog
349     		AlertDialog.Builder removeLayerDialogBuilder = new AlertDialog.Builder(this);
350     		removeLayerDialogBuilder.setTitle(R.string.uiDialogTextChoseRemove);
351     		removeLayerDialogBuilder.setItems(vNames, new DialogInterface.OnClickListener() {
352 
353     			@Override
354     			public void onClick(DialogInterface dialog, int witch) {
355     				// TODO Auto-generated method stub
356     				osgNativeLib.unLoadObject(witch);
357     			}
358     		});
359     		removeLayerDialog = removeLayerDialogBuilder.create();
360 
361     		if(vNames.length > 0)
362     			removeLayerDialog.show();
363 
364             return true;
365         case R.id.menuChangeBackground:
366         	Log.d(TAG,"Change background color");
367         	int[] test = new int [3];
368         	test = osgNativeLib.getClearColor();
369         	backgroundColor = Color.rgb(test[0], test[1], test[2]);
370 
371         	ColorPickerDialog colorDialog;
372         	new ColorPickerDialog(this, this, backgroundColor).show();
373             return true;
374         case R.id.menuShowKeyboard:
375         	Log.d(TAG,"Keyboard");
376         	InputMethodManager mgr= (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
377     		mgr.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
378             return true;
379         default:
380             return super.onOptionsItemSelected(item);
381         }
382     }
383 
384     //Utilities
385     /** Show an event in the LogCat view, for debugging */
dumpEvent(MotionEvent event)386     private void dumpEvent(MotionEvent event) {
387        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
388              "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
389        StringBuilder sb = new StringBuilder();
390        int action = event.getAction();
391        int actionCode = action & MotionEvent.ACTION_MASK;
392        sb.append("event ACTION_").append(names[actionCode]);
393        if (actionCode == MotionEvent.ACTION_POINTER_DOWN
394              || actionCode == MotionEvent.ACTION_POINTER_UP) {
395           sb.append("(pid ").append(
396                 action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
397           sb.append(")");
398        }
399        sb.append("[");
400        for (int i = 0; i < event.getPointerCount(); i++) {
401           sb.append("#").append(i);
402           sb.append("(pid ").append(event.getPointerId(i));
403           sb.append(")=").append((int) event.getX(i));
404           sb.append(",").append((int) event.getY(i));
405           if (i + 1 < event.getPointerCount())
406              sb.append(";");
407        }
408        sb.append("]");
409        //Log.d(TAG, sb.toString());
410     }
sqrDistance(MotionEvent event)411     private float sqrDistance(MotionEvent event) {
412         float x = event.getX(0) - event.getX(1);
413         float y = event.getY(0) - event.getY(1);
414         return (float)(Math.sqrt(x * x + y * y));
415      }
416 
417 }