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 }