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().

This commit is contained in:
Kevin Ruland 2012-01-22 02:44:17 +00:00
parent 35052eb6ad
commit 8603cbeff5
22 changed files with 901 additions and 543 deletions

View File

@ -27,7 +27,7 @@
</intent-filter>
</activity>
<activity
android:name=".android.rocket.OpenRocketViewer"
android:name=".android.rocket.OpenRocketLoader"
android:label="@string/app_name" >
<!--
@ -35,7 +35,7 @@
Combining the <data> elements into a single field did not result in a working
application. The first intent-filter (with mimeType wildcard) convinces the
file browser to associate the correct launcher icon. the second intent-filter
is actually invoked when a file is selected.
is actually invoked when a file is selected.
-->
<!-- this intent filter convinces the file browser to display icons -->
<intent-filter>
@ -61,6 +61,9 @@
android:scheme="file" />
</intent-filter>
</activity>
<activity
android:name=".android.rocket.OpenRocketViewer"
android:label="@string/app_name" />
<activity android:name=".android.PreferencesActivity" >
<intent-filter>
<action android:name="net.sf.openrocket.android.PreferencesActivity" />
@ -68,16 +71,12 @@
<category android:name="android.intent.category.PREFERENCE" />
</intent-filter>
</activity>
<activity
android:name=".android.motor.MotorHierarchicalBrowser"
android:label="@string/MotorListTitle" />
<activity android:name=".android.motor.MotorHierarchicalBrowser" />
<activity android:name=".android.motor.MotorDetails" />
<activity
android:name=".android.thrustcurve.TCQueryActivity"
android:label="@string/MotorListTitle" />
<activity android:name=".android.thrustcurve.TCQueryActivity" />
<activity android:name=".android.simulation.SimulationViewer" />
<activity android:name=".android.simulation.GraphicalActivity" />
<activity android:name=".android.filebrowser.SimpleFileBrowser" />
</application>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -1,144 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:layout_height="match_parent">
<TabHost
android:id="@+id/openrocketviewerTabHost"
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black" >
android:layout_height="match_parent">
<LinearLayout
<TabWidget
android:id="@android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:layout_height="wrap_content"
android:layout_weight="0"/>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:id="@+id/openrocketviewerOverview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Designer" />
<TextView
android:id="@+id/openrocketviewerDesigner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Length" />
<TextView
android:id="@+id/openrocketviewerLength"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Empty Mass" />
<TextView
android:id="@+id/openrocketviewerMass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Stage Count" />
<TextView
android:id="@+id/openrocketviewerStageCount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<Spinner android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/openrocketviewerConfigurationSpinner"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Lift off weight" />
<TextView
android:id="@+id/openrocketviewerLiftOffWeight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="CG" />
<TextView
android:id="@+id/openrocketviewerCG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="CP" />
<TextView
android:id="@+id/openrocketviewerCP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Stability margin" />
<TextView
android:id="@+id/openrocketviewerStabilityMargin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
<pl.polidea.treeview.TreeViewList
android:id="@+id/openrocketviewerComponentTree"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical"
android:smoothScrollbar="true" />
<ListView
android:id="@+id/openrocketviewerSimulationList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>
</LinearLayout>
</TabHost>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<pl.polidea.treeview.TreeViewList xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/openrocketviewerComponentTree"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical"
android:smoothScrollbar="true" />

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/openrocketviewerOverview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Designer" />
<TextView
android:id="@+id/openrocketviewerDesigner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Length" />
<TextView
android:id="@+id/openrocketviewerLength"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Empty Mass" />
<TextView
android:id="@+id/openrocketviewerMass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stage Count" />
<TextView
android:id="@+id/openrocketviewerStageCount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<Spinner
android:id="@+id/openrocketviewerConfigurationSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lift off weight" />
<TextView
android:id="@+id/openrocketviewerLiftOffWeight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CG" />
<TextView
android:id="@+id/openrocketviewerCG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CP" />
<TextView
android:id="@+id/openrocketviewerCP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stability margin" />
<TextView
android:id="@+id/openrocketviewerStabilityMargin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/openrocketviewerSimulationList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/main_menu_open"
android:title="Open"/>
<item
android:id="@+id/main_menu_motor"
android:title="Motor"/>
<item
android:id="@+id/main_menu_preferences"
android:title="@string/Preferences"
android:icon="@drawable/ic_menu_preferences"/>
</menu>

