From 1a068e7cee4e1a4995c792a606aff251bf4d5561 Mon Sep 17 00:00:00 2001 From: Maxime Graulich <maxime.graulich@gmail.com> Date: Wed, 18 Sep 2013 09:17:16 +0000 Subject: [PATCH] Android: add a SeekBar to show animation progress --- .../Android/res/drawable-hdpi/ic_list.png | Bin 464 -> 0 bytes .../Android/res/drawable-hdpi/ic_mesh.png | Bin 760 -> 0 bytes .../Android/res/drawable-hdpi/ic_settings.png | Bin 1412 -> 0 bytes .../mobile/Android/res/layout/control_bar.xml | 54 +++++++++++------- .../Android/src/org/geuz/onelab/Gmsh.java | 6 +- .../src/org/geuz/onelab/MainActivity.java | 4 ++ .../src/org/geuz/onelab/ModelFragment.java | 22 ++++--- contrib/mobile/androidGModel.cpp | 14 +++-- contrib/mobile/androidGModel.h | 16 ++++-- contrib/mobile/drawContext.cpp | 39 ++++++++----- contrib/mobile/drawContext.h | 5 +- 11 files changed, 104 insertions(+), 56 deletions(-) delete mode 100644 contrib/mobile/Android/res/drawable-hdpi/ic_list.png delete mode 100644 contrib/mobile/Android/res/drawable-hdpi/ic_mesh.png delete mode 100644 contrib/mobile/Android/res/drawable-hdpi/ic_settings.png diff --git a/contrib/mobile/Android/res/drawable-hdpi/ic_list.png b/contrib/mobile/Android/res/drawable-hdpi/ic_list.png deleted file mode 100644 index 0845ffb33f34db2c2e4501f38c5dad6088d53f95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 464 zcmeAS@N?(olHy`uVBq!ia0vp^=0L2=!3HF`rhVQGq*#ibJVQ8upoSx*1IXtr@Q5sC zU=a8R!i*+Xa~*(!k|nMYCBgY=CFO}lsSM@i<$9TU*~Q6;1*v-ZMd`EO*+?-kF#3AB zIEG|2zP)9iE#fG{_8{GyapMl7(0z_ME~{DAaXK+s^64m<B~5;|W4-c`^$C-iox7$? zSDNl*Fu^M*I-)D$)%m2&1xq&EN}Z89FKc=A{iJ_y3_@KFuo%lMnzmhg&ZA&aLH&=a zg$wL_vd#oAe{pipvB_67t3GY%>WGb5?sutqyJ=WOx&`Zdli;^&sv>lwm2*@&uk;=` zU-n_godr+!E&m&?Iem4IUii|ObzVDTrWWnI74!Sv@ri%<&xQZ!u@80WDQKR%WaF-{ zvel;dq{9qv99whj^%c)5qqQ47<}On2E<3mOgHGuzzPpdF{+j<IqF8hG@2s6iR2Rh< zKUp>9bSSdfxpq?dC;vbAvsiY^Q$G`b)3_xbS2pJV=->xhVme*R`E%L_f7809eitX- y4|TCQejR9w!P>%Z<~fh^Z`sU^cqAeIpJCSm?~7}niG2cwK7*&LpUXO@geCwyYRRbp diff --git a/contrib/mobile/Android/res/drawable-hdpi/ic_mesh.png b/contrib/mobile/Android/res/drawable-hdpi/ic_mesh.png deleted file mode 100644 index 2c927569920e18ae051265d2fb7187c682cd8cf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 760 zcmV<U0tfwxP)<h;3K|Lk000e1NJLTq001!n001xu1^@s6xWJOR00004b3#c}2nYxW zd<bNS00009a7bBm000pF000pF0W><DKmY&$8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10(D75K~!jg?b^#~Q$ZZZ@vlixH||{)R1~ipS5onAvDW(wxD!#4 zQoJHkw5?e61zd@@>H~-y7lOWn?gT;5swk~mFRfn}nLvz5&LonPvp7FEgv`u;&V0z? z9A+|4B{GA+HDETjAcd5Gxl-idAz%zB0)4=nPOU031z-f&4lF`Vx=yLz)d9=tiKyx1 zRZwrKAJu*%3eE(;?(n_ah=O`s{h+Q3YiU|=E&%$g+PaA-sCU%&0YDPsLICWlY3~-I zsNM~LwN>p65f{}NwXaTJHxNbjo;s<nsp+eW7!H7)4JJ$*QB)@aV0E4Te-M`fU`LZl z(?k^22kJX@Rf92qAx6}1>h^?*(?XQghw58(Ws`9|swH3?I1U^Fo&yUL9yALg#{5r8 zz%8H`*aEyrDwwB6zjvgV-@s~;0X@L0%4^4RU@~IzPry3hb-SyJ$THv=5x+ns6~q+q zIkKjevF&8K)q+ANR*`mcL{^d`vXUH;mE?%5Bu8W=IU*~`5m`x&$VzfVR+1yKlGu}? z>U4VZY<~ERxyJ%%5Am{%nszc1JFpeRG2j<)6nNC?idx80;0fj3y=GYt+y^Eqo5YI~ zHh52{Kh=XNY$mU;e8AIe%m#Hzy`d6=I2iy3QUJstdev$5dZjH1F{u7f_ooC%LTn6x z@#^+wh@k-3mm;7UVw3tsy;|GX2yr?9_NEMIgxIWpRj<^msfRcl0DHOssE61Z0Ar16 zY7yrHV4zEYTEsTX$8e*~YN`>Hv+MpAZ`vuujsUovR8u+bx(OTxjsQ<P_Z*AL65uf~ qNBLhp7n2IIdS*8Zi~_?kgZ}_LKel6i!d7tr0000<MNUMnLSTZ8JVU+! diff --git a/contrib/mobile/Android/res/drawable-hdpi/ic_settings.png b/contrib/mobile/Android/res/drawable-hdpi/ic_settings.png deleted file mode 100644 index aced98ab0d9c88e34b584f2b91441190f7cbf521..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1412 zcmV-~1$+95P)<h;3K|Lk000e1NJLTq001!n001ut1^@s6N<bp_00004b3#c}2nYxW zd<bNS00009a7bBm000m;000m;0d6Z0ApigX8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H11p!G!K~!jgwV7LpR#g<oe=}adks{37WSS`{;S`xfWkw=t7c0%k zhX|t#L4+Ox2?8IAf_f0T&`Sy0OJq<+gk`9C2{h0!OhtXjOX_4}+Sqs-XMR2G^TF3Q z=eECZ{KMkF-g~We{^zW{_u6YWsq_;D0i%FcV07|q1@;18McBCoSOT;GBNKTK_%KVM zDU!rE;OUeXZ3S)wno@Mu0SijnUkZEx46JHv2POg+GPTqq8Ie3Es7H;%5p`S%AE@&) zY%D9%Ei!zc+M%vek4F;t!$7<Y0n~#jHjb%-8zC`Q?TUQy3Qnn$A_$Dnu=8md{pO4) zdlC2=Xek-X)#v~o1`b8&+>z0~r;KtMi2;PwVPHyM5zYd$fqjvBXENHyl+e99>le*X zyCXyBAN8Jy5UQ4O88&wn=uK1)rFBd-Oy(GzSEtuW0Ck|+lVbO(`c7iIxkhK9dPY5- zwoiNqJQ@)Smw?BBEfG3tI04+0(|;P+4h$n~h!c|b1GRB~JMd7X^K-zlNS!palTTtK z@Jvek;mX8*g0LFx28KjB9}WBjOo`O1#u8v^ow{35Us8J`=Rg`dtZ!mB>c0)OvjGFO z=u~G~p1>m0Cv;h?HrcVSL@4#D9~C&hXxQzG2s~F{rwCirVJc1P24GH!*!vrJ4Oj&% zPM%rl1{MLIXY?-wJ|k?bY1jeGCCs-eiL?TL0e=z}l5c@t0MsGs#vI1`)H#N=y!uPN zTJWWM)Ft-)0}IUGNPkwZPthw(09%sZlZMxG47^c5M0I)9_<81s?{4*m7y{KKP=~79 zYmD|9R*yU*@0TF*mSLV;&Ka}EB*q&dfqI>~BQe@#`1M6bn$$HVh+NI-+p7+*hk(h% zuANjZgk$L0WD=FZ0N@MCA498g0GLTgE9ye*89NVy2`k3z2%SR&0;d{r+@B->h5|nT z(@Tu~9e9wC_%(#AlU=>&BCPLaPIc$Vt6)T+zezwijSVj`ZYm*tAJwSC{w6UA*ht9v z%ivDJ8DU%_PWzL@t-vNist|+Q2&w$!dL8!{iLt<D;O30}qSa$8unoAY9_Rf*qLn~k zd`ACy!l9?Dz|KhEN6M{i|3|&MWFjNg{W&}FzlO>Q>TL7VjtaUA31{7DM~n<pf6aNB zi|VWzodxEn9~E4-T*{M~c0foYo+QNhC}0F|l28=eN670p0Mjyl@D*Sl@O?_(3&3j9 zE9lke0bT~y6pTy#6Rqmb5??C|SJbBpzTPV(ZS^K&qr+)k0|c(B&lWjNWJQGC6)_}c zG(ez7eZC}timZ&Vzp^ZeH|r$Ot1gZtP?1#;em=2pIkOLmt#y(pD*Wb2v${6I*IIQ@ z9*L7xgAc2l)GyW31%{6|K!W6@)<+OoZzyo2k~pun+qZ7itUjQ=YkIAy+mzoNDMQq4 z5k$6{R7I+dG#M@m#}qjGCBtZIgCs~^YIg*YUFz`a+-WfIIK?Ne?HTQP745R<1Rf!r zyUSo2@OCwc%fS8;idpC38%sJaLI>fTex$_MJ;3sMve>qa_A(!!EKU$EFWYm*93ezb zXKc(4Hry@O;$T0_hcsz3Txr#!L!De17i)A`#sr&xjYy#0YgjcaxS-x&JtoFji{X;J z8r|yBYe=9Xv(!t5+^kP>8FN>?m{4NbNvPKS27C-0tt;x|u$gcjFbeplw(~!~lLE$5 SP4Tz@0000<MNUMnLSTY&7kZ%p diff --git a/contrib/mobile/Android/res/layout/control_bar.xml b/contrib/mobile/Android/res/layout/control_bar.xml index 89bc5c543d..22f76a01b4 100644 --- a/contrib/mobile/Android/res/layout/control_bar.xml +++ b/contrib/mobile/Android/res/layout/control_bar.xml @@ -2,30 +2,42 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="horizontal" + android:orientation="vertical" android:background="@android:color/black" android:alpha=".50" android:gravity="center" > + <SeekBar + android:id="@+id/controlStepper" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:background="@android:color/black" + android:alpha=".50" + android:gravity="center" > - <ImageButton - android:id="@+id/controlPrev" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@android:drawable/ic_media_previous" - android:contentDescription="previous" /> - - <ImageButton - android:id="@+id/controlPlay" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@android:drawable/ic_media_play" - android:contentDescription="play" /> - - <ImageButton - android:id="@+id/controlNext" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@android:drawable/ic_media_next" - android:contentDescription="next" /> + <ImageButton + android:id="@+id/controlPrev" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@android:drawable/ic_media_previous" + android:contentDescription="previous" /> + + <ImageButton + android:id="@+id/controlPlay" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@android:drawable/ic_media_play" + android:contentDescription="play" /> + + <ImageButton + android:id="@+id/controlNext" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@android:drawable/ic_media_next" + android:contentDescription="next" /> + </LinearLayout> </LinearLayout> \ No newline at end of file diff --git a/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java b/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java index 2e1e04fda1..4ba89b2a58 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java @@ -31,8 +31,10 @@ public class Gmsh implements Parcelable { public native void setPView(int position, int intervalsType,int visible,int nbIso, float raisez); // Change options for a PView public native int onelabCB(String action); // Call onelab - public native void animationNext(); - public native void animationPrev(); + public boolean haveAnimation() {return numberOfAnimation() > 1;} + public native int numberOfAnimation(); + public native int animationNext(); + public native int animationPrev(); /** Java CLASS **/ private long ptr; diff --git a/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java b/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java index 2a3a8f85b5..24013b948e 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java @@ -120,6 +120,7 @@ public class MainActivity extends Activity{ new Run().execute(); } else if(item.getTitle().equals(getString(R.string.menu_stop))){ + _runStopMenuItem.setEnabled(false); _gmsh.onelabCB("stop"); } else if(item.getTitle().equals(getString(R.string.menu_share))) { @@ -196,6 +197,7 @@ public class MainActivity extends Activity{ protected void onPostExecute(Integer[] result) { //(Vibrator) getSystemService(Context.VIBRATOR_SERVICE).vibrate(350); _runStopMenuItem.setTitle(R.string.menu_run); + _runStopMenuItem.setEnabled(true); if(_modelFragment != null) _modelFragment.hideProgress(); _compute = false; if(_notify) notifyEndComputing(); @@ -332,4 +334,6 @@ public class MainActivity extends Activity{ } }; }; + + public boolean isComputing() {return _compute;} } diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java b/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java index bb4e2c7fd3..b24245bb21 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java @@ -24,6 +24,7 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; +import android.widget.SeekBar; import android.widget.TextView; public class ModelFragment extends Fragment{ @@ -36,9 +37,10 @@ public class ModelFragment extends Fragment{ private GestureDetector _gestureDetector; private Timer _animation; private Handler _hideDelay; - + private SeekBar _annimationStepper; + final Runnable hideControlsRunnable = new Runnable() {public void run() {hideControlBar();}}; - + public static ModelFragment newInstance(Gmsh g) { ModelFragment fragment = new ModelFragment(); Bundle bundle = new Bundle(); @@ -116,16 +118,19 @@ public class ModelFragment extends Fragment{ final ImageButton prevButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPrev); final ImageButton playPauseButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPlay); final ImageButton nextButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlNext); + _annimationStepper = (SeekBar)_controlBarLayout.findViewById(R.id.controlStepper); + _controlBarLayout.setEnabled(false); playPauseButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { postDelay(); if(((ImageButton)v).getContentDescription().equals("play")) { ((ImageButton)v).setContentDescription("pause"); ((ImageButton)v).setImageResource(android.R.drawable.ic_media_pause); + _annimationStepper.setMax(_gmsh.numberOfAnimation()); _animation = new Timer(); _animation.schedule(new TimerTask() { public void run() { - _gmsh.animationNext(); + _annimationStepper.setProgress(_gmsh.animationNext()); requestRender(); } }, 0, 500); prevButton.setEnabled(false); @@ -143,14 +148,14 @@ public class ModelFragment extends Fragment{ nextButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { postDelay(); - _gmsh.animationNext(); + _annimationStepper.setProgress(_gmsh.animationNext()); requestRender(); } }); prevButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { postDelay(); - _gmsh.animationPrev(); + _annimationStepper.setProgress(_gmsh.animationPrev()); requestRender(); } }); @@ -169,9 +174,10 @@ public class ModelFragment extends Fragment{ this.postDelay(6000); } public void showControlBar() { - if(getActivity() == null) return; + if(getActivity() == null || ((MainActivity)getActivity()).isComputing() || !_gmsh.haveAnimation()) return; + _controlBarLayout.setEnabled(true); + _annimationStepper.setMax(_gmsh.numberOfAnimation()); this.postDelay(); - //getActivity().getActionBar().show(); Animation bottomUp = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in); _controlBarLayout.setVisibility(View.VISIBLE); _controlBarLayout.startAnimation(bottomUp); @@ -179,10 +185,10 @@ public class ModelFragment extends Fragment{ public void hideControlBar() { if(getActivity() == null) return; _hideDelay.removeCallbacks(hideControlsRunnable); - //getActivity().getActionBar().hide(); Animation bottomDown = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out); _controlBarLayout.startAnimation(bottomDown); _controlBarLayout.setVisibility(View.INVISIBLE); + } public void showProgress(String progress) { _progressLayout.setAlpha(1); diff --git a/contrib/mobile/androidGModel.cpp b/contrib/mobile/androidGModel.cpp index 606626e840..92ffcf899b 100644 --- a/contrib/mobile/androidGModel.cpp +++ b/contrib/mobile/androidGModel.cpp @@ -304,14 +304,20 @@ JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_onelabCB const char* action = env->GetStringUTFChars(jaction, NULL); return onelab_cb(action); } -JNIEXPORT void JNICALL Java_org_geuz_onelab_Gmsh_animationNext + +JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_numberOfAnimation + (JNIEnv *, jobject) +{ + return number_of_animation(); +} +JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_animationNext (JNIEnv *, jobject) { - animation_next(); + return animation_next(); } -JNIEXPORT void JNICALL Java_org_geuz_onelab_Gmsh_animationPrev +JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_animationPrev (JNIEnv *, jobject) { - animation_prev(); + return animation_prev(); } } diff --git a/contrib/mobile/androidGModel.h b/contrib/mobile/androidGModel.h index 043816e971..991a211071 100644 --- a/contrib/mobile/androidGModel.h +++ b/contrib/mobile/androidGModel.h @@ -137,20 +137,28 @@ JNIEXPORT void JNICALL Java_org_geuz_onelab_Gmsh_setPView JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_onelabCB (JNIEnv *, jobject, jstring); +/* + * Class: org_geuz_onelab_Gmsh + * Method: numberOfAnimation + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_numberOfAnimation + (JNIEnv *, jobject); + /* * Class: org_geuz_onelab_Gmsh * Method: animationNext - * Signature: ()V + * Signature: ()I */ -JNIEXPORT void JNICALL Java_org_geuz_onelab_Gmsh_animationNext +JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_animationNext (JNIEnv *, jobject); /* * Class: org_geuz_onelab_Gmsh * Method: animationPrev - * Signature: ()V + * Signature: ()I */ -JNIEXPORT void JNICALL Java_org_geuz_onelab_Gmsh_animationPrev +JNIEXPORT jint JNICALL Java_org_geuz_onelab_Gmsh_animationPrev (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/contrib/mobile/drawContext.cpp b/contrib/mobile/drawContext.cpp index 886f1dcd72..3a158c326e 100644 --- a/contrib/mobile/drawContext.cpp +++ b/contrib/mobile/drawContext.cpp @@ -682,41 +682,50 @@ int onelab_cb(std::string action) return redraw; } -void animation_next() { +int number_of_animation() { + int ret = 0; + for(unsigned int i = 0; i < PView::list.size(); i++){ + PView * p = PView::list[i]; + if(p->getOptions()->visible){ + int numSteps = (int)p->getData()->getNumTimeSteps(); + if(numSteps > ret) ret = numSteps; + } + } + return ret; +} + +int animation_next() { + int ret = 0; for(unsigned int i = 0; i < PView::list.size(); i++){ PView * p = PView::list[i]; if(p->getOptions()->visible){ - // skip empty steps int step = (int)p->getOptions()->timeStep + 1; int numSteps = (int)p->getData()->getNumTimeSteps(); - for(int j = 0; j < numSteps; j++){ - if(p->getData()->hasTimeStep(step)) break; - else step += 1; - if(step < 0) step = numSteps - 1; - if(step > numSteps - 1) step = 0; - } + if(step < 0) step = numSteps - 1; + if(step > numSteps - 1) step = 0; p->getOptions()->timeStep = step; p->setChanged(true); + ret = step; } } + return ret; } -void animation_prev() { +int animation_prev() { + int ret = 0; for(unsigned int i = 0; i < PView::list.size(); i++){ PView * p = PView::list[i]; if(p->getOptions()->visible){ // skip empty steps int step = (int)p->getOptions()->timeStep - 1; int numSteps = (int)p->getData()->getNumTimeSteps(); - for(int j = 0; j < numSteps; j++){ - if(p->getData()->hasTimeStep(step)) break; - else step -= 1; - if(step < 0) step = numSteps - 1; - if(step > numSteps - 1) step = 0; - } + if(step < 0) step = numSteps - 1; + if(step > numSteps - 1) step = 0; p->getOptions()->timeStep = step; p->setChanged(true); + ret = step; } } + return ret; } // vim:set ts=2: diff --git a/contrib/mobile/drawContext.h b/contrib/mobile/drawContext.h index e69035fb0a..a42a687577 100644 --- a/contrib/mobile/drawContext.h +++ b/contrib/mobile/drawContext.h @@ -21,8 +21,9 @@ void drawArray(VertexArray *va, int type, bool useColorArray=false, bool useNormalArray=false); int onelab_cb(std::string); -void animation_next(); -void animation_prev(); +int animation_next(); +int animation_prev(); +int number_of_animation(); class drawContext{ private: -- GitLab