From: kruland2607 Date: Sun, 22 Jan 2012 02:44:17 +0000 (+0000) Subject: Various changes to android application. Separate the loading of an ork file into... X-Git-Tag: upstream/12.03~1^2~108 X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=3cdaf29f3018779f7429823a628b63cad8f901b1;p=debian%2Fopenrocket Various changes to android application. Separate the loading of an ork file into the OpenRocketLoader activity. Changed OpenRocketViewer to use Fragments for each of the tab contents. Added Component, Overview and Simulations fragments for the tabs in OpenRocketViewer. Modified the graphics on the UI. Have the PreferencesActivity pack the changed preferences into the application onStop(). git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@363 180e2498-e6e9-4542-8430-84ac67f01cd8 --- diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 6ae3d51f..e0b9dba3 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -27,7 +27,7 @@ @@ -61,6 +61,9 @@ android:scheme="file" /> + @@ -68,16 +71,12 @@ - + - + - + \ No newline at end of file diff --git a/android/res/drawable/ic_menu_preferences.png b/android/res/drawable/ic_menu_preferences.png new file mode 100644 index 00000000..b8e71412 Binary files /dev/null and b/android/res/drawable/ic_menu_preferences.png differ diff --git a/android/res/drawable/or_launcher.png b/android/res/drawable/or_launcher.png index c2170d35..77464db0 100644 Binary files a/android/res/drawable/or_launcher.png and b/android/res/drawable/or_launcher.png differ diff --git a/android/res/layout/openrocketviewer.xml b/android/res/layout/openrocketviewer.xml index 25d7d9b4..efb2b6be 100644 --- a/android/res/layout/openrocketviewer.xml +++ b/android/res/layout/openrocketviewer.xml @@ -1,144 +1,33 @@ - + android:layout_height="match_parent"> - + android:layout_height="match_parent"> - + android:layout_height="wrap_content" + android:layout_weight="0"/> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - \ No newline at end of file + + diff --git a/android/res/layout/rocket_component.xml b/android/res/layout/rocket_component.xml new file mode 100644 index 00000000..40c3ba2c --- /dev/null +++ b/android/res/layout/rocket_component.xml @@ -0,0 +1,7 @@ + + diff --git a/android/res/layout/rocket_overview.xml b/android/res/layout/rocket_overview.xml new file mode 100644 index 00000000..7eca8962 --- /dev/null +++ b/android/res/layout/rocket_overview.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/res/layout/rocket_simulations.xml b/android/res/layout/rocket_simulations.xml new file mode 100644 index 00000000..e856d1e9 --- /dev/null +++ b/android/res/layout/rocket_simulations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/android/res/menu/main_menu.xml b/android/res/menu/main_menu.xml new file mode 100644 index 00000000..f378ed0f --- /dev/null +++ b/android/res/menu/main_menu.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/android/res/menu/rocket_viewer_option_menu.xml b/android/res/menu/rocket_viewer_option_menu.xml index 6d4f5c6f..4ebd72d4 100644 --- a/android/res/menu/rocket_viewer_option_menu.xml +++ b/android/res/menu/rocket_viewer_option_menu.xml @@ -1,8 +1,12 @@ - - - - + + + \ No newline at end of file diff --git a/android/res/values/pref_strings.xml b/android/res/values/pref_strings.xml new file mode 100644 index 00000000..5bf18212 --- /dev/null +++ b/android/res/values/pref_strings.xml @@ -0,0 +1,54 @@ + + + + PreferenceMotorBrowserGroupingOption + + PreferenceUseInternalFileBrowserOpion + + + 0 + 1 + 2 + 3 + + + PreferenceUnitLengthOption + + + mm + cm + m + in + ft + + + PreferenceUnitMassOption + + + g + kg + oz + lb + + + PreferenceUnitVelocityOption + + + m/s + km/h + ft/s + mph + + + PreferenceUnitDistanceOption + + + m + km + ft + yd + mi + nmi + + + \ No newline at end of file diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 5d7b232f..eeb1b494 100644 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -4,7 +4,7 @@ OpenRocket Save Motor List - PreferenceMotorBrowserGroupingOption + Preferences Case @@ -12,12 +12,6 @@ Impulse Manufacturer - - 0 - 1 - 2 - 3 - Impulse @@ -96,8 +90,11 @@ Download from ThrustCurve Series 1 Series 2 - PreferenceUnitLengthOption + Motor Browser Grouping + Use Internal File Browser + uncheck to use system file browser if available + Millimeters Centimeters @@ -105,46 +102,18 @@ Inches Feet - - mm - cm - m - in - ft - - - PreferenceUnitMassOption - Grams Kilograms Ounces Pounds - - g - kg - oz - lb - - - PreferenceUnitVelocityOption - Meters/Second Kilometers/Hour Feet/Second Miles/Hour - - m/s - km/h - ft/s - mph - - - PreferenceUnitDistanceOption - Meters Kilometers @@ -153,13 +122,5 @@ Miles Nautical Miles - - m - km - ft - yd - mi - nmi - \ No newline at end of file diff --git a/android/res/xml/preferences.xml b/android/res/xml/preferences.xml index d229d6ef..77b1cdef 100644 --- a/android/res/xml/preferences.xml +++ b/android/res/xml/preferences.xml @@ -1,50 +1,55 @@ - android:key="preferences" android:title="Pref Title" android:summary="pref summary" - - + android:title="@string/motorbrowsergrouptitle" /> - - - - - + + + + + + + + \ No newline at end of file diff --git a/android/src/net/sf/openrocket/android/ActivityHelpers.java b/android/src/net/sf/openrocket/android/ActivityHelpers.java new file mode 100644 index 00000000..bc6db510 --- /dev/null +++ b/android/src/net/sf/openrocket/android/ActivityHelpers.java @@ -0,0 +1,21 @@ +package net.sf.openrocket.android; + +import net.sf.openrocket.android.motor.MotorHierarchicalBrowser; +import android.app.Activity; +import android.content.Intent; + +public abstract class ActivityHelpers { + + + public static void browseMotors( Activity parent ) { + Intent i = new Intent(parent, MotorHierarchicalBrowser.class); + parent.startActivity(i); + + } + + public static void startPreferences( Activity parent ) { + Intent intent = new Intent(parent, PreferencesActivity.class); + parent.startActivity(intent); + + } +} diff --git a/android/src/net/sf/openrocket/android/Main.java b/android/src/net/sf/openrocket/android/Main.java index cdb7366a..ff5fd8de 100644 --- a/android/src/net/sf/openrocket/android/Main.java +++ b/android/src/net/sf/openrocket/android/Main.java @@ -2,15 +2,20 @@ package net.sf.openrocket.android; import net.sf.openrocket.R; import net.sf.openrocket.android.filebrowser.SimpleFileBrowser; -import net.sf.openrocket.android.motor.MotorHierarchicalBrowser; -import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Resources; import android.net.Uri; import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.FragmentActivity; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; -public class Main extends Activity { +public class Main extends FragmentActivity { private static final int PICK_ORK_FILE_RESULT = 1; @@ -21,6 +26,29 @@ public class Main extends Activity { setContentView(R.layout.main); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch( item.getItemId() ) { + case R.id.main_menu_motor: + ActivityHelpers.browseMotors(this); + return true; + case R.id.main_menu_open: + pickOrkFiles(); + return true; + case R.id.main_menu_preferences: + ActivityHelpers.startPreferences(this); + return true; + } + return super.onOptionsItemSelected(item); + } + /* (non-Javadoc) * @see android.app.Activity#onActivityResult(int, int, android.content.Intent) */ @@ -39,21 +67,37 @@ public class Main extends Activity { super.onActivityResult(requestCode, resultCode, data); } - public void pickOrkFiles( View v ) { - try { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.setType("file/*"); - startActivityForResult(intent,PICK_ORK_FILE_RESULT); - } catch ( ActivityNotFoundException ex ) { - // No activity for ACTION_GET_CONTENT use internal file browser + private void pickOrkFiles( ) { + Resources resources = this.getResources(); + String key = resources.getString(R.string.PreferenceUseInternalFileBrowserOption); + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); + + boolean useinternalbrowser = pref.getBoolean(key, false); + + if ( useinternalbrowser ) { Intent intent = new Intent(Main.this, SimpleFileBrowser.class); startActivityForResult(intent,PICK_ORK_FILE_RESULT); - } + } else { + try { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("file/*"); + startActivityForResult(intent,PICK_ORK_FILE_RESULT); + } catch ( ActivityNotFoundException ex ) { + // No activity for ACTION_GET_CONTENT use internal file browser + // update the preference value. + pref.edit().putBoolean(key, false).commit(); + // fire our browser + Intent intent = new Intent(Main.this, SimpleFileBrowser.class); + startActivityForResult(intent,PICK_ORK_FILE_RESULT); + } + } + } + public void pickOrkFiles( View v ) { + pickOrkFiles(); } public void browseMotors( View v ) { - Intent i = new Intent(Main.this, MotorHierarchicalBrowser.class); - startActivity(i); + ActivityHelpers.browseMotors(this); } } diff --git a/android/src/net/sf/openrocket/android/PreferencesActivity.java b/android/src/net/sf/openrocket/android/PreferencesActivity.java index 5b14bf23..9680c9e8 100644 --- a/android/src/net/sf/openrocket/android/PreferencesActivity.java +++ b/android/src/net/sf/openrocket/android/PreferencesActivity.java @@ -52,5 +52,13 @@ implements SharedPreferences.OnSharedPreferenceChangeListener { UnitGroup.UNITS_DISTANCE.setDefaultUnit( distance ); } + + @Override + protected void onStop() { + initializePreferences(getApplication(), PreferenceManager.getDefaultSharedPreferences(this)); + super.onStop(); + } + + } diff --git a/android/src/net/sf/openrocket/android/motor/BurnPlotFragment.java b/android/src/net/sf/openrocket/android/motor/BurnPlotFragment.java index 96ff0845..49373762 100644 --- a/android/src/net/sf/openrocket/android/motor/BurnPlotFragment.java +++ b/android/src/net/sf/openrocket/android/motor/BurnPlotFragment.java @@ -42,12 +42,6 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener { private ScaleGestureDetector mScaleDetector; private float mScaleFactor = 1.f; - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - Log.d(TAG,"onAttach"); - } - @Override public void onCreate(Bundle savedInstanceState) { Log.d(TAG,"onCreate"); diff --git a/android/src/net/sf/openrocket/android/rocket/Component.java b/android/src/net/sf/openrocket/android/rocket/Component.java new file mode 100644 index 00000000..a19f2e7c --- /dev/null +++ b/android/src/net/sf/openrocket/android/rocket/Component.java @@ -0,0 +1,76 @@ +package net.sf.openrocket.android.rocket; + +import net.sf.openrocket.R; +import net.sf.openrocket.android.Application; +import net.sf.openrocket.android.rocket.RocketComponentTreeAdapter.RocketComponentWithId; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import pl.polidea.treeview.InMemoryTreeStateManager; +import pl.polidea.treeview.TreeBuilder; +import pl.polidea.treeview.TreeStateManager; +import pl.polidea.treeview.TreeViewList; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListAdapter; + +public class Component extends Fragment { + + private TreeViewList componentTree; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.rocket_component, container, false); + componentTree = (TreeViewList) v.findViewById(R.id.openrocketviewerComponentTree); + + return v; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument(); + componentTree.setAdapter( buildAdapter( rocketDocument.getRocket() ) ); + } + + private ListAdapter buildAdapter( Rocket rocket ) { + + TreeStateManager manager = new InMemoryTreeStateManager(); + TreeBuilder treeBuilder = new TreeBuilder(manager); + + int depth = buildRecursive( rocket, treeBuilder, 0 ); + return new RocketComponentTreeAdapter(this.getActivity(), manager, depth+1); + } + + long id = 0; + private int buildRecursive( RocketComponent comp, TreeBuilder builder, int depth ) { + + + int maxDepth = depth; + + RocketComponentWithId rcid = new RocketComponentWithId(comp, id++); + + // Add this component. + builder.sequentiallyAddNextNode(rcid, depth); + + if ( comp.allowsChildren() ) { + + for( RocketComponent child : comp.getChildren() ) { + int childDepth = buildRecursive( child, builder, depth+1); + if ( childDepth > maxDepth) { + maxDepth = childDepth; + } + } + + } + + return maxDepth; + } + + +} diff --git a/android/src/net/sf/openrocket/android/rocket/OpenRocketLoader.java b/android/src/net/sf/openrocket/android/rocket/OpenRocketLoader.java new file mode 100644 index 00000000..ee35ba00 --- /dev/null +++ b/android/src/net/sf/openrocket/android/rocket/OpenRocketLoader.java @@ -0,0 +1,79 @@ +package net.sf.openrocket.android.rocket; + +import java.io.File; + +import net.sf.openrocket.R; +import net.sf.openrocket.android.Application; +import net.sf.openrocket.document.OpenRocketDocument; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; + +public class OpenRocketLoader extends FragmentActivity { + private static final String TAG = "OpenRocketLoader"; + + private ProgressDialog progress; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + Intent i = getIntent(); + Uri file = i.getData(); + loadOrkFile(file); + } + + @Override + protected void onDestroy() { + if ( progress != null ) { + if ( progress.isShowing() ) { + progress.dismiss(); + } + progress = null; + } + super.onDestroy(); + } + + private void loadOrkFile( Uri file ) { + Log.d(TAG,"Use ork file: " + file); + String path = file.getPath(); + File orkFile = new File(path); + progress = ProgressDialog.show(this, "Loading file", ""); + + final OpenRocketLoaderTask task = new OpenRocketLoaderTask() { + + /* (non-Javadoc) + * @see android.os.AsyncTask#onPostExecute(java.lang.Object) + */ + @Override + protected void onPostExecute(OpenRocketDocument result) { + super.onPostExecute(result); + ((Application)OpenRocketLoader.this.getApplication()).setRocketDocument( result ); + Log.d(TAG,"Finished loading " + OpenRocketLoader.this); + finishedLoading(); + } + + }; + + task.execute(orkFile); + + } + + private void finishedLoading() { + if ( progress.isShowing() ) { + progress.dismiss(); + } + + Intent i = new Intent(this,OpenRocketViewer.class); + startActivity(i); + finish(); + } + + +} diff --git a/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java b/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java index 6985c934..a79beb6e 100644 --- a/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java +++ b/android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java @@ -1,89 +1,42 @@ package net.sf.openrocket.android.rocket; -import java.io.File; - import net.sf.openrocket.R; -import net.sf.openrocket.aerodynamics.AerodynamicCalculator; -import net.sf.openrocket.aerodynamics.BarrowmanCalculator; -import net.sf.openrocket.aerodynamics.FlightConditions; -import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.android.ActivityHelpers; import net.sf.openrocket.android.Application; -import net.sf.openrocket.android.PreferencesActivity; -import net.sf.openrocket.android.motor.MotorHierarchicalBrowser; -import net.sf.openrocket.android.rocket.RocketComponentTreeAdapter.RocketComponentWithId; -import net.sf.openrocket.android.simulation.SimulationViewer; +import net.sf.openrocket.android.util.TabsAdapter; import net.sf.openrocket.document.OpenRocketDocument; -import net.sf.openrocket.document.Simulation; -import net.sf.openrocket.masscalc.BasicMassCalculator; -import net.sf.openrocket.masscalc.MassCalculator; -import net.sf.openrocket.masscalc.MassCalculator.MassCalcType; import net.sf.openrocket.rocketcomponent.Configuration; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.rocketcomponent.RocketUtils; -import net.sf.openrocket.unit.Unit; -import net.sf.openrocket.unit.UnitGroup; -import net.sf.openrocket.util.Coordinate; -import pl.polidea.treeview.InMemoryTreeStateManager; -import pl.polidea.treeview.TreeBuilder; -import pl.polidea.treeview.TreeStateManager; -import pl.polidea.treeview.TreeViewList; -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.Intent; import android.content.SharedPreferences; -import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.support.v4.app.FragmentActivity; +import android.support.v4.view.ViewPager; import android.util.Log; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.Spinner; import android.widget.TabHost; -import android.widget.TextView; -public class OpenRocketViewer extends Activity +public class OpenRocketViewer extends FragmentActivity implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "OpenRocketViewer"; - private ProgressDialog progress; - - private Spinner configurationSpinner; - private TreeViewList componentTree; - private ListView simulationList; - - /* Calculation of CP and CG */ - private AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator(); - private MassCalculator massCalculator = new BasicMassCalculator(); - OpenRocketDocument rocketDocument; Configuration rocketConfiguration; private Application app; - private final static int PICK_ORK_FILE_RESULT = 1; + TabHost mTabHost; + ViewPager mViewPager; + TabsAdapter mTabsAdapter; - /* (non-Javadoc) - * @see android.app.Activity#onCreate(android.os.Bundle) - */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Log.d(TAG,"In onCreate"); - app = (Application) this.getApplication(); setContentView(R.layout.openrocketviewer); @@ -91,89 +44,29 @@ implements SharedPreferences.OnSharedPreferenceChangeListener SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); prefs.registerOnSharedPreferenceChangeListener(this); - TabHost tabs=(TabHost)findViewById(R.id.openrocketviewerTabHost); - - tabs.setup(); - - TabHost.TabSpec spec=tabs.newTabSpec("tag1"); + mTabHost = (TabHost)findViewById(android.R.id.tabhost); + mTabHost.setup(); - spec.setContent(R.id.openrocketviewerOverview); - spec.setIndicator("Overview"); - tabs.addTab(spec); + mViewPager = (ViewPager)findViewById(R.id.pager); - spec=tabs.newTabSpec("tag2"); - spec.setContent(R.id.openrocketviewerComponentTree); - spec.setIndicator("Components"); - tabs.addTab(spec); + mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager); - spec=tabs.newTabSpec("tag3"); - spec.setContent(R.id.openrocketviewerSimulationList); - spec.setIndicator("Simulations"); - tabs.addTab(spec); + mTabsAdapter.addTab(mTabHost.newTabSpec("overview").setIndicator("Overview"), + Overview.class, null); + mTabsAdapter.addTab(mTabHost.newTabSpec("components").setIndicator("Components"), + Component.class, null); + mTabsAdapter.addTab(mTabHost.newTabSpec("simulations").setIndicator("Simulations"), + Simulations.class, null); - configurationSpinner = (Spinner) findViewById(R.id.openrocketviewerConfigurationSpinner); - componentTree = (TreeViewList) findViewById(R.id.openrocketviewerComponentTree); - simulationList = (ListView) findViewById(R.id.openrocketviewerSimulationList); - - Intent i = getIntent(); - Uri file = i.getData(); - - if ( file == null ) { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.setType("file/*"); - startActivityForResult(intent,PICK_ORK_FILE_RESULT); - - } else { - loadOrkFile(file); + if (savedInstanceState != null) { + mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); } } @Override - protected void onDestroy() { - if ( progress != null ) { - if ( progress.isShowing() ) { - progress.dismiss(); - } - progress = null; - } - super.onDestroy(); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - // TODO Auto-generated method stub - switch(requestCode){ - case PICK_ORK_FILE_RESULT: - if(resultCode==RESULT_OK){ - Uri file = data.getData(); - loadOrkFile(file); - } - break; - } - } - - private void loadOrkFile( Uri file ) { - Log.d(TAG,"Use ork file: " + file); - String path = file.getPath(); - File orkFile = new File(path); - progress = ProgressDialog.show(this, "Loading file", ""); - - final OpenRocketLoaderTask task = new OpenRocketLoaderTask() { - - /* (non-Javadoc) - * @see android.os.AsyncTask#onPostExecute(java.lang.Object) - */ - @Override - protected void onPostExecute(OpenRocketDocument result) { - super.onPostExecute(result); - app.setRocketDocument( result ); - updateContents(); - } - - }; - - task.execute(orkFile); - + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString("tab", mTabHost.getCurrentTabTag()); } /* (non-Javadoc) @@ -182,115 +75,7 @@ implements SharedPreferences.OnSharedPreferenceChangeListener @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { // just in case the user changed the units, we redraw. - PreferencesActivity.initializePreferences(getApplication(), PreferenceManager.getDefaultSharedPreferences(this)); - updateContents(); - } - - private void updateContents() { - - rocketDocument = app.getRocketDocument(); - rocketConfiguration = rocketDocument.getDefaultConfiguration(); - Rocket rocket = rocketDocument.getRocket(); - - setTitle(rocket.getName()); - - String[] motorConfigs = rocket.getMotorConfigurationIDs(); - ArrayAdapter spinnerAdapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item); - for( String config: motorConfigs ) { - spinnerAdapter.add(rocket.getMotorConfigurationNameOrDescription(config)); - } - - configurationSpinner.setAdapter(spinnerAdapter); - configurationSpinner.setOnItemSelectedListener( new AdapterView.OnItemSelectedListener() { - - /* (non-Javadoc) - * @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long) - */ - @Override - public void onItemSelected(AdapterView arg0, View arg1, - int arg2, long arg3) { - - String selectedConfigId = rocketDocument.getRocket().getMotorConfigurationIDs()[arg2]; - rocketConfiguration.setMotorConfigurationID(selectedConfigId); - Coordinate cp = aerodynamicCalculator.getWorstCP(rocketConfiguration, - new FlightConditions(rocketConfiguration), - new WarningSet()); - - Coordinate cg = massCalculator.getCG(rocketConfiguration, MassCalcType.LAUNCH_MASS); - - Unit lengthUnit = UnitGroup.UNITS_LENGTH.getDefaultUnit(); - Unit massUnit = UnitGroup.UNITS_MASS.getDefaultUnit(); - Unit stabilityUnit = UnitGroup.stabilityUnits(rocketConfiguration).getDefaultUnit(); - - ((TextView)findViewById(R.id.openrocketviewerCP)).setText(lengthUnit.toStringUnit(cp.x)); - ((TextView)findViewById(R.id.openrocketviewerCG)).setText(lengthUnit.toStringUnit(cg.x)); - ((TextView)findViewById(R.id.openrocketviewerLiftOffWeight)).setText(massUnit.toStringUnit(cg.weight)); - ((TextView)findViewById(R.id.openrocketviewerStabilityMargin)).setText(stabilityUnit.toStringUnit(cp.x-cg.x)); - - } - - /* (non-Javadoc) - * @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView) - */ - @Override - public void onNothingSelected(AdapterView arg0) { - ((TextView)findViewById(R.id.openrocketviewerCP)).setText(""); - ((TextView)findViewById(R.id.openrocketviewerCG)).setText(""); - ((TextView)findViewById(R.id.openrocketviewerLiftOffWeight)).setText(""); - ((TextView)findViewById(R.id.openrocketviewerStabilityMargin)).setText(""); - } - - }); - - Unit lengthUnit = UnitGroup.UNITS_LENGTH.getDefaultUnit(); - Unit massUnit = UnitGroup.UNITS_MASS.getDefaultUnit(); - - Coordinate cg = RocketUtils.getCG(rocket, MassCalcType.NO_MOTORS); - double length = RocketUtils.getLength(rocket); - ((TextView)findViewById(R.id.openrocketviewerDesigner)).setText(rocket.getDesigner()); - ((TextView)findViewById(R.id.openrocketviewerLength)).setText(lengthUnit.toStringUnit(length)); - ((TextView)findViewById(R.id.openrocketviewerMass)).setText(massUnit.toStringUnit(cg.weight)); - ((TextView)findViewById(R.id.openrocketviewerStageCount)).setText(String.valueOf(rocket.getStageCount())); - - - ArrayAdapter sims = new ArrayAdapter(this,android.R.layout.simple_list_item_2,rocketDocument.getSimulations()) { - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if ( v == null ) { - LayoutInflater li = getLayoutInflater(); - v = li.inflate(android.R.layout.simple_list_item_2,null); - } - Simulation sim = this.getItem(position); - ((TextView)v.findViewById(android.R.id.text1)).setText( sim.getName() ); - StringBuilder sb = new StringBuilder(); - sb.append("motors: ").append(sim.getConfiguration().getMotorConfigurationDescription()); - Unit distanceUnit = UnitGroup.UNITS_DISTANCE.getDefaultUnit(); - sb.append(" apogee: ").append( distanceUnit.toStringUnit(sim.getSimulatedData().getMaxAltitude())); - sb.append(" time: ").append(sim.getSimulatedData().getFlightTime()).append("s"); - ((TextView)v.findViewById(android.R.id.text2)).setText( sb.toString() ); - return v; - } - - }; - simulationList.setOnItemClickListener( new OnItemClickListener() { - @Override - public void onItemClick(AdapterView l, View v, int position, long id) { - Intent i = new Intent(OpenRocketViewer.this, SimulationViewer.class); - Log.d(TAG,"onItemClick simulation number " + id ); - i.putExtra("Simulation",(int)id); - startActivity(i); - } - - }); - simulationList.setAdapter(sims); - - componentTree.setAdapter( buildAdapter( rocket ) ); - - if ( progress.isShowing() ) { - progress.dismiss(); - } + // TODO = updateContents(); redraw all children.. } @Override @@ -300,73 +85,32 @@ implements SharedPreferences.OnSharedPreferenceChangeListener return true; } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch ( item.getItemId() ) { + /* case android.R.id.home: + Intent i = new Intent( this, Main.class ); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + return true; + */ + default: + return super.onOptionsItemSelected(item); + } + } + @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { Log.d(TAG,"onMenuItemSelected" + item.getItemId()); switch(item.getItemId()) { case R.id.motor_list_menu_option: - startMotorBrowser(); + ActivityHelpers.browseMotors(this); return true; case R.id.preference_menu_option: - Intent intent = new Intent().setClass(this, PreferencesActivity.class); - this.startActivity(intent); + ActivityHelpers.startPreferences(this); return true; } return super.onMenuItemSelected(featureId, item); } - public void startMotorBrowser() { - Log.d(TAG,"motorBrowserButton clicked"); - Intent i = new Intent(OpenRocketViewer.this, MotorHierarchicalBrowser.class); - startActivity(i); - } - - private ListAdapter buildAdapter( Rocket rocket ) { - /* - final int[] DEMO_NODES = new int[] { 0, 0, 1, 1, 1, 2, 2, 1, - 1, 2, 1, 0, 0, 0, 1, 2, 3, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1 }; - final int LEVEL_NUMBER = 4; - - TreeStateManager manager = new InMemoryTreeStateManager(); - final TreeBuilder treeBuilder = new TreeBuilder(manager); - for (int i = 0; i < DEMO_NODES.length; i++) { - treeBuilder.sequentiallyAddNextNode((long) i, DEMO_NODES[i]); - } - - return new SimpleStandardAdapter(this, manager, LEVEL_NUMBER); - */ - - TreeStateManager manager = new InMemoryTreeStateManager(); - TreeBuilder treeBuilder = new TreeBuilder(manager); - - int depth = buildRecursive( rocket, treeBuilder, 0 ); - return new RocketComponentTreeAdapter(this, manager, depth+1); - } - - long id = 0; - private int buildRecursive( RocketComponent comp, TreeBuilder builder, int depth ) { - - - int maxDepth = depth; - - RocketComponentWithId rcid = new RocketComponentWithId(comp, id++); - - // Add this component. - builder.sequentiallyAddNextNode(rcid, depth); - - if ( comp.allowsChildren() ) { - - for( RocketComponent child : comp.getChildren() ) { - int childDepth = buildRecursive( child, builder, depth+1); - if ( childDepth > maxDepth) { - maxDepth = childDepth; - } - } - - } - - return maxDepth; - } - - } diff --git a/android/src/net/sf/openrocket/android/rocket/Overview.java b/android/src/net/sf/openrocket/android/rocket/Overview.java new file mode 100644 index 00000000..69a35ef7 --- /dev/null +++ b/android/src/net/sf/openrocket/android/rocket/Overview.java @@ -0,0 +1,123 @@ +package net.sf.openrocket.android.rocket; + +import net.sf.openrocket.R; +import net.sf.openrocket.aerodynamics.AerodynamicCalculator; +import net.sf.openrocket.aerodynamics.BarrowmanCalculator; +import net.sf.openrocket.aerodynamics.FlightConditions; +import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.android.Application; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.masscalc.BasicMassCalculator; +import net.sf.openrocket.masscalc.MassCalculator; +import net.sf.openrocket.masscalc.MassCalculator.MassCalcType; +import net.sf.openrocket.rocketcomponent.Configuration; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.RocketUtils; +import net.sf.openrocket.unit.Unit; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.Coordinate; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import android.widget.TextView; + +public class Overview extends Fragment { + + /* Calculation of CP and CG */ + private AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator(); + private MassCalculator massCalculator = new BasicMassCalculator(); + + private Spinner configurationSpinner; + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + Log.d("Overview", "Created View"); + View v = inflater.inflate(R.layout.rocket_overview, container, false); + configurationSpinner = (Spinner) v.findViewById(R.id.openrocketviewerConfigurationSpinner); + + return v; + } + + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument(); + final Configuration rocketConfiguration = rocketDocument.getDefaultConfiguration(); + Rocket rocket = rocketDocument.getRocket(); + + String[] motorConfigs = rocket.getMotorConfigurationIDs(); + ArrayAdapter spinnerAdapter = new ArrayAdapter(getActivity(),android.R.layout.simple_spinner_item); + for( String config: motorConfigs ) { + spinnerAdapter.add(rocket.getMotorConfigurationNameOrDescription(config)); + } + + Log.d("Overview", "spinnerAdapter = " + spinnerAdapter); + Log.d("Overview", "configurationSpinner = " + configurationSpinner); + + configurationSpinner.setAdapter(spinnerAdapter); + configurationSpinner.setOnItemSelectedListener( new AdapterView.OnItemSelectedListener() { + + /* (non-Javadoc) + * @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long) + */ + @Override + public void onItemSelected(AdapterView arg0, View arg1, + int arg2, long arg3) { + + String selectedConfigId = rocketDocument.getRocket().getMotorConfigurationIDs()[arg2]; + rocketConfiguration.setMotorConfigurationID(selectedConfigId); + Coordinate cp = aerodynamicCalculator.getWorstCP(rocketConfiguration, + new FlightConditions(rocketConfiguration), + new WarningSet()); + + Coordinate cg = massCalculator.getCG(rocketConfiguration, MassCalcType.LAUNCH_MASS); + + Unit lengthUnit = UnitGroup.UNITS_LENGTH.getDefaultUnit(); + Unit massUnit = UnitGroup.UNITS_MASS.getDefaultUnit(); + Unit stabilityUnit = UnitGroup.stabilityUnits(rocketConfiguration).getDefaultUnit(); + + ((TextView)getActivity().findViewById(R.id.openrocketviewerCP)).setText(lengthUnit.toStringUnit(cp.x)); + ((TextView)getActivity().findViewById(R.id.openrocketviewerCG)).setText(lengthUnit.toStringUnit(cg.x)); + ((TextView)getActivity().findViewById(R.id.openrocketviewerLiftOffWeight)).setText(massUnit.toStringUnit(cg.weight)); + ((TextView)getActivity().findViewById(R.id.openrocketviewerStabilityMargin)).setText(stabilityUnit.toStringUnit(cp.x-cg.x)); + + } + + /* (non-Javadoc) + * @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView) + */ + @Override + public void onNothingSelected(AdapterView arg0) { + ((TextView)getActivity().findViewById(R.id.openrocketviewerCP)).setText(""); + ((TextView)getActivity().findViewById(R.id.openrocketviewerCG)).setText(""); + ((TextView)getActivity().findViewById(R.id.openrocketviewerLiftOffWeight)).setText(""); + ((TextView)getActivity().findViewById(R.id.openrocketviewerStabilityMargin)).setText(""); + } + + }); + + Unit lengthUnit = UnitGroup.UNITS_LENGTH.getDefaultUnit(); + Unit massUnit = UnitGroup.UNITS_MASS.getDefaultUnit(); + + Coordinate cg = RocketUtils.getCG(rocket, MassCalcType.NO_MOTORS); + double length = RocketUtils.getLength(rocket); + ((TextView)getActivity().findViewById(R.id.openrocketviewerDesigner)).setText(rocket.getDesigner()); + ((TextView)getActivity().findViewById(R.id.openrocketviewerLength)).setText(lengthUnit.toStringUnit(length)); + ((TextView)getActivity().findViewById(R.id.openrocketviewerMass)).setText(massUnit.toStringUnit(cg.weight)); + ((TextView)getActivity().findViewById(R.id.openrocketviewerStageCount)).setText(String.valueOf(rocket.getStageCount())); + + + } + + +} diff --git a/android/src/net/sf/openrocket/android/rocket/Simulations.java b/android/src/net/sf/openrocket/android/rocket/Simulations.java new file mode 100644 index 00000000..231c50da --- /dev/null +++ b/android/src/net/sf/openrocket/android/rocket/Simulations.java @@ -0,0 +1,77 @@ +package net.sf.openrocket.android.rocket; + +import net.sf.openrocket.R; +import net.sf.openrocket.android.Application; +import net.sf.openrocket.android.simulation.SimulationViewer; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.document.Simulation; +import net.sf.openrocket.unit.Unit; +import net.sf.openrocket.unit.UnitGroup; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; + +public class Simulations extends Fragment { + + private ListView simulationList; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.rocket_simulations, container, false); + simulationList = (ListView) v.findViewById(R.id.openrocketviewerSimulationList); + + return v; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument(); + Log.d("sim","activity = " + this.getActivity()); + + ArrayAdapter sims = new ArrayAdapter(this.getActivity(),android.R.layout.simple_list_item_2,rocketDocument.getSimulations()) { + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if ( v == null ) { + LayoutInflater li = getActivity().getLayoutInflater(); + v = li.inflate(android.R.layout.simple_list_item_2,null); + } + Simulation sim = this.getItem(position); + ((TextView)v.findViewById(android.R.id.text1)).setText( sim.getName() ); + StringBuilder sb = new StringBuilder(); + sb.append("motors: ").append(sim.getConfiguration().getMotorConfigurationDescription()); + Unit distanceUnit = UnitGroup.UNITS_DISTANCE.getDefaultUnit(); + sb.append(" apogee: ").append( distanceUnit.toStringUnit(sim.getSimulatedData().getMaxAltitude())); + sb.append(" time: ").append(sim.getSimulatedData().getFlightTime()).append("s"); + ((TextView)v.findViewById(android.R.id.text2)).setText( sb.toString() ); + return v; + } + + }; + simulationList.setOnItemClickListener( new OnItemClickListener() { + @Override + public void onItemClick(AdapterView l, View v, int position, long id) { + Intent i = new Intent(getActivity(), SimulationViewer.class); + i.putExtra("Simulation",(int)id); + startActivity(i); + } + + }); + simulationList.setAdapter(sims); + + } + +} diff --git a/android/src/net/sf/openrocket/android/util/TabsAdapter.java b/android/src/net/sf/openrocket/android/util/TabsAdapter.java new file mode 100644 index 00000000..e8d8c6a8 --- /dev/null +++ b/android/src/net/sf/openrocket/android/util/TabsAdapter.java @@ -0,0 +1,140 @@ +package net.sf.openrocket.android.util; + +import java.util.ArrayList; + +import android.content.Context; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TabHost; +import android.widget.TabWidget; + +//This class was copied from: +//http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.html +//With the following copyright & license. + +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This is a helper class that implements the management of tabs and all + * details of connecting a ViewPager with associated TabHost. It relies on a + * trick. Normally a tab host has a simple API for supplying a View or + * Intent that each tab will show. This is not sufficient for switching + * between pages. So instead we make the content part of the tab host + * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy + * view to show as the tab content. It listens to changes in tabs, and takes + * care of switch to the correct paged in the ViewPager whenever the selected + * tab changes. + */ +public class TabsAdapter extends FragmentPagerAdapter + implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener { + private final Context mContext; + private final TabHost mTabHost; + private final ViewPager mViewPager; + private final ArrayList mTabs = new ArrayList(); + + static final class TabInfo { + private final String tag; + private final Class clss; + private final Bundle args; + + TabInfo(String _tag, Class _class, Bundle _args) { + tag = _tag; + clss = _class; + args = _args; + } + } + + static class DummyTabFactory implements TabHost.TabContentFactory { + private final Context mContext; + + public DummyTabFactory(Context context) { + mContext = context; + } + + @Override + public View createTabContent(String tag) { + View v = new View(mContext); + v.setMinimumWidth(0); + v.setMinimumHeight(0); + return v; + } + } + + public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) { + super(activity.getSupportFragmentManager()); + mContext = activity; + mTabHost = tabHost; + mViewPager = pager; + mTabHost.setOnTabChangedListener(this); + mViewPager.setAdapter(this); + mViewPager.setOnPageChangeListener(this); + } + + public void addTab(TabHost.TabSpec tabSpec, Class clss, Bundle args) { + tabSpec.setContent(new DummyTabFactory(mContext)); + String tag = tabSpec.getTag(); + + TabInfo info = new TabInfo(tag, clss, args); + mTabs.add(info); + mTabHost.addTab(tabSpec); + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mTabs.size(); + } + + @Override + public Fragment getItem(int position) { + TabInfo info = mTabs.get(position); + return Fragment.instantiate(mContext, info.clss.getName(), info.args); + } + + @Override + public void onTabChanged(String tabId) { + int position = mTabHost.getCurrentTab(); + mViewPager.setCurrentItem(position); + } + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageSelected(int position) { + // Unfortunately when TabHost changes the current tab, it kindly + // also takes care of putting focus on it when not in touch mode. + // The jerk. + // This hack tries to prevent this from pulling focus out of our + // ViewPager. + TabWidget widget = mTabHost.getTabWidget(); + int oldFocusability = widget.getDescendantFocusability(); + widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); + mTabHost.setCurrentTab(position); + widget.setDescendantFocusability(oldFocusability); + } + + @Override + public void onPageScrollStateChanged(int state) { + } +}