View File

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:title="Motor List" android:id="@+id/motor_list_menu_option"/>
<item android:title="Preferences" android:id="@+id/preference_menu_option"/>
<item
android:id="@+id/motor_list_menu_option"
android:title="Motor List"/>
<item
android:id="@+id/preference_menu_option"
android:title="@string/Preferences"
android:icon="@drawable/ic_menu_preferences"/>
</menu>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="PreferenceMotorBrowserGroupingOption">PreferenceMotorBrowserGroupingOption</string>
<string name="PreferenceUseInternalFileBrowserOption">PreferenceUseInternalFileBrowserOpion</string>
<string-array name="PreferenceMotorBrowserGroupingValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string name="PreferenceUnitLengthOption">PreferenceUnitLengthOption</string>
<string-array name="PreferenceUnitLengthValues">
<item>mm</item>
<item>cm</item>
<item>m</item>
<item>in</item>
<item>ft</item>
</string-array>
<string name="PreferenceUnitMassOption">PreferenceUnitMassOption</string>
<string-array name="PreferenceUnitMassValues">
<item>g</item>
<item>kg</item>
<item>oz</item>
<item>lb</item>
</string-array>
<string name="PreferenceUnitVelocityOption">PreferenceUnitVelocityOption</string>
<string-array name="PreferenceUnitVelocityValues">
<item>m/s</item>
<item>km/h</item>
<item>ft/s</item>
<item>mph</item>
</string-array>
<string name="PreferenceUnitDistanceOption">PreferenceUnitDistanceOption</string>
<string-array name="PreferenceUnitDistanceValues">
<item>m</item>
<item>km</item>
<item>ft</item>
<item>yd</item>
<item>mi</item>
<item>nmi</item>
</string-array>
</resources>

View File

@ -4,7 +4,7 @@
<string name="app_name">OpenRocket</string>
<string name="save">Save</string>
<string name="MotorListTitle">Motor List</string>
<string name="PreferenceMotorBrowserGroupingOption">PreferenceMotorBrowserGroupingOption</string>
<string name="Preferences">Preferences</string>
<string-array name="PreferenceMotorBrowserGroupingEntries">
<item>Case</item>
@ -12,12 +12,6 @@
<item>Impulse</item>
<item>Manufacturer</item>
</string-array>
<string-array name="PreferenceMotorBrowserGroupingValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string name="TCMotorSearchFormImpulse">Impulse</string>
@ -96,8 +90,11 @@
<string name="tcdownload">Download from ThrustCurve</string>
<string name="simulationSeries1Label">Series 1</string>
<string name="simulationSeries2Label">Series 2</string>
<string name="PreferenceUnitLengthOption">PreferenceUnitLengthOption</string>
<string name="motorbrowsergrouptitle">Motor Browser Grouping</string>
<string name="useinternalfilebrowsertitle">Use Internal File Browser</string>
<string name="useinternalfilebrowsersummary">uncheck to use system file browser if available</string>
<string-array name="PreferenceUnitLengthEntries">
<item>Millimeters</item>
<item>Centimeters</item>
@ -105,46 +102,18 @@
<item>Inches</item>
<item>Feet</item>
</string-array>
<string-array name="PreferenceUnitLengthValues">
<item>mm</item>
<item>cm</item>
<item>m</item>
<item>in</item>
<item>ft</item>
</string-array>
<string name="PreferenceUnitMassOption">PreferenceUnitMassOption</string>
<string-array name="PreferenceUnitMassEntries">
<item>Grams</item>
<item>Kilograms</item>
<item>Ounces</item>
<item>Pounds</item>
</string-array>
<string-array name="PreferenceUnitMassValues">
<item>g</item>
<item>kg</item>
<item>oz</item>
<item>lb</item>
</string-array>
<string name="PreferenceUnitVelocityOption">PreferenceUnitVelocityOption</string>
<string-array name="PreferenceUnitVelocityEntries">
<item>Meters/Second</item>
<item>Kilometers/Hour</item>
<item>Feet/Second</item>
<item>Miles/Hour</item>
</string-array>
<string-array name="PreferenceUnitVelocityValues">
<item>m/s</item>
<item>km/h</item>
<item>ft/s</item>
<item>mph</item>
</string-array>
<string name="PreferenceUnitDistanceOption">PreferenceUnitDistanceOption</string>
<string-array name="PreferenceUnitDistanceEntries">
<item>Meters</item>
<item>Kilometers</item>
@ -153,13 +122,5 @@
<item>Miles</item>
<item>Nautical Miles</item>
</string-array>
<string-array name="PreferenceUnitDistanceValues">
<item>m</item>
<item>km</item>
<item>ft</item>
<item>yd</item>
<item>mi</item>
<item>nmi</item>
</string-array>
</resources>

View File

