0025195: Samples - add Java sample for Android 4.x
[occt.git] / samples / java / jniviewer / src / com / opencascade / jnisample / OcctJniActivity.java
1 // Copyright (c) 2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 package com.opencascade.jnisample;
15
16 import java.io.File;
17 import java.io.FileOutputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.util.Arrays;
22 import java.util.List;
23
24 import android.app.Activity;
25 import android.content.Context;
26
27 import android.content.Intent;
28 import android.content.res.AssetManager;
29 import android.content.res.Configuration;
30 import android.content.res.Resources;
31 import android.graphics.Point;
32 import android.graphics.drawable.Drawable;
33 import android.net.Uri;
34 import android.os.Bundle;
35 import android.os.Environment;
36
37 import android.text.Html;
38 import android.text.Html.ImageGetter;
39 import android.text.Spanned;
40 import android.util.TypedValue;
41 import android.view.Display;
42 import android.view.Gravity;
43 import android.view.MotionEvent;
44 import android.view.View;
45 import android.view.View.OnClickListener;
46 import android.view.ViewGroup;
47 import android.widget.ImageButton;
48 import android.widget.LinearLayout;
49 import android.view.ViewGroup.LayoutParams;
50 import android.widget.TextView;
51 import android.widget.Toast;
52
53 //! Main activity
54 public class OcctJniActivity extends Activity implements OnClickListener
55 {
56
57   //! Auxiliary method to print temporary info messages
58   public static void printShortInfo (Activity     theActivity,
59                                      CharSequence theInfo)
60   {
61     Context aCtx   = theActivity.getApplicationContext();
62     Toast   aToast = Toast.makeText (aCtx, theInfo, Toast.LENGTH_LONG);
63     aToast.show();
64   }
65
66   //! Load single native library
67   private static boolean loadLibVerbose (String        theLibName,
68                                          StringBuilder theLoadedInfo,
69                                          StringBuilder theFailedInfo)
70   {
71     try
72     {
73       System.loadLibrary (theLibName);
74       theLoadedInfo.append ("Info:  native library \"");
75       theLoadedInfo.append (theLibName);
76       theLoadedInfo.append ("\" has been loaded\n");
77       return true;
78     }
79     catch (java.lang.UnsatisfiedLinkError theError)
80     {
81       theFailedInfo.append ("Error: native library \"");
82       theFailedInfo.append (theLibName);
83       theFailedInfo.append ("\" is unavailable:\n  " + theError.getMessage());
84       return false;
85     }
86     catch (SecurityException theError)
87     {
88       theFailedInfo.append ("Error: native library \"");
89       theFailedInfo.append (theLibName);
90       theFailedInfo.append ("\" can not be loaded for security reasons:\n  " + theError.getMessage());
91       return false;
92     }
93   }
94
95   public static boolean wasNativesLoadCalled = false;
96   public static boolean areNativeLoaded      = false;
97   public static String  nativeLoaded         = "";
98   public static String  nativeFailed         = "";
99
100   //! Auxiliary method to load native libraries
101   public boolean loadNatives()
102   {
103     if (wasNativesLoadCalled)
104     {
105       return areNativeLoaded;
106     }
107     wasNativesLoadCalled = true;
108     StringBuilder aLoaded = new StringBuilder();
109     StringBuilder aFailed = new StringBuilder();
110
111     // copy OCCT resources
112     String aResFolder = getFilesDir().getAbsolutePath();
113     copyAssetFolder (getAssets(), "Shaders",   aResFolder + "/Shaders");
114     copyAssetFolder (getAssets(), "SHMessage", aResFolder + "/SHMessage");
115     copyAssetFolder (getAssets(), "XSMessage", aResFolder + "/XSMessage");
116     copyAssetFolder (getAssets(), "TObj",      aResFolder + "/TObj");
117     copyAssetFolder (getAssets(), "UnitsAPI",  aResFolder + "/UnitsAPI");
118
119     // C++ runtime
120     loadLibVerbose ("gnustl_shared", aLoaded, aFailed);
121
122     // 3rd-parties
123     loadLibVerbose ("freetype",  aLoaded, aFailed);
124     loadLibVerbose ("freeimage", aLoaded, aFailed);
125
126     if (// OCCT modeling
127         !loadLibVerbose ("TKernel",      aLoaded, aFailed)
128      || !loadLibVerbose ("TKMath",       aLoaded, aFailed)
129      || !loadLibVerbose ("TKG2d",        aLoaded, aFailed)
130      || !loadLibVerbose ("TKG3d",        aLoaded, aFailed)
131      || !loadLibVerbose ("TKGeomBase",   aLoaded, aFailed)
132      || !loadLibVerbose ("TKBRep",       aLoaded, aFailed)
133      || !loadLibVerbose ("TKGeomAlgo",   aLoaded, aFailed)
134      || !loadLibVerbose ("TKTopAlgo",    aLoaded, aFailed)
135      || !loadLibVerbose ("TKShHealing",  aLoaded, aFailed)
136      || !loadLibVerbose ("TKMesh",       aLoaded, aFailed)
137         // exchange
138      || !loadLibVerbose ("TKPrim",       aLoaded, aFailed)
139      || !loadLibVerbose ("TKBO",         aLoaded, aFailed)
140      || !loadLibVerbose ("TKBool",       aLoaded, aFailed)
141      || !loadLibVerbose ("TKFillet",     aLoaded, aFailed)
142      || !loadLibVerbose ("TKOffset",     aLoaded, aFailed)
143      || !loadLibVerbose ("TKXSBase",     aLoaded, aFailed)
144      || !loadLibVerbose ("TKIGES",       aLoaded, aFailed)
145      || !loadLibVerbose ("TKSTEPBase",   aLoaded, aFailed)
146      || !loadLibVerbose ("TKSTEPAttr",   aLoaded, aFailed)
147      || !loadLibVerbose ("TKSTEP209",    aLoaded, aFailed)
148      || !loadLibVerbose ("TKSTEP",       aLoaded, aFailed)
149         // OCCT Visualization
150      || !loadLibVerbose ("TKService",    aLoaded, aFailed)
151      || !loadLibVerbose ("TKHLR",        aLoaded, aFailed)
152      || !loadLibVerbose ("TKV3d",        aLoaded, aFailed)
153      || !loadLibVerbose ("TKOpenGl",     aLoaded, aFailed)
154         // application code
155      || !loadLibVerbose ("TKJniSample",  aLoaded, aFailed))
156     {
157       nativeLoaded = aLoaded.toString();
158       nativeFailed = aFailed.toString();
159       areNativeLoaded = false;
160       //exitWithError (theActivity, "Broken apk?\n" + theFailedInfo);
161       return false;
162     }
163     nativeLoaded = aLoaded.toString();
164     areNativeLoaded = true;
165     return true;
166   }
167
168   //! Create activity
169   @Override protected void onCreate (Bundle theBundle)
170   {
171     super.onCreate (theBundle);
172
173     boolean isLoaded = loadNatives();
174     if (!isLoaded)
175     {
176       printShortInfo (this, nativeFailed);
177       OcctJniLogger.postMessage (nativeLoaded + "\n" + nativeFailed);
178     }
179
180     setContentView (R.layout.activity_main);
181     
182     myOcctView        = (OcctJniView )findViewById (R.id.custom_view);
183     myMessageTextView = (TextView    )findViewById (R.id.message_view);
184     OcctJniLogger.setTextView (myMessageTextView);
185
186     createViewAndButtons (Configuration.ORIENTATION_LANDSCAPE);
187
188     myButtonPreferSize = defineButtonSize ((LinearLayout )findViewById (R.id.panel_menu));
189     ImageButton aScrollBtn = (ImageButton )findViewById (R.id.scroll_btn);
190     aScrollBtn.setY (myButtonPreferSize);
191     aScrollBtn.setOnTouchListener (new View.OnTouchListener()
192     {
193       @Override
194       public boolean onTouch (View theView, MotionEvent theEvent)
195       {
196         return onScrollBtnTouch (theView, theEvent);
197       }
198     });
199
200     onConfigurationChanged (getResources().getConfiguration());
201
202     Intent anIntent = getIntent();
203     Uri    aDataUrl  = anIntent != null ? anIntent.getData() : null;
204     String aDataPath = aDataUrl != null ? aDataUrl.getPath() : "";
205     myOcctView.open (aDataPath);
206     myLastPath = aDataPath;
207   }
208
209   //! Handle scroll events
210   private boolean onScrollBtnTouch (View        theView,
211                                     MotionEvent theEvent)
212   {
213     switch (theEvent.getAction())
214     {
215       case MotionEvent.ACTION_DOWN:
216       {
217         LinearLayout aPanelMenu = (LinearLayout )findViewById (R.id.panel_menu);
218         boolean isLandscape = (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
219         if (aPanelMenu.getVisibility() == View.VISIBLE)
220         {
221           aPanelMenu.setVisibility (View.GONE);
222           if (!isLandscape)
223           {
224             ((ImageButton )theView).setImageResource (R.drawable.open_p);
225             theView.setY (0);
226           }
227           else
228           {
229             ((ImageButton )theView).setImageResource (R.drawable.open_l);
230             theView.setX (0);
231           }
232         }
233         else
234         {
235           aPanelMenu.setVisibility (View.VISIBLE);
236           if (!isLandscape)
237           {
238             ((ImageButton )theView).setImageResource (R.drawable.close_p);
239             theView.setY (myButtonPreferSize);
240           }
241           else
242           {
243             ((ImageButton )theView).setImageResource (R.drawable.close_l);
244             theView.setX (myButtonPreferSize);
245           }
246         }
247         break;
248       }
249     }
250     return false;
251   }
252
253   //! Initialize views and buttons
254   private void createViewAndButtons (int theOrientation)
255   {
256     // open button
257     ImageButton anOpenButton = (ImageButton )findViewById (R.id.open);
258     anOpenButton.setOnClickListener (this);
259
260     // fit all
261     ImageButton aFitAllButton = (ImageButton )findViewById (R.id.fit);
262     aFitAllButton.setOnClickListener (this);
263     aFitAllButton.setOnTouchListener (new View.OnTouchListener()
264     {
265       @Override
266       public boolean onTouch (View theView, MotionEvent theEvent)
267       {
268         return onTouchButton (theView, theEvent);
269       }
270     });
271     
272     // message
273     ImageButton aMessageButton = (ImageButton )findViewById (R.id.message);
274     aMessageButton.setOnClickListener (this);
275
276     // info
277     ImageButton anInfoButton = (ImageButton )findViewById (R.id.info);
278     anInfoButton.setOnClickListener (this);
279     
280     // font for text view
281     TextView anInfoView = (TextView )findViewById (R.id.info_view);
282     anInfoView.setTextSize (TypedValue.COMPLEX_UNIT_SP, 18);
283
284     // add submenu buttons
285     createSubmenuBtn (R.id.view, R.id.view_group,
286                       Arrays.asList (R.id.proj_front, R.id.proj_top,    R.id.proj_left,
287                                      R.id.proj_back,  R.id.proj_bottom, R.id.proj_right),
288                       Arrays.asList (R.drawable.proj_front, R.drawable.proj_top,    R.drawable.proj_left,
289                                      R.drawable.proj_back,  R.drawable.proj_bottom, R.drawable.proj_right),
290                       4);
291   }
292
293   @Override protected void onNewIntent (Intent theIntent)
294   {
295     super.onNewIntent (theIntent);
296     setIntent (theIntent);
297   }
298
299   @Override protected void onDestroy()
300   {
301     super.onDestroy();
302     OcctJniLogger.setTextView (null);
303   }
304
305   @Override protected void onPause()
306   {
307     super.onPause();
308     myOcctView.onPause();
309   }
310
311   @Override protected void onResume()
312   {
313     super.onResume();
314     myOcctView.onResume();
315
316     Intent anIntent = getIntent();
317     Uri    aDataUrl  = anIntent != null ? anIntent.getData() : null;
318     String aDataPath = aDataUrl != null ? aDataUrl.getPath() : "";
319     if (!aDataPath.equals (myLastPath))
320     {
321       myOcctView.open (aDataPath);
322       myLastPath = aDataPath;
323     }
324   }
325
326   //! Copy folder from assets
327   private boolean copyAssetFolder (AssetManager theAssetMgr,
328                                    String       theAssetFolder,
329                                    String       theFolderPathTo)
330   {
331     try
332     {
333       String[] aFiles  = theAssetMgr.list (theAssetFolder);
334       File     aFolder = new File (theFolderPathTo);
335       aFolder.mkdirs();
336       boolean isOk = true;
337       for (String aFileIter : aFiles)
338       {
339         if (aFileIter.contains ("."))
340         {
341           isOk &= copyAsset (theAssetMgr,
342                              theAssetFolder  + "/" + aFileIter,
343                              theFolderPathTo + "/" + aFileIter);
344         }
345         else
346         {
347           isOk &= copyAssetFolder (theAssetMgr,
348                                    theAssetFolder  + "/" + aFileIter,
349                                    theFolderPathTo + "/" + aFileIter);
350         }
351       }
352       return isOk;
353     }
354     catch (Exception theError)
355     {
356       theError.printStackTrace();
357       return false;
358     }
359   }
360
361   //! Copy single file from assets
362   private boolean copyAsset (AssetManager theAssetMgr,
363                              String       thePathFrom,
364                              String       thePathTo)
365   {
366     try
367     {
368       InputStream aStreamIn = theAssetMgr.open (thePathFrom);
369       File aFileTo = new File (thePathTo);
370       aFileTo.createNewFile();
371       OutputStream aStreamOut = new FileOutputStream (thePathTo);
372       copyStreamContent (aStreamIn, aStreamOut);
373       aStreamIn.close();
374       aStreamIn = null;
375       aStreamOut.flush();
376       aStreamOut.close();
377       aStreamOut = null;
378       return true;
379     }
380     catch (Exception theError)
381     {
382       theError.printStackTrace();
383       return false;
384     }
385   }
386
387   //! Copy single file
388   private static void copyStreamContent (InputStream  theIn,
389                                          OutputStream theOut) throws IOException
390   {
391     byte[] aBuffer = new byte[1024];
392     int aNbReadBytes = 0;
393     while ((aNbReadBytes = theIn.read (aBuffer)) != -1)
394     {
395       theOut.write (aBuffer, 0, aNbReadBytes);
396     }
397   }
398   
399   //! Show/hide text view
400   private void switchTextView (TextView    theTextView,
401                                ImageButton theClickedBtn,
402                                boolean     theToSwitchOn)
403   {
404     if (theTextView != null
405      && theTextView.getVisibility() == View.GONE
406      && theToSwitchOn)
407     {
408       theTextView.setVisibility (View.VISIBLE);
409       theClickedBtn.setBackgroundColor (getResources().getColor(R.color.pressedBtnColor));
410       setTextViewPosition (theTextView);
411     }
412     else
413     {
414       theTextView.setVisibility (View.GONE);
415       theClickedBtn.setBackgroundColor (getResources().getColor (R.color.btnColor));
416     }
417   }
418
419   //! Setup text view position
420   private void setTextViewPosition (TextView theTextView)
421   {
422     if (theTextView.getVisibility() != View.VISIBLE)
423     {
424       return;
425     }
426
427     if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
428     {
429       theTextView.setX (myButtonPreferSize);
430       theTextView.setY (0);
431     }
432     else
433     {
434       theTextView.setX (0);
435       theTextView.setY (myButtonPreferSize);
436     }
437   }
438
439   @Override
440   public void onClick (View theButton)
441   {
442     ImageButton aClickedBtn = (ImageButton )theButton;
443     switch (aClickedBtn.getId())
444     {
445       case R.id.message:
446       {
447         switchTextView ((TextView    )findViewById (R.id.info_view),
448                         (ImageButton )findViewById (R.id.info), false);
449         switchTextView (myMessageTextView, aClickedBtn, true);
450         return;
451       }
452       case R.id.info:
453       {
454         String aText = getString (R.string.info_html);
455         aText = String.format (aText, cppOcctMajorVersion(), cppOcctMinorVersion(), cppOcctMicroVersion());
456         Spanned aSpanned = Html.fromHtml (aText, new ImageGetter()
457         {
458           @Override
459           public Drawable getDrawable (String theSource)
460           {
461             Resources aResources = getResources();
462             int anId = aResources.getIdentifier (theSource, "drawable", getPackageName());
463             Drawable aRes = aResources.getDrawable (anId);
464             aRes.setBounds (0, 0, aRes.getIntrinsicWidth(), aRes.getIntrinsicHeight());
465             return aRes;
466           }
467         }, null);
468
469         TextView anInfoView = (TextView )findViewById (R.id.info_view);
470         anInfoView.setText (aSpanned);
471         switchTextView (myMessageTextView, (ImageButton ) findViewById (R.id.message), false);
472         switchTextView (anInfoView,        aClickedBtn,                                true);
473         return;
474       }
475       case R.id.fit:
476       {
477         myOcctView.fitAll();
478         return;
479       }
480       case R.id.proj_front:
481       {
482         myOcctView.setProj (OcctJniRenderer.TypeOfOrientation.Xpos);
483         return;
484       }
485       case R.id.proj_left:
486       {
487         myOcctView.setProj (OcctJniRenderer.TypeOfOrientation.Yneg);
488         return;
489       }
490       case R.id.proj_top:
491       {
492         myOcctView.setProj (OcctJniRenderer.TypeOfOrientation.Zpos);
493         return;
494       }
495       case R.id.proj_back:
496       {
497         myOcctView.setProj (OcctJniRenderer.TypeOfOrientation.Xneg);
498         return;
499       }
500       case R.id.proj_right:
501       {
502         myOcctView.setProj (OcctJniRenderer.TypeOfOrientation.Ypos);
503         return;
504       }
505       case R.id.proj_bottom:
506       {
507         myOcctView.setProj (OcctJniRenderer.TypeOfOrientation.Zneg);
508         return;
509       }
510       case R.id.open:
511       {
512         File aPath = Environment.getExternalStorageDirectory();
513         aClickedBtn.setBackgroundColor (getResources().getColor(R.color.pressedBtnColor));
514         if (myFileOpenDialog == null)
515         {
516           myFileOpenDialog = new OcctJniFileDialog (this, aPath);
517           myFileOpenDialog.setFileEndsWith (".brep");
518           myFileOpenDialog.setFileEndsWith (".rle");
519           myFileOpenDialog.setFileEndsWith (".iges");
520           myFileOpenDialog.setFileEndsWith (".igs");
521           myFileOpenDialog.setFileEndsWith (".step");
522           myFileOpenDialog.setFileEndsWith (".stp");
523           myFileOpenDialog.addFileListener (new OcctJniFileDialog.FileSelectedListener()
524           {
525             public void fileSelected (File theFile)
526             {
527               if (theFile != null && myOcctView != null)
528               {
529                 myOcctView.open (theFile.getPath());
530               }
531             }
532           });
533           myFileOpenDialog.addDialogDismissedListener (new OcctJniFileDialog.DialogDismissedListener()
534           {
535             @Override
536             public void dialogDismissed()
537             {
538               ImageButton openButton = (ImageButton )findViewById (R.id.open);
539               openButton.setBackgroundColor (getResources().getColor(R.color.btnColor));
540             }
541           });
542         }
543         myFileOpenDialog.showDialog();
544         return;
545       }
546     }
547   }
548
549   private void createSubmenuBtn (int     theParentBtnId,
550                                  int     theParentLayoutId,
551                                  final List<Integer> theNewButtonIds,
552                                  final List<Integer> theNewButtonImageIds,
553                                  int     thePosition)
554   {
555     int aPosInList = 0;
556     final ImageButton aParentBtn = (ImageButton )findViewById (theParentBtnId);
557
558     ViewGroup.LayoutParams aParams = null;
559     LinearLayout parentLayout = (LinearLayout ) findViewById (theParentLayoutId);
560     for (Integer newButtonId : theNewButtonIds)
561     {
562       ImageButton aNewButton = (ImageButton )findViewById (newButtonId);
563       if (aNewButton == null)
564       {
565         aNewButton = (ImageButton )new ImageButton (this);
566         aNewButton.setId (newButtonId);
567         aNewButton.setImageResource (theNewButtonImageIds.get (aPosInList));
568         aNewButton.setLayoutParams (aParams);
569         parentLayout.addView (aNewButton);
570       }
571
572       aNewButton.setOnClickListener (this);
573       aNewButton.setVisibility (View.GONE);
574
575       aNewButton.setOnTouchListener (new View.OnTouchListener()
576       {
577         @Override
578         public boolean onTouch (View theView, MotionEvent theEvent)
579         {
580           return onTouchButton (theView, theEvent);
581         }
582       });
583       ++aPosInList;
584     }
585
586     if (aParentBtn != null)
587     {
588       aParentBtn.setOnTouchListener (null);
589       aParentBtn.setOnTouchListener (new View.OnTouchListener()
590       {
591         @Override
592         public boolean onTouch (View theView, MotionEvent theEvent)
593         {
594           if (theEvent.getAction () == MotionEvent.ACTION_DOWN)
595           {
596             Boolean isVisible = false;
597             for (Integer aNewButtonId : theNewButtonIds)
598             {
599               ImageButton anBtn = (ImageButton )findViewById (aNewButtonId);
600               if (anBtn != null)
601               {
602                 if (anBtn.getVisibility() == View.GONE)
603                 {
604                   anBtn.setVisibility (View.VISIBLE);
605                   isVisible = true;
606                 }
607                 else
608                 {
609                   anBtn.setVisibility (View.GONE);
610                 }
611               }
612             }
613             aParentBtn.setBackgroundColor (!isVisible ? getResources().getColor(R.color.btnColor) : getResources().getColor(R.color.pressedBtnColor));
614           }
615           return false;
616         }
617       });
618     }
619   }
620
621   //! Implements onTouch functionality
622   private boolean onTouchButton (View        theView,
623                                  MotionEvent theEvent)
624   {
625     switch (theEvent.getAction())
626     {
627       case MotionEvent.ACTION_DOWN:
628         ((ImageButton )theView).setBackgroundColor (getResources().getColor (R.color.pressedBtnColor));
629         break;
630       case MotionEvent.ACTION_UP:
631         ((ImageButton )theView).setBackgroundColor (getResources().getColor (R.color.btnColor));
632         break;
633     }
634     return false;
635   }
636
637   //! Handle configuration change event
638   @Override
639   public void onConfigurationChanged (Configuration theNewConfig)
640   {
641     super.onConfigurationChanged (theNewConfig);
642     LinearLayout aLayoutPanelMenu       = (LinearLayout )findViewById (R.id.panel_menu);
643     LayoutParams aPanelMenuLayoutParams = aLayoutPanelMenu.getLayoutParams();
644
645     LinearLayout aLayoutViewGroup       = (LinearLayout )findViewById (R.id.view_group);
646     LayoutParams aViewGroupLayoutParams = aLayoutViewGroup.getLayoutParams();
647     ImageButton  aScrollBtn             = (ImageButton )findViewById (R.id.scroll_btn);
648     LayoutParams aScrollBtnLayoutParams = aScrollBtn.getLayoutParams();
649
650     myButtonPreferSize = defineButtonSize ((LinearLayout )findViewById (R.id.panel_menu));
651     defineButtonSize ((LinearLayout )findViewById (R.id.view_group));
652
653     switch (theNewConfig.orientation)
654     {
655       case Configuration.ORIENTATION_PORTRAIT:
656       {
657         setHorizontal (aLayoutPanelMenu, aPanelMenuLayoutParams);
658         setHorizontal (aLayoutViewGroup, aViewGroupLayoutParams);
659         aLayoutViewGroup.setGravity (Gravity.BOTTOM);
660
661         aScrollBtnLayoutParams.height = LayoutParams.WRAP_CONTENT;
662         aScrollBtnLayoutParams.width  = LayoutParams.MATCH_PARENT;
663         aScrollBtn.setLayoutParams (aScrollBtnLayoutParams);
664         if (aLayoutPanelMenu.getVisibility() == View.VISIBLE)
665         {
666           aScrollBtn.setImageResource (R.drawable.close_p);
667           aScrollBtn.setY (myButtonPreferSize);
668           aScrollBtn.setX (0);
669         }
670         else
671         {
672           aScrollBtn.setImageResource (R.drawable.open_p);
673           aScrollBtn.setY (0);
674           aScrollBtn.setX (0);
675         }
676         break;
677       }
678       case Configuration.ORIENTATION_LANDSCAPE:
679       {
680         setVertical (aLayoutPanelMenu, aPanelMenuLayoutParams);
681         setVertical (aLayoutViewGroup, aViewGroupLayoutParams);
682         aLayoutViewGroup.setGravity (Gravity.RIGHT);
683
684         aScrollBtnLayoutParams.height = LayoutParams.MATCH_PARENT;
685         aScrollBtnLayoutParams.width  = LayoutParams.WRAP_CONTENT;
686         aScrollBtn.setLayoutParams (aScrollBtnLayoutParams);
687         if (aLayoutPanelMenu.getVisibility() == View.VISIBLE)
688         {
689           aScrollBtn.setImageResource (R.drawable.close_l);
690           aScrollBtn.setX (myButtonPreferSize);
691           aScrollBtn.setY (0);
692         }
693         else
694         {
695           aScrollBtn.setImageResource (R.drawable.open_l);
696           aScrollBtn.setY (0);
697           aScrollBtn.setX (0);
698         }
699         break;
700       }
701     }
702     setTextViewPosition (myMessageTextView);
703     setTextViewPosition ((TextView )findViewById (R.id.info_view));
704   }
705
706   private void setHorizontal (LinearLayout theLayout,
707                               LayoutParams theLayoutParams)
708   {
709     theLayout.setOrientation (LinearLayout.HORIZONTAL);
710     theLayoutParams.height = LayoutParams.WRAP_CONTENT;
711     theLayoutParams.width  = LayoutParams.MATCH_PARENT;
712     theLayout.setLayoutParams (theLayoutParams);
713   }
714
715   private void setVertical (LinearLayout theLayout,
716                             LayoutParams theLayoutParams)
717   {
718     theLayout.setOrientation (LinearLayout.VERTICAL);
719     theLayoutParams.height = LayoutParams.MATCH_PARENT;
720     theLayoutParams.width  = LayoutParams.WRAP_CONTENT;
721     theLayout.setLayoutParams (theLayoutParams);
722   }
723
724   //! Define button size
725   private int defineButtonSize (LinearLayout theLayout)
726   {
727     boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
728     Display aDisplay    = getWindowManager().getDefaultDisplay();
729     Point   aDispPnt    = new Point();
730     aDisplay.getSize (aDispPnt);
731
732     int aNbChildren = theLayout.getChildCount();
733     int aHeight     = aDispPnt.y / aNbChildren;
734     int aWidth      = aDispPnt.x / aNbChildren;
735     int aResultSize = 0;
736     for (int aChildIter = 0; aChildIter < aNbChildren; ++aChildIter)
737     {
738       View aView = theLayout.getChildAt (aChildIter);
739       if (aView instanceof ImageButton)
740       {
741         ImageButton aButton = (ImageButton )aView;
742         if (isLandscape)
743         {
744           aButton.setMinimumWidth (aHeight);
745         }
746         else
747         {
748           aButton.setMinimumHeight (aWidth);
749         }
750       }
751     }
752     if (isLandscape)
753     {
754       aResultSize = aHeight;
755     }
756     else
757     {
758       aResultSize = aWidth;
759     }
760     return aResultSize;
761   }
762
763   //! OCCT major version
764   private native long cppOcctMajorVersion();
765
766   //! OCCT minor version
767   private native long cppOcctMinorVersion();
768
769   //! OCCT micro version
770   private native long cppOcctMicroVersion();
771
772   private OcctJniView       myOcctView;
773   private TextView          myMessageTextView;
774   private String            myLastPath;
775   private OcctJniFileDialog myFileOpenDialog;
776   private int               myButtonPreferSize = 65;
777
778 }