1 package org.geuz.onelab;
2 
3 import org.geuz.onelab.Gmsh;
4 
5 import java.io.File;
6 import java.io.FileNotFoundException;
7 import java.io.FileOutputStream;
8 import java.util.Timer;
9 import java.util.TimerTask;
10 
11 import android.app.Fragment;
12 import android.graphics.Bitmap;
13 import android.opengl.GLSurfaceView;
14 import android.os.Bundle;
15 import android.os.Handler;
16 import android.view.GestureDetector;
17 import android.view.GestureDetector.OnGestureListener;
18 import android.view.Gravity;
19 import android.view.LayoutInflater;
20 import android.view.MotionEvent;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.view.animation.Animation;
24 import android.view.animation.AnimationUtils;
25 import android.widget.ImageButton;
26 import android.widget.LinearLayout;
27 import android.widget.ProgressBar;
28 import android.widget.RelativeLayout;
29 import android.widget.SeekBar;
30 import android.widget.TextView;
31 import android.util.TypedValue;
32 
33 public class ModelFragment extends Fragment {
34   private Gmsh _gmsh;
35   private mGLSurfaceView _glView;
36   private TextView _progress;
37   private LinearLayout _progressLayout;
38   private LinearLayout _controlBarLayout;
39   private GestureDetector _gestureDetector;
40   private Timer _animation;
41   private Handler _hideDelay;
42   private SeekBar _animationStepper;
43 
44   final Runnable hideControlsRunnable = new Runnable() {
45     public void run() { hideControlBar(); }
46   };
47 
newInstance(Gmsh g)48   public static ModelFragment newInstance(Gmsh g)
49   {
50     ModelFragment fragment = new ModelFragment();
51     Bundle bundle = new Bundle();
52     bundle.putParcelable("Gmsh", g);
53     fragment.setArguments(bundle);
54     return fragment;
55   }
56 
ModelFragment()57   public ModelFragment() {}
58 
onCreate(Bundle savedInstanceState)59   @Override public void onCreate(Bundle savedInstanceState)
60   {
61     super.onCreate(savedInstanceState);
62     _gmsh = getArguments().getParcelable("Gmsh");
63   }
64 
65   @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)66   public View onCreateView(LayoutInflater inflater, ViewGroup container,
67                            Bundle savedInstanceState)
68   {
69     View rootView = inflater.inflate(R.layout.fragment_model, container, false);
70     RelativeLayout glViewLayout =
71       (RelativeLayout)rootView.findViewById(R.id.glViewLayout);
72     GLESRender renderer = new GLESRender(_gmsh);
73     _glView = new mGLSurfaceView(glViewLayout.getContext(), renderer);
74     _glView.setEGLContextClientVersion(1);
75     _glView.setRenderer(renderer);
76     _glView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
77     _glView.requestRender();
78     _hideDelay = new Handler();
79     _gestureDetector =
80       new GestureDetector(getActivity(), new OnGestureListener() {
81         // UNUSED Auto-generated method stub
82         public boolean onSingleTapUp(MotionEvent e) { return false; }
83         // UNUSED Auto-generated method stub
84         public void onShowPress(MotionEvent e) {}
85         // UNUSED Auto-generated method stub
86         public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
87                                 float distanceY)
88         {
89           return false;
90         }
91         // UNUSED Auto-generated method stub
92         public void onLongPress(MotionEvent e) {}
93         // UNUSED Auto-generated method stub
94         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
95                                float velocityY)
96         {
97           return false;
98         }
99         // UNUSED Auto-generated method stub
100         public boolean onDown(MotionEvent e) { return false; }
101       });
102     _gestureDetector.setOnDoubleTapListener(
103       new GestureDetector.OnDoubleTapListener() {
104         public boolean onSingleTapConfirmed(MotionEvent e)
105         {
106           if(View.VISIBLE == _controlBarLayout.getVisibility())
107             hideControlBar();
108           else
109             showControlBar();
110           return true;
111         }
112         // UNUSED Auto-generated method stub
113         public boolean onDoubleTapEvent(MotionEvent e) { return false; }
114         // UNUSED Auto-generated method stub
115         public boolean onDoubleTap(MotionEvent e) { return false; }
116       });
117     _glView.setOnTouchListener(new View.OnTouchListener() {
118       public boolean onTouch(View v, MotionEvent event)
119       {
120         return _gestureDetector.onTouchEvent(event);
121       }
122     });
123     glViewLayout.addView(_glView);
124     RelativeLayout topRightLayout = new RelativeLayout(container.getContext());
125     ImageButton rotationButton = new ImageButton(container.getContext());
126     rotationButton.setBackgroundResource(R.drawable.icon_rotate);
127     rotationButton.setLayoutParams(new LinearLayout.LayoutParams(60, 60));
128     rotationButton.setOnClickListener(new View.OnClickListener() {
129       public void onClick(View v)
130       {
131         boolean rotate = !_glView.getRotate();
132         ((ImageButton)v)
133           .setBackgroundResource(rotate ? R.drawable.icon_translate :
134                                           R.drawable.icon_rotate);
135         _glView.setRotate(rotate);
136       }
137     });
138     topRightLayout.addView(rotationButton);
139     RelativeLayout.LayoutParams layoutParams =
140       new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
141                                       RelativeLayout.LayoutParams.WRAP_CONTENT);
142 
143     TypedValue tv = new TypedValue();
144     int actionBarHeight = 80;
145     if(container.getContext().getTheme().resolveAttribute(
146          android.R.attr.actionBarSize, tv, true)) {
147       actionBarHeight = TypedValue.complexToDimensionPixelSize(
148         tv.data, getResources().getDisplayMetrics());
149     }
150     layoutParams.setMargins(0, actionBarHeight + 20, 20, 0);
151     layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
152     layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
153     glViewLayout.addView(topRightLayout, layoutParams);
154     _progressLayout = new LinearLayout(container.getContext());
155     ProgressBar bar = new ProgressBar(container.getContext());
156     bar.setOnClickListener(new View.OnClickListener() {
157       public void onClick(View v)
158       {
159         _progress.setAlpha((_progress.getAlpha() > 0) ? 0 : 1);
160       }
161     });
162     _progressLayout.addView(bar);
163     _progress = new TextView(container.getContext());
164     _progressLayout.setAlpha(0);
165     _progressLayout.setGravity(Gravity.CENTER);
166     _progressLayout.addView(_progress);
167     layoutParams =
168       new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
169                                       RelativeLayout.LayoutParams.WRAP_CONTENT);
170     layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
171     glViewLayout.addView(_progressLayout, layoutParams);
172     _controlBarLayout = (LinearLayout)getActivity().getLayoutInflater().inflate(
173       R.layout.control_bar, null);
174     final ImageButton prevButton =
175       (ImageButton)_controlBarLayout.findViewById(R.id.controlPrev);
176     final ImageButton playPauseButton =
177       (ImageButton)_controlBarLayout.findViewById(R.id.controlPlay);
178     final ImageButton nextButton =
179       (ImageButton)_controlBarLayout.findViewById(R.id.controlNext);
180     _animationStepper =
181       (SeekBar)_controlBarLayout.findViewById(R.id.controlStepper);
182     _animationStepper.setOnSeekBarChangeListener(
183       new SeekBar.OnSeekBarChangeListener() {
184         // UNUSED Auto-generated method stub
185         public void onStopTrackingTouch(SeekBar seekBar) {}
186         // UNUSED Auto-generated method stub
187         public void onStartTrackingTouch(SeekBar seekBar) {}
188         public void onProgressChanged(SeekBar seekBar, int progress,
189                                       boolean fromUser)
190         {
191           if(fromUser) {
192             postDelay();
193             _gmsh.setAnimation(progress);
194             requestRender();
195           }
196         }
197       });
198     _controlBarLayout.setEnabled(false);
199     playPauseButton.setOnClickListener(new View.OnClickListener() {
200       public void onClick(View v)
201       {
202         postDelay();
203         if(((ImageButton)v).getContentDescription().equals("play")) {
204           ((ImageButton)v).setContentDescription("pause");
205           ((ImageButton)v).setImageResource(android.R.drawable.ic_media_pause);
206           _animationStepper.setMax(_gmsh.numberOfAnimation() - 1);
207           _animation = new Timer();
208           _animation.schedule(new TimerTask() {
209             public void run()
210             {
211               _animationStepper.setProgress(_gmsh.animationNext());
212               requestRender();
213             }
214           }, 0, 500);
215           prevButton.setEnabled(false);
216           nextButton.setEnabled(false);
217         }
218         else {
219           ((ImageButton)v).setContentDescription("play");
220           ((ImageButton)v).setImageResource(android.R.drawable.ic_media_play);
221           _animation.cancel();
222           prevButton.setEnabled(true);
223           nextButton.setEnabled(true);
224         }
225       }
226     });
227     nextButton.setOnClickListener(new View.OnClickListener() {
228       public void onClick(View v)
229       {
230         postDelay();
231         _animationStepper.setProgress(_gmsh.animationNext());
232         requestRender();
233       }
234     });
235     prevButton.setOnClickListener(new View.OnClickListener() {
236       public void onClick(View v)
237       {
238         postDelay();
239         _animationStepper.setProgress(_gmsh.animationPrev());
240         requestRender();
241       }
242     });
243     layoutParams =
244       new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
245                                       RelativeLayout.LayoutParams.WRAP_CONTENT);
246     layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
247     glViewLayout.addView(_controlBarLayout, layoutParams);
248     this._controlBarLayout.setVisibility(View.INVISIBLE);
249     return rootView;
250   }
postDelay(int delay)251   public void postDelay(int delay)
252   {
253     _hideDelay.removeCallbacks(hideControlsRunnable);
254     _hideDelay.postDelayed(hideControlsRunnable, delay);
255   }
postDelay()256   public void postDelay() { this.postDelay(6000); }
showControlBar()257   public void showControlBar()
258   {
259     if(getActivity() == null || ((MainActivity)getActivity()).isComputing() ||
260        !_gmsh.haveAnimation())
261       return;
262     _controlBarLayout.setEnabled(true);
263     _animationStepper.setMax(_gmsh.numberOfAnimation() - 1);
264     this.postDelay();
265     Animation bottomUp =
266       AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in);
267     _controlBarLayout.setVisibility(View.VISIBLE);
268     _controlBarLayout.startAnimation(bottomUp);
269   }
hideControlBar()270   public void hideControlBar()
271   {
272     if(getActivity() == null ||
273        View.INVISIBLE == _controlBarLayout.getVisibility())
274       return;
275     _hideDelay.removeCallbacks(hideControlsRunnable);
276     Animation bottomDown =
277       AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
278     _controlBarLayout.startAnimation(bottomDown);
279     _controlBarLayout.setVisibility(View.INVISIBLE);
280   }
showProgress(String progress)281   public void showProgress(String progress)
282   {
283     _progressLayout.setAlpha(1);
284     _progress.setText(progress);
285   }
hideProgress()286   public void hideProgress()
287   {
288     _progressLayout.setAlpha(0);
289     _progress.setText("");
290   }
requestRender()291   public void requestRender() { _glView.requestRender(); }
292 }
293