@ -1,50 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
android:key="preferences"
android:title="Pref Title"
android:summary="pref summary"
<ListPreference
android:defaultValue="1"
android:entries="@array/PreferenceMotorBrowserGroupingEntries"
android:entryValues="@array/PreferenceMotorBrowserGroupingValues"
android:key="@string/PreferenceMotorBrowserGroupingOption"
android:summary="Set the grouping in Motor Browser"
android:title="Motor Browser Group" />
android:title="@string/motorbrowsergrouptitle" />
<ListPreference
android:defaultValue="cm"
android:entries="@array/PreferenceUnitLengthEntries"
android:entryValues="@array/PreferenceUnitLengthValues"
android:key="@string/PreferenceUnitLengthOption"
android:summary="Set the length unit"
android:title="Unit of Length"
<CheckBoxPreference
android:defaultValue="false"
android:title="@string/useinternalfilebrowsertitle"
android:key="@string/PreferenceUseInternalFileBrowserOption"
android:summary="@string/useinternalfilebrowsersummary"
/>
<ListPreference
android:defaultValue="g"
android:entries="@array/PreferenceUnitMassEntries"
android:entryValues="@array/PreferenceUnitMassValues"
android:key="@string/PreferenceUnitMassOption"
android:summary="Set the mass unit"
android:title="Unit of Mass"
/>
<ListPreference
android:defaultValue="m/s"
android:entries="@array/PreferenceUnitVelocityEntries"
android:entryValues="@array/PreferenceUnitVelocityValues"
android:key="@string/PreferenceUnitVelocityOption"
android:summary="Set the velocity unit"
android:title="Unit for Velocity"
/>
<ListPreference
android:defaultValue="m"
android:entries="@array/PreferenceUnitDistanceEntries"
android:entryValues="@array/PreferenceUnitDistanceValues"
android:key="@string/PreferenceUnitDistanceOption"
android:summary="Set the distance unit"
android:title="Unit for Distance and Altitude"
/>
<PreferenceScreen
android:key="UnitPrefences"
android:summary="Configure units"
android:title="Units" >
<ListPreference
android:defaultValue="cm"
android:entries="@array/PreferenceUnitLengthEntries"
android:entryValues="@array/PreferenceUnitLengthValues"
android:key="@string/PreferenceUnitLengthOption"
android:summary="Set the length unit"
android:title="Unit of Length" />
<ListPreference
android:defaultValue="g"
android:entries="@array/PreferenceUnitMassEntries"
android:entryValues="@array/PreferenceUnitMassValues"
android:key="@string/PreferenceUnitMassOption"
android:summary="Set the mass unit"
android:title="Unit of Mass" />
<ListPreference
android:defaultValue="m/s"
android:entries="@array/PreferenceUnitVelocityEntries"
android:entryValues="@array/PreferenceUnitVelocityValues"
android:key="@string/PreferenceUnitVelocityOption"
android:summary="Set the velocity unit"
android:title="Unit for Velocity" />
<ListPreference
android:defaultValue="m"
android:entries="@array/PreferenceUnitDistanceEntries"
android:entryValues="@array/PreferenceUnitDistanceValues"
android:key="@string/PreferenceUnitDistanceOption"
android:summary="Set the distance unit"
android:title="Unit for Distance and Altitude" />
</PreferenceScreen>
</PreferenceScreen>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -52,5 +52,13 @@ implements SharedPreferences.OnSharedPreferenceChangeListener {
UnitGroup.UNITS_DISTANCE.setDefaultUnit( distance );
}
@Override
protected void onStop() {
initializePreferences(getApplication(), PreferenceManager.getDefaultSharedPreferences(this));
super.onStop();
}
}

View File

@ -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");

View File

@ -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<RocketComponentWithId> manager = new InMemoryTreeStateManager<RocketComponentWithId>();
TreeBuilder<RocketComponentWithId> treeBuilder = new TreeBuilder<RocketComponentWithId>(manager);
int depth = buildRecursive( rocket, treeBuilder, 0 );
return new RocketComponentTreeAdapter(this.getActivity(), manager, depth+1);
}
long id = 0;
private int buildRecursive( RocketComponent comp, TreeBuilder<RocketComponentWithId> 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;
}
}

View File

@ -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();
}
}

View File

@ -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);
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
tabs.setup();
mViewPager = (ViewPager)findViewById(R.id.pager);
TabHost.TabSpec spec=tabs.newTabSpec("tag1");
mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
spec.setContent(R.id.openrocketviewerOverview);
spec.setIndicator("Overview");
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);
spec=tabs.newTabSpec("tag2");
spec.setContent(R.id.openrocketviewerComponentTree);
spec.setIndicator("Components");
tabs.addTab(spec);
spec=tabs.newTabSpec("tag3");
spec.setContent(R.id.openrocketviewerSimulationList);
spec.setIndicator("Simulations");
tabs.addTab(spec);
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<String> spinnerAdapter = new ArrayAdapter<String>(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<Simulation> sims = new ArrayAdapter<Simulation>(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<Long> manager = new InMemoryTreeStateManager<Long>();
final TreeBuilder<Long> treeBuilder = new TreeBuilder<Long>(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<RocketComponentWithId> manager = new InMemoryTreeStateManager<RocketComponentWithId>();
TreeBuilder<RocketComponentWithId> treeBuilder = new TreeBuilder<RocketComponentWithId>(manager);
int depth = buildRecursive( rocket, treeBuilder, 0 );
return new RocketComponentTreeAdapter(this, manager, depth+1);
}
long id = 0;
private int buildRecursive( RocketComponent comp, TreeBuilder<RocketComponentWithId> 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;
}
}

View File

@ -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<String> spinnerAdapter = new ArrayAdapter<String>(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()));
}
}

View File

@ -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<Simulation> sims = new ArrayAdapter<Simulation>(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);
}
}

View File

@ -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<TabInfo> mTabs = new ArrayList<TabInfo>();
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) {
}
}