Version für alte Androidversionen der Visiereinstellung für Recurvebogen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RBSMainActivity.java 43KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. package ch.spherIC.recurvebowsight;
  2. import android.app.Activity;
  3. import android.app.AlertDialog;
  4. import android.app.Dialog;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.os.Bundle;
  8. import android.os.Handler;
  9. import android.text.SpannableString;
  10. import android.text.style.TabStopSpan;
  11. import android.view.Gravity;
  12. import android.view.Menu;
  13. import android.view.MenuItem;
  14. import android.view.MotionEvent;
  15. import android.view.View;
  16. import android.view.View.OnClickListener;
  17. import android.view.View.OnTouchListener;
  18. import android.view.inputmethod.InputMethodManager;
  19. import android.widget.AdapterView;
  20. import android.widget.AdapterView.OnItemSelectedListener;
  21. import android.widget.Button;
  22. import android.widget.LinearLayout;
  23. import android.widget.ListView;
  24. import android.widget.ScrollView;
  25. import android.widget.TextView;
  26. import android.widget.Toast;
  27. import android.widget.ViewFlipper;
  28. import ch.spherIC.recurvebowsight.components.FontArrayAdapter;
  29. import ch.spherIC.recurvebowsight.components.FontTextView;
  30. import ch.spherIC.recurvebowsight.components.RiserSpinner;
  31. import ch.spherIC.recurvebowsight.components.SightSpinner;
  32. import ch.spherIC.recurvebowsight.components.XSpinner;
  33. import ch.spherIC.recurvebowsight.components.XTextView;
  34. import ch.spherIC.recurvebowsight.database.RBSDatabaseHelper;
  35. import ch.spherIC.recurvebowsight.database.dao.ArcherySetupDao;
  36. import ch.spherIC.recurvebowsight.database.dao.RiserDao;
  37. import ch.spherIC.recurvebowsight.database.dao.SightDao;
  38. import ch.spherIC.recurvebowsight.dialog.ChooseArcherySetupDlg.ChooseArcherySetupDlgDismissListener;
  39. import ch.spherIC.recurvebowsight.logic.CalculationTask;
  40. import ch.spherIC.recurvebowsight.logic.TrajectoryCalculator;
  41. import ch.spherIC.recurvebowsight.model.IArcherySetup;
  42. import ch.spherIC.recurvebowsight.model.IRiser;
  43. import ch.spherIC.recurvebowsight.model.ISight;
  44. import ch.spherIC.recurvebowsight.model.Riser;
  45. import ch.spherIC.recurvebowsight.model.Sight;
  46. import java.text.DecimalFormat;
  47. import java.util.ArrayList;
  48. import java.util.List;
  49. import java.util.StringTokenizer;
  50. public class RBSMainActivity extends Activity implements ChooseArcherySetupDlgDismissListener, TrajectoryCalculation {
  51. public static final DecimalFormat DF = new DecimalFormat("0.##");
  52. public static final DecimalFormat DF_FC = new DecimalFormat("0.000");
  53. public static final DecimalFormat DF_1 = new DecimalFormat("0.00");
  54. public static final DecimalFormat DF_EVS = new DecimalFormat("0.#");
  55. public static final int DLG_CHOOSE_ARCHERYSETUP = 0;
  56. public static final int DLG_USERGUIDE_PARAMS = 1;
  57. public static final int DLG_USERGUIDE_SIGHT = 2;
  58. public static final int DLG_ABOUT = 3;
  59. private static final Double ANGLE_90 = 90d;
  60. private static final int MIN_DISTANCE = 50;
  61. private static final double CENTI = 0.01;
  62. private static final double MILLI = 0.001;
  63. private static final String TAB = "\u0009";
  64. private ViewFlipper viewFlipper;
  65. private ScrollView paramsScrollView;
  66. private ScrollView sightCfgScrollView;
  67. private float lastX;
  68. private ListView listView1;
  69. private XTextView txtViewParams;
  70. private XTextView txtViewResults;
  71. private XTextView txtViewSight;
  72. private TextView arrowDiameterTxtFld;
  73. private TextView arrowCwTxtFld;
  74. private TextView arrowWeightTxtFld;
  75. private TextView bowPulloutTxtFld;
  76. private TextView arrowV0TxtFld;
  77. private TextView airTemperatureTxtFld;
  78. private TextView airRelativeHumidityTxtFld;
  79. private TextView shootingDistanzTxtFld;
  80. private TextView arrowNockHeightTxtFld;
  81. private TextView targetCenterHeightTxtFld;
  82. private XSpinner calcTimeIntervalCboBox;
  83. private XSpinner calcAccuracyCboBox;
  84. private RiserSpinner scRiserSpinner;
  85. private TextView scVvisHTxtFld;
  86. private TextView scVvisVTxtFld;
  87. private SightSpinner scSightSpinner;
  88. private XSpinner scHeVSSpinner;
  89. private TextView scHeVSTxtFld;
  90. private TextView scaVTxtFld;
  91. private TextView scaHTxtFld;
  92. private TextView scVertScaleRngTxtFld;
  93. private TextView scVertScaleMiddleTxtFld;
  94. private FontTextView scEvSValue;
  95. private Button calcSettingBtn;
  96. private XTextView flightCurveTxtFld;
  97. private boolean showInfoMenu;
  98. private IArcherySetup selectedArcherySetup;
  99. private Double startAngle;
  100. private String selectedHeVS;
  101. private AlertDialog calculationAlert;
  102. @Override
  103. public void onCreate(final Bundle savedInstanceState) {
  104. super.onCreate(savedInstanceState);
  105. setContentView(R.layout.rbs_main);
  106. PlatformUtils.getPlatformSelectionColor(getApplicationContext());
  107. this.calculationAlert = new AlertDialog.Builder(this).create();
  108. this.calculationAlert.setCancelable(false); // This blocks the 'BACK' button
  109. this.calculationAlert.setMessage(getApplicationContext().getResources().getString(R.string.caption_Calculating));
  110. UnitConverter.setApplication(getApplication());
  111. RBSDatabaseHelper.setContext(this);
  112. RBSDatabaseHelper.getInstance().initializeDB();
  113. initializeComponents();
  114. addTouchListeners();
  115. xTextViewUp(this.txtViewParams);
  116. this.calcTimeIntervalCboBox.setAdapter(new FontArrayAdapter<String>(this, R.layout.rbs_spinner,
  117. getResources().getStringArray(R.array.CalculationTimeIntervals),
  118. this.calcTimeIntervalCboBox));
  119. this.calcAccuracyCboBox.setAdapter(new FontArrayAdapter<String>(this, R.layout.rbs_spinner,
  120. getResources().getStringArray(R.array.CalculationAccuracies),
  121. this.calcAccuracyCboBox));
  122. List<IRiser> risers = RiserDao.getInstance().loadAll();
  123. risers.add(0, new Riser(-999, getResources().getString(R.string.caption_NoSelection), "", null, null, null));
  124. this.scRiserSpinner.setAdapter(new FontArrayAdapter<IRiser>(this, R.layout.rbs_spinner, risers,
  125. this.scRiserSpinner));
  126. List<ISight> sights = SightDao.getInstance().loadAll();
  127. sights.add(0,
  128. new Sight(-999, getResources().getString(R.string.caption_NoSelection), "", null, null, "", null, null));
  129. this.scSightSpinner.setAdapter(new FontArrayAdapter<ISight>(this, R.layout.rbs_spinner, sights,
  130. this.scSightSpinner));
  131. addRiserAndSightSpinnerListeners();
  132. }
  133. @Override
  134. protected void onRestoreInstanceState(final Bundle savedInstanceState) {
  135. super.onRestoreInstanceState(savedInstanceState);
  136. int selView = savedInstanceState.getInt("ViewFlipper.SelectedView", 0);
  137. this.viewFlipper.setDisplayedChild(selView);
  138. if (savedInstanceState.containsKey("SelectedArcherySetup")) {
  139. this.selectedArcherySetup = ArcherySetupDao.getInstance().loadById(savedInstanceState.getLong("SelectedArcherySetup"));
  140. }
  141. this.startAngle = savedInstanceState.getDouble("StartAngle", 0);
  142. this.selectedHeVS = savedInstanceState.getString("SelectedHeVS");
  143. deactivateAllXTextView();
  144. switch (selView) {
  145. case 0:
  146. xTextViewUp(this.txtViewParams);
  147. break;
  148. case 1:
  149. xTextViewUp(this.txtViewResults);
  150. break;
  151. case 2:
  152. xTextViewUp(this.txtViewSight);
  153. break;
  154. default:
  155. break;
  156. }
  157. }
  158. @Override
  159. protected void onSaveInstanceState(final Bundle outState) {
  160. super.onSaveInstanceState(outState);
  161. outState.putInt("ViewFlipper.SelectedView", this.viewFlipper.getDisplayedChild());
  162. if (this.selectedArcherySetup != null) {
  163. outState.putLong("SelectedArcherySetup", this.selectedArcherySetup.getId());
  164. }
  165. if (this.startAngle != null) {
  166. outState.putDouble("StartAngle", this.startAngle);
  167. }
  168. if (this.scHeVSSpinner.getSelectedItem() != null) {
  169. outState.putString("SelectedHeVS", this.scHeVSSpinner.getSelectedItem().toString());
  170. }
  171. }
  172. private void initializeComponents() {
  173. this.viewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);
  174. this.paramsScrollView = (ScrollView) findViewById(R.id.paramsScrollView);
  175. this.sightCfgScrollView = (ScrollView) findViewById(R.id.sightCfgScrollView);
  176. this.txtViewParams = (XTextView) findViewById(R.id.viewParams);
  177. this.txtViewResults = (XTextView) findViewById(R.id.viewResults);
  178. this.txtViewSight = (XTextView) findViewById(R.id.viewSight);
  179. this.arrowDiameterTxtFld = (TextView) findViewById(R.id.arrowDiameterTxtFld);
  180. this.arrowCwTxtFld = (TextView) findViewById(R.id.arrowCwTxtFld);
  181. this.arrowWeightTxtFld = (TextView) findViewById(R.id.arrowWeightTxtFld);
  182. this.bowPulloutTxtFld = (TextView) findViewById(R.id.bowPulloutTxtFld);
  183. this.arrowV0TxtFld = (TextView) findViewById(R.id.arrowV0TxtFld);
  184. this.airTemperatureTxtFld = (TextView) findViewById(R.id.airTemperatureTxtFld);
  185. this.airRelativeHumidityTxtFld = (TextView) findViewById(R.id.airRelativeHumidityTxtFld);
  186. this.shootingDistanzTxtFld = (TextView) findViewById(R.id.shootingDistanzTxtFld);
  187. this.arrowNockHeightTxtFld = (TextView) findViewById(R.id.arrowNockHeightTxtFld);
  188. this.targetCenterHeightTxtFld = (TextView) findViewById(R.id.targetCenterHeightTxtFld);
  189. this.calcTimeIntervalCboBox = (XSpinner) findViewById(R.id.deltaTimeCboBox);
  190. this.calcAccuracyCboBox = (XSpinner) findViewById(R.id.calcPrecisionCboBox);
  191. this.scRiserSpinner = (RiserSpinner) findViewById(R.id.scRiserSpinner);
  192. this.scVvisHTxtFld = (TextView) findViewById(R.id.scVvisHTxtFld);
  193. this.scVvisVTxtFld = (TextView) findViewById(R.id.scVvisVTxtFld);
  194. this.scSightSpinner = (SightSpinner) findViewById(R.id.scSightSpinner);
  195. this.scHeVSSpinner = (XSpinner) findViewById(R.id.scHeVSSpinner);
  196. this.scHeVSTxtFld = (TextView) findViewById(R.id.scHeVSTxtFld);
  197. this.scaVTxtFld = (TextView) findViewById(R.id.scaVTxtFld);
  198. this.scaHTxtFld = (TextView) findViewById(R.id.scaHTxtFld);
  199. this.scVertScaleRngTxtFld = (TextView) findViewById(R.id.scVertScaleRngTxtFld);
  200. this.scVertScaleMiddleTxtFld = (TextView) findViewById(R.id.scVertSkalaMiddleTxtFld);
  201. this.scEvSValue = (FontTextView) findViewById(R.id.scEvSValue);
  202. this.flightCurveTxtFld = (XTextView) findViewById(R.id.flightCurveTxtFld);
  203. this.calcSettingBtn = (Button) findViewById(R.id.scBtnCalc);
  204. }
  205. private void addRiserAndSightSpinnerListeners() {
  206. this.scRiserSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
  207. @Override
  208. public void onItemSelected(final AdapterView<?> parent, final View view, final int position,
  209. final long id) {
  210. IRiser riser = RBSMainActivity.this.scRiserSpinner.getSelectedRiser();
  211. if (riser.getId() != -999) {
  212. RBSMainActivity.this.scVvisHTxtFld.setText(DF.format(riser.getVVisH()));
  213. RBSMainActivity.this.scVvisVTxtFld.setText(DF.format(riser.getVVisV()));
  214. } else {
  215. RBSMainActivity.this.scVvisHTxtFld.setText("");
  216. RBSMainActivity.this.scVvisVTxtFld.setText("");
  217. }
  218. RBSMainActivity.this.scVvisHTxtFld.setEnabled(riser.getId() == -999);
  219. RBSMainActivity.this.scVvisVTxtFld.setEnabled(riser.getId() == -999);
  220. }
  221. @Override
  222. public void onNothingSelected(final AdapterView<?> parent) { }
  223. });
  224. this.scSightSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
  225. @Override
  226. public void onItemSelected(final AdapterView<?> parent, final View view, final int position,
  227. final long id) {
  228. ISight sight = RBSMainActivity.this.scSightSpinner.getSelectedSight();
  229. if (sight.getId() != -999) {
  230. List<String> listHeVis = new ArrayList<String>();
  231. String heVis = sight.getHeVis();
  232. StringTokenizer t = new StringTokenizer(heVis, ",");
  233. while (t.hasMoreTokens()) {
  234. listHeVis.add(t.nextToken());
  235. }
  236. RBSMainActivity.this.scHeVSTxtFld.setVisibility(View.INVISIBLE);
  237. RBSMainActivity.this.scHeVSTxtFld.setLayoutParams(new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSTxtFld.getLayoutParams().width,
  238. RBSMainActivity.this.scHeVSTxtFld.getLayoutParams().height,
  239. 0f));
  240. RBSMainActivity.this.scHeVSSpinner.setVisibility(View.VISIBLE);
  241. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSSpinner.getLayoutParams().width,
  242. RBSMainActivity.this.scHeVSSpinner.getLayoutParams().height,
  243. 1f);
  244. params.gravity = Gravity.FILL_VERTICAL;
  245. RBSMainActivity.this.scHeVSSpinner.setLayoutParams(params);
  246. RBSMainActivity.this.scHeVSSpinner.setAdapter(new FontArrayAdapter<String>(RBSMainActivity.this,
  247. R.layout.rbs_spinner,
  248. listHeVis,
  249. RBSMainActivity.this.scHeVSSpinner));
  250. if (RBSMainActivity.this.selectedHeVS == null) {
  251. if (RBSMainActivity.this.selectedArcherySetup != null
  252. && RBSMainActivity.this.selectedArcherySetup.getSight().getId() == sight.getId()) {
  253. RBSMainActivity.this.scHeVSSpinner.setSelectionByVal(DF.format(RBSMainActivity.this.selectedArcherySetup.getSightHorSetting()));
  254. }
  255. } else {
  256. RBSMainActivity.this.scHeVSSpinner.setSelectionByVal(RBSMainActivity.this.selectedHeVS);
  257. }
  258. RBSMainActivity.this.scaVTxtFld.setText(DF.format(sight.getAV()));
  259. RBSMainActivity.this.scaHTxtFld.setText(DF.format(sight.getAH()));
  260. RBSMainActivity.this.scVertScaleRngTxtFld.setText(DF.format(sight.getVertSkalaRangeMin()) + "-"
  261. + DF.format(sight.getVertSkalaRangeMax()));
  262. } else {
  263. RBSMainActivity.this.scHeVSSpinner.setVisibility(View.INVISIBLE);
  264. RBSMainActivity.this.scHeVSSpinner.setLayoutParams(new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSSpinner.getLayoutParams().width,
  265. RBSMainActivity.this.scHeVSSpinner.getLayoutParams().height,
  266. 0f));
  267. RBSMainActivity.this.scHeVSTxtFld.setVisibility(View.VISIBLE);
  268. RBSMainActivity.this.scHeVSTxtFld.setLayoutParams(new LinearLayout.LayoutParams(RBSMainActivity.this.scHeVSTxtFld.getLayoutParams().width,
  269. RBSMainActivity.this.scHeVSTxtFld.getLayoutParams().height,
  270. 1f));
  271. RBSMainActivity.this.scHeVSSpinner.setAdapter(new FontArrayAdapter<String>(RBSMainActivity.this,
  272. R.layout.rbs_spinner,
  273. new ArrayList<String>(),
  274. RBSMainActivity.this.scHeVSSpinner));
  275. RBSMainActivity.this.scaVTxtFld.setText("");
  276. RBSMainActivity.this.scaHTxtFld.setText("");
  277. RBSMainActivity.this.scVertScaleRngTxtFld.setText("");
  278. }
  279. RBSMainActivity.this.scaVTxtFld.setEnabled(sight.getId() == -999);
  280. RBSMainActivity.this.scaHTxtFld.setEnabled(sight.getId() == -999);
  281. RBSMainActivity.this.scVertScaleRngTxtFld.setEnabled(sight.getId() == -999);
  282. }
  283. @Override
  284. public void onNothingSelected(final AdapterView<?> parent) { }
  285. });
  286. }
  287. private void addTouchListeners() {
  288. // Scrollview muss den Swipe selbst handeln
  289. this.paramsScrollView.setOnTouchListener(new OnTouchListener() {
  290. private float downX, downY, upX, upY;
  291. @Override
  292. public boolean onTouch(final View v, final MotionEvent event) {
  293. switch (event.getAction()) {
  294. case MotionEvent.ACTION_DOWN: {
  295. this.downX = event.getX();
  296. this.downY = event.getY();
  297. }
  298. case MotionEvent.ACTION_UP: {
  299. this.upX = event.getX();
  300. this.upY = event.getY();
  301. float deltaX = this.upX - this.downX;
  302. float deltaY = this.upY - this.downY;
  303. // swipe from right to left ?
  304. if (deltaX < 0 && Math.abs(deltaX) > MIN_DISTANCE && Math.abs(deltaY) < MIN_DISTANCE) {
  305. // set the required Animation type to ViewFlipper
  306. // The Next screen will come in form Right and current Screen will go OUT to Left
  307. RBSMainActivity.this.viewFlipper.setInAnimation(RBSMainActivity.this, R.anim.in_from_right);
  308. RBSMainActivity.this.viewFlipper.setOutAnimation(RBSMainActivity.this, R.anim.out_to_left);
  309. // Show The Next Screen
  310. RBSMainActivity.this.viewFlipper.showNext();
  311. deactivateXTextView(RBSMainActivity.this.txtViewParams);
  312. xTextViewUp(RBSMainActivity.this.txtViewResults);
  313. deactivateXTextView(RBSMainActivity.this.txtViewSight);
  314. }
  315. }
  316. }
  317. return false;
  318. }
  319. });
  320. // Scrollview muss den Swipe selbst handeln
  321. this.sightCfgScrollView.setOnTouchListener(new OnTouchListener() {
  322. private float downX, downY, upX, upY;
  323. @Override
  324. public boolean onTouch(final View v, final MotionEvent event) {
  325. switch (event.getAction()) {
  326. case MotionEvent.ACTION_DOWN: {
  327. this.downX = event.getX();
  328. this.downY = event.getY();
  329. }
  330. case MotionEvent.ACTION_UP: {
  331. this.upX = event.getX();
  332. this.upY = event.getY();
  333. float deltaX = this.upX - this.downX;
  334. float deltaY = this.upY - this.downY;
  335. // swipe from left to right?
  336. if (deltaX > 0 && Math.abs(deltaX) > MIN_DISTANCE && Math.abs(deltaY) < MIN_DISTANCE) {
  337. // set the required Animation type to ViewFlipper
  338. // The Next screen will come in form Right and current Screen will go OUT to Left
  339. RBSMainActivity.this.viewFlipper.setInAnimation(RBSMainActivity.this, R.anim.in_from_left);
  340. RBSMainActivity.this.viewFlipper.setOutAnimation(RBSMainActivity.this, R.anim.out_to_right);
  341. // Show The Next Screen
  342. RBSMainActivity.this.viewFlipper.showPrevious();
  343. deactivateXTextView(RBSMainActivity.this.txtViewSight);
  344. xTextViewUp(RBSMainActivity.this.txtViewResults);
  345. deactivateXTextView(RBSMainActivity.this.txtViewParams);
  346. }
  347. }
  348. }
  349. return false;
  350. }
  351. });
  352. // Touchlistener für die oberen 3 Tabs
  353. OnTouchListener tabListener = new OnTouchListener() {
  354. @Override
  355. public boolean onTouch(final View v, final MotionEvent event) {
  356. switch (event.getAction()) {
  357. case MotionEvent.ACTION_DOWN: {
  358. deactivateAllXTextView();
  359. xTextViewDown((XTextView) v);
  360. return true;
  361. }
  362. case MotionEvent.ACTION_UP: {
  363. RBSMainActivity.this.viewFlipper.setInAnimation(RBSMainActivity.this, R.anim.in_from_right);
  364. RBSMainActivity.this.viewFlipper.setOutAnimation(RBSMainActivity.this, R.anim.out_to_left);
  365. if (v == RBSMainActivity.this.txtViewParams) {
  366. if (RBSMainActivity.this.viewFlipper.getDisplayedChild() != 0) {
  367. RBSMainActivity.this.viewFlipper.setDisplayedChild(0);
  368. }
  369. } else if (v == RBSMainActivity.this.txtViewResults) {
  370. if (RBSMainActivity.this.viewFlipper.getDisplayedChild() != 1) {
  371. RBSMainActivity.this.viewFlipper.setDisplayedChild(1);
  372. }
  373. } else {
  374. if (RBSMainActivity.this.viewFlipper.getDisplayedChild() != 2) {
  375. RBSMainActivity.this.viewFlipper.setDisplayedChild(2);
  376. }
  377. }
  378. xTextViewUp((XTextView) v);
  379. return true;
  380. }
  381. }
  382. return false;
  383. }
  384. };
  385. // Touchlistener an Tabs anhängen
  386. this.txtViewParams.setOnTouchListener(tabListener);
  387. this.txtViewResults.setOnTouchListener(tabListener);
  388. this.txtViewSight.setOnTouchListener(tabListener);
  389. this.calcSettingBtn.setOnClickListener(new OnClickListener() {
  390. @Override
  391. public void onClick(final View v) {
  392. calculateSettings();
  393. }
  394. });
  395. }
  396. @Override
  397. public boolean onPrepareOptionsMenu(final Menu menu) {
  398. int size = menu.size();
  399. for (int i = size - 1; i >= 0; i--) {
  400. menu.removeItem(menu.getItem(i).getItemId());
  401. }
  402. if (this.showInfoMenu) {
  403. this.showInfoMenu = false;
  404. getMenuInflater().inflate(R.menu.rbs_info_menu, menu);
  405. } else {
  406. getMenuInflater().inflate(R.menu.rbs_main, menu);
  407. }
  408. return true;
  409. }
  410. @Override
  411. public boolean onOptionsItemSelected(final MenuItem item) {
  412. // Handle item selection
  413. switch (item.getItemId()) {
  414. case R.id.chooseConfiguration:
  415. showDialog(DLG_CHOOSE_ARCHERYSETUP);
  416. return true;
  417. case R.id.doCalculation:
  418. calculate();
  419. return true;
  420. case R.id.addConfiguration:
  421. // ************************************************************************
  422. // ** TEST WEISE AB HIER***************************************************
  423. // ************************************************************************
  424. // this.listView1 = (ListView) findViewById(R.id.listView1);
  425. //
  426. // String[] values = new String[] { "Riser", "Sight", "General Config" };
  427. //
  428. // final ArrayList<String> list = new ArrayList<String>(Arrays.asList(values));
  429. // final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
  430. // this.listView1.setAdapter(adapter);
  431. // this.listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  432. //
  433. // @Override
  434. // public void onItemClick(final AdapterView<?> parent, final View view, final int position,
  435. // final long id) {
  436. // final String item = (String) parent.getItemAtPosition(position);
  437. // if (item.equals("Riser")) {
  438. Intent intent = new Intent(RBSMainActivity.this, RiserSightConfigurationActivity.class);
  439. startActivity(intent);
  440. // }
  441. // }
  442. // });
  443. return true;
  444. case R.id.moreItems:
  445. this.showInfoMenu = true;
  446. closeOptionsMenu();
  447. new Handler().post(new Runnable() {
  448. @Override
  449. public void run() {
  450. openOptionsMenu();
  451. }
  452. });
  453. return true;
  454. default:
  455. return super.onOptionsItemSelected(item);
  456. }
  457. }
  458. @Override
  459. public boolean onTouchEvent(final MotionEvent touchevent) {
  460. switch (touchevent.getAction()) {
  461. // when user first touches the screen to swap
  462. case MotionEvent.ACTION_DOWN: {
  463. this.lastX = touchevent.getX();
  464. break;
  465. }
  466. case MotionEvent.ACTION_UP: {
  467. float currentX = touchevent.getX();
  468. // if right to left swipe on screen
  469. if (this.lastX > currentX) {
  470. if (this.viewFlipper.getDisplayedChild() == 2) {
  471. break;
  472. }
  473. // set the required Animation type to ViewFlipper
  474. // The Next screen will come in form Right and current Screen will go OUT to Left
  475. this.viewFlipper.setInAnimation(this, R.anim.in_from_right);
  476. this.viewFlipper.setOutAnimation(this, R.anim.out_to_left);
  477. // Show The Next Screen
  478. this.viewFlipper.showNext();
  479. } else if (this.lastX < currentX) { // if left to right swipe on screen
  480. // If no more View/Child to flip
  481. if (this.viewFlipper.getDisplayedChild() == 0) {
  482. break;
  483. }
  484. // set the required Animation type to ViewFlipper
  485. // The Next screen will come in form Left and current Screen will go OUT to Right
  486. this.viewFlipper.setInAnimation(this, R.anim.in_from_left);
  487. this.viewFlipper.setOutAnimation(this, R.anim.out_to_right);
  488. // Show the previous Screen
  489. this.viewFlipper.showPrevious();
  490. }
  491. deactivateAllXTextView();
  492. switch (this.viewFlipper.getDisplayedChild()) {
  493. case 0:
  494. xTextViewUp(this.txtViewParams);
  495. break;
  496. case 1:
  497. xTextViewUp(this.txtViewResults);
  498. break;
  499. case 2:
  500. xTextViewUp(this.txtViewSight);
  501. break;
  502. default:
  503. break;
  504. }
  505. break;
  506. }
  507. }
  508. return false;
  509. }
  510. private void xTextViewDown(final XTextView view) {
  511. view.setDrawborderColor(getResources().getColor(R.color.android_yellow_dark));
  512. view.setTextColor(getResources().getColor(R.color.android_yellow_dark));
  513. }
  514. private void xTextViewUp(final XTextView view) {
  515. view.setDrawborderColor(getResources().getColor(R.color.android_yellow));
  516. view.setTextColor(getResources().getColor(R.color.android_yellow));
  517. }
  518. private void deactivateXTextView(final XTextView view) {
  519. view.setDrawborderColor(getResources().getColor(R.color.white));
  520. view.setTextColor(getResources().getColor(R.color.white));
  521. }
  522. private void deactivateAllXTextView() {
  523. deactivateXTextView(this.txtViewParams);
  524. deactivateXTextView(this.txtViewResults);
  525. deactivateXTextView(this.txtViewSight);
  526. }
  527. @Override
  528. protected Dialog onCreateDialog(final int id) {
  529. return DialogFactory.createDialog(id, this);
  530. }
  531. @Override
  532. public void onArcherySetupDlgDismissed(final IArcherySetup archerySetup) {
  533. this.selectedArcherySetup = archerySetup;
  534. if (archerySetup != null && archerySetup.getId() != -999) {
  535. this.arrowDiameterTxtFld.setText(DF.format(archerySetup.getArrowDiameter()));
  536. this.arrowCwTxtFld.setText(DF.format(archerySetup.getArrowCw()));
  537. this.arrowWeightTxtFld.setText(DF.format(archerySetup.getArrowWeight()));
  538. this.bowPulloutTxtFld.setText(DF.format(archerySetup.getBowPullout()));
  539. this.arrowV0TxtFld.setText(DF.format(archerySetup.getArrowV0()));
  540. this.arrowNockHeightTxtFld.setText(DF_1.format(archerySetup.getArrowNockHeight()));
  541. this.targetCenterHeightTxtFld.setText(DF_1.format(archerySetup.getArrowCenterHeight()));
  542. this.calcTimeIntervalCboBox.setSelectionByVal(archerySetup.getDeltaTime().toString());
  543. this.calcAccuracyCboBox.setSelectionByVal(archerySetup.getCalcPrecision().toString());
  544. this.scRiserSpinner.setSelectedRiser(archerySetup.getRiser());
  545. this.scRiserSpinner.fireSelectionChangedEvent();
  546. this.scSightSpinner.setSelectedSight(archerySetup.getSight());
  547. this.scSightSpinner.fireSelectionChangedEvent();
  548. this.scVertScaleMiddleTxtFld.setText(DF.format(archerySetup.getSightVertSkalaMiddle()));
  549. this.airTemperatureTxtFld.setText("25");
  550. this.airRelativeHumidityTxtFld.setText("50");
  551. this.shootingDistanzTxtFld.setText("18");
  552. } else {
  553. this.arrowDiameterTxtFld.setText("");
  554. this.arrowDiameterTxtFld.setText("");
  555. this.arrowCwTxtFld.setText("");
  556. this.arrowWeightTxtFld.setText("");
  557. this.bowPulloutTxtFld.setText("");
  558. this.arrowV0TxtFld.setText("");
  559. this.arrowNockHeightTxtFld.setText("");
  560. this.targetCenterHeightTxtFld.setText("");
  561. this.calcTimeIntervalCboBox.setSelectionByVal("");
  562. this.calcAccuracyCboBox.setSelectionByVal("");
  563. this.scRiserSpinner.setSelection(0);
  564. this.scRiserSpinner.fireSelectionChangedEvent();
  565. this.scSightSpinner.setSelection(0);
  566. this.scSightSpinner.fireSelectionChangedEvent();
  567. this.scVertScaleMiddleTxtFld.setText("");
  568. }
  569. }
  570. private boolean allParamFieldsValid() {
  571. return !this.arrowDiameterTxtFld.getText().toString().isEmpty()
  572. && !this.arrowCwTxtFld.getText().toString().isEmpty()
  573. && !this.arrowWeightTxtFld.getText().toString().isEmpty()
  574. && !this.bowPulloutTxtFld.getText().toString().isEmpty()
  575. && !this.arrowV0TxtFld.getText().toString().isEmpty()
  576. && !this.airTemperatureTxtFld.getText().toString().isEmpty()
  577. && !this.airRelativeHumidityTxtFld.getText().toString().isEmpty()
  578. && !this.shootingDistanzTxtFld.getText().toString().isEmpty()
  579. && !this.arrowNockHeightTxtFld.getText().toString().isEmpty()
  580. && !this.targetCenterHeightTxtFld.getText().toString().isEmpty()
  581. && this.calcTimeIntervalCboBox.getSelectedItem() != null
  582. && this.calcAccuracyCboBox.getSelectedItem() != null
  583. && allSightParamFieldsValid();
  584. }
  585. private boolean allSightParamFieldsValid() {
  586. return !this.scVvisHTxtFld.getText().toString().isEmpty()
  587. && !this.scVvisVTxtFld.getText().toString().isEmpty()
  588. && !this.scaHTxtFld.getText().toString().isEmpty()
  589. && !this.scaVTxtFld.getText().toString().isEmpty()
  590. && !this.scVertScaleRngTxtFld.getText().toString().isEmpty()
  591. && ((this.scHeVSSpinner.getVisibility() == View.VISIBLE && this.scHeVSSpinner.getSelectedItem() != null)
  592. || (this.scHeVSTxtFld.getVisibility() == View.VISIBLE && !this.scHeVSTxtFld.getText().toString().isEmpty()))
  593. && !this.scVertScaleMiddleTxtFld.getText().toString().isEmpty();
  594. }
  595. /**
  596. * Startet die Berechnung wenn alle notwendigen Felder gefüllt sind.
  597. */
  598. private void calculate() {
  599. if (allParamFieldsValid()) {
  600. InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
  601. if (getCurrentFocus() != null) {
  602. imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
  603. }
  604. CalculationTask calcTask = new CalculationTask();
  605. TrajectoryCalculator calculator = new TrajectoryCalculator(Double.valueOf(this.arrowDiameterTxtFld.getText().toString().trim()) * MILLI, //
  606. Double.valueOf(this.arrowCwTxtFld.getText().toString().trim()), //
  607. Double.valueOf(this.arrowWeightTxtFld.getText().toString().trim()) * MILLI, //
  608. Double.valueOf(this.arrowV0TxtFld.getText().toString().trim()), //
  609. Double.valueOf(this.shootingDistanzTxtFld.getText().toString().trim()), //
  610. Double.valueOf(this.targetCenterHeightTxtFld.getText().toString().trim())
  611. - Double.valueOf(this.arrowNockHeightTxtFld.getText().toString().trim()), //
  612. Double.valueOf(this.airTemperatureTxtFld.getText().toString().trim()), //
  613. Double.valueOf(this.airRelativeHumidityTxtFld.getText().toString().trim())
  614. * CENTI, //
  615. Double.valueOf(this.calcTimeIntervalCboBox.getSelectedItem().toString().trim()), //
  616. Double.valueOf(this.calcAccuracyCboBox.getSelectedItem().toString().trim())
  617. * CENTI, //
  618. this);
  619. calculator.setStartAngle(0d);
  620. calcTask.execute(calculator);
  621. this.calculationAlert.show();
  622. } else {
  623. Toast toast = Toast.makeText(this, getResources().getString(R.string.caption_FillAllMandatoryFields), Toast.LENGTH_LONG);
  624. toast.setGravity(Gravity.CENTER, 0, 0);
  625. toast.show();
  626. }
  627. }
  628. @Override
  629. public void onCalculationDone(final Double[][] flightCurve, final Double startAngle, final Double[] maxHCurve) {
  630. this.startAngle = startAngle;
  631. this.flightCurveTxtFld.setText("");
  632. this.flightCurveTxtFld.append("Abschusswinkel:" + TAB + DF_FC.format(startAngle) + " °\n");
  633. this.flightCurveTxtFld.append("Max. Höhe der Flugbahn:" + TAB + DF_FC.format(maxHCurve[0])
  634. + " m / " + DF_FC.format(maxHCurve[0] + Double.valueOf(this.arrowNockHeightTxtFld.getText().toString().trim()))
  635. + " m, [t = " + DF_FC.format(maxHCurve[1]) + " s]\n");
  636. this.flightCurveTxtFld.append("Flugzeit:" + TAB + TAB
  637. + DF_FC.format(flightCurve[flightCurve.length - 1][TrajectoryCalculator.IDX_T])
  638. + " sec\n\n");
  639. SpannableString line = new SpannableString("t [sec]\tVx [m/s]\tVy [m/s]\tx [m]\ty [m]\n\n");
  640. line.setSpan(new TabStopSpan.Standard(100), 7, 9, 0);
  641. line.setSpan(new TabStopSpan.Standard(200), 17, 19, 0);
  642. line.setSpan(new TabStopSpan.Standard(300), 27, 29, 0);
  643. line.setSpan(new TabStopSpan.Standard(400), 34, 36, 0);
  644. this.flightCurveTxtFld.append(line);
  645. // this.flightCurveTxtFld.append("t [sec]" + TAB + TAB + "Vx [m/s]" + TAB + TAB + "Vy [m/s]" + TAB + TAB + "x [m]" + TAB + TAB + "y [m]\n\n");
  646. //
  647. // for (int i = 0; i < flightCurve.length; i++) {
  648. // Double[] r1 = flightCurve[i];
  649. // StringBuffer line = new StringBuffer();
  650. // line.append(DF_FC.format(r1[TrajectoryCalculator.IDX_T]) + TAB + TAB
  651. // + DF_FC.format(r1[TrajectoryCalculator.IDX_VX]) + TAB + TAB + TAB
  652. // + DF_FC.format(r1[TrajectoryCalculator.IDX_VY]) + TAB + TAB + TAB + TAB
  653. // + DF_FC.format(r1[TrajectoryCalculator.IDX_X]) + TAB + TAB
  654. // + DF_FC.format(r1[TrajectoryCalculator.IDX_Y]) + "\n");
  655. // this.flightCurveTxtFld.append(line.toString());
  656. // }
  657. calculateSettings();
  658. if (this.calculationAlert != null) {
  659. this.calculationAlert.dismiss();
  660. }
  661. this.txtViewSight.doSingleTouch();
  662. }
  663. /**
  664. * Berechnet die definitve Visiereinstellung anhand des berechneten Flugbahnwinkels.
  665. */
  666. private void calculateSettings() {
  667. if (allSightParamFieldsValid() && this.selectedArcherySetup != null && this.startAngle != null) {
  668. Double x0;
  669. Double y0;
  670. Double x1;
  671. Double y1;
  672. Double x2;
  673. Double y2;
  674. Double x3;
  675. Double y3;
  676. Double r;
  677. Double s;
  678. Double vVh = Double.valueOf(this.scVvisHTxtFld.getText().toString()) + Double.valueOf(this.scaHTxtFld.getText().toString());
  679. Double vVv = Double.valueOf(this.scVvisVTxtFld.getText().toString()) + Double.valueOf(this.scaVTxtFld.getText().toString());
  680. Double a = Double.valueOf(this.bowPulloutTxtFld.getText().toString()) * 10;
  681. Double heVs = this.scHeVSSpinner.getVisibility() == View.VISIBLE ? Double.valueOf(this.scHeVSSpinner.getSelectedItem().toString()) : Double.valueOf(this.scHeVSTxtFld.getText().toString());
  682. Double lhNA = this.selectedArcherySetup.getHNA() * 10;
  683. Double dltH = (Double.valueOf(this.targetCenterHeightTxtFld.getText().toString())
  684. - Double.valueOf(this.arrowNockHeightTxtFld.getText().toString())) * Math.pow(10, 3);
  685. Double ldistH = Double.valueOf(this.shootingDistanzTxtFld.getText().toString()) * Math.pow(10, 3);
  686. Double minSkala = this.scVertScaleRngTxtFld.getText().toString().contains("-") ? Double.valueOf(this.scVertScaleRngTxtFld.getText().toString().substring(0,
  687. this.scVertScaleRngTxtFld.getText().toString().indexOf('-'))) : 0d;
  688. Double maxSkala = this.scVertScaleRngTxtFld.getText().toString().contains("-") ? Double.valueOf(this.scVertScaleRngTxtFld.getText().toString().substring(this.scVertScaleRngTxtFld.getText().toString().indexOf('-') + 1,
  689. this.scVertScaleRngTxtFld.getText().toString().length())) : 0d;
  690. // PIN auf Höhe Pfeil
  691. x0 = (a + vVh + heVs) * Math.cos(Math.toRadians(this.startAngle));
  692. y0 = (a + vVh + heVs) * Math.sin(Math.toRadians(this.startAngle));
  693. // PIN auf Höhe Horizontalschlitten Visier
  694. x2 = x0 + vVv * Math.cos(Math.toRadians(ANGLE_90 + this.startAngle));
  695. y2 = y0 + vVv * Math.sin(Math.toRadians(ANGLE_90 + this.startAngle));
  696. // Schnittpunkt der Achse Horizontalschlitten Visier mit Achse Befestigungslöcher Visier
  697. x3 = (a + vVh) * Math.cos(Math.toRadians(this.startAngle)) + vVv * Math.cos(Math.toRadians(ANGLE_90 + this.startAngle));
  698. y3 = (a + vVh) * Math.sin(Math.toRadians(this.startAngle)) + vVv * Math.sin(Math.toRadians(ANGLE_90 + this.startAngle));
  699. // Unbekannte der Vektorgeradengleichung
  700. r = (lhNA * (x0 - x2) - x0 * y2 + x2 * y0) / (ldistH * (y0 - y2) + (dltH - lhNA) * (x2 - x0));
  701. s = -((ldistH * (lhNA - y0) + (dltH - lhNA) * x0) / (ldistH * (y0 - y2) + (dltH - lhNA) * (x2 - x0)));
  702. // Pin auf Visierlinie
  703. x1 = r * ldistH;
  704. y1 = lhNA + r * (dltH - lhNA);
  705. // Unten (+) oder oben (-) von (x2/y2) ?
  706. Double n = ((y2 - y3) * (x1 - x3) - (x2 - x3) * (y1 - y3)) < 0 ? -1.0 : 1.0;
  707. // Abstand P1 - P2
  708. Double d = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) * n;
  709. // Einstellung auf vert. Skala
  710. Double sV = Double.valueOf(this.scVertScaleMiddleTxtFld.getText().toString()) + d;
  711. this.scEvSValue.setText(DF_EVS.format(sV));
  712. if (minSkala <= sV && sV <= maxSkala) {
  713. this.scEvSValue.setBackgroundDrawable(getResources().getDrawable(R.drawable.evs_ok_background));
  714. } else {
  715. this.scEvSValue.setBackgroundDrawable(getResources().getDrawable(R.drawable.evs_nok_background));
  716. }
  717. } else {
  718. this.scEvSValue.setText("");
  719. Toast toast = Toast.makeText(this, getResources().getString(R.string.caption_FillAllMandatoryFields), Toast.LENGTH_LONG);
  720. toast.setGravity(Gravity.CENTER, 0, 0);
  721. toast.show();
  722. }
  723. }
  724. }