Added Configuration tab to the rocket viewer which displays all the motor configurations and allows one to create a new motor configuration.

This commit is contained in:
Kevin Ruland 2012-05-22 19:34:11 +00:00
parent 6185091ee1
commit 02d9954ff1
13 changed files with 953 additions and 1 deletions

View File

@ -0,0 +1,23 @@
<?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" >
<EditText
android:id="@+id/motor_config_delay_diag_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number" >
<requestFocus />
</EditText>
<ListView
android:id="@+id/motor_config_delay_diag_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false" >
<TextView
android:id="@+id/motor_config_motor_mount_name"
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:text="Stage" />
<Button
android:id="@+id/motor_config_motor_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/motor_config_motor_mount_name"
android:layout_margin="0dp"
android:layout_toLeftOf="@+id/motor_config_motor_dash"
android:text="@string/select_motor"
android:textAppearance="@style/valueTextStyle" />
<TextView
android:id="@+id/motor_config_motor_dash"
style="@style/valueTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/motor_config_motor_desc"
android:layout_below="@id/motor_config_motor_mount_name"
android:layout_toLeftOf="@+id/motor_config_motor_delay"
android:gravity="right"
android:text="-" />
<Button
android:id="@+id/motor_config_motor_delay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/motor_config_motor_desc"
android:layout_alignParentRight="true"
android:layout_below="@id/motor_config_motor_mount_name"
android:text="@string/select_delay"
android:textAppearance="@style/valueTextStyle" />
</RelativeLayout>

View File

@ -0,0 +1,13 @@
<?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" >
<fragment
android:id="@+id/motor_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="net.sf.openrocket.motor.MotorListFragment" />
</LinearLayout>

View File

@ -0,0 +1,28 @@
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical" >
<!-- Note because my implementation of ExpandableListFragment is stupid, the id
of the ExpandableListView must be @android:id/list -->
<ExpandableListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/openrocketviewerAddConfiguration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Add" />
</LinearLayout>

View File

@ -0,0 +1,61 @@
<?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" >
<TextView
style="@style/labelTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/simulationConditionWind" />
<EditText
android:id="@+id/simulation_condition_windspeed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:gravity="right"
android:inputType="number"
android:text="0" >
<requestFocus />
</EditText>
<TextView
style="@style/labelTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/simulationConditionsRodLength" />
<EditText
android:id="@+id/simulation_condition_rodlength"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:gravity="right"
android:inputType="number"
android:text="0" />
<TextView
style="@style/labelTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/simulationConditionsLaunchRodAngle" />
<EditText
android:id="@+id/simulation_condition_rodangle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:gravity="right"
android:inputType="number"
android:text="0" />
<Spinner
android:id="@+id/simulationConditionConfigurationSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:prompt="@string/simulationConditionSelectMotors" />
</LinearLayout>

View File

@ -75,5 +75,11 @@
<string name="motor_impulseclass">Impulse Class</string>
<string name="motor_diameter">Diameter</string>
<string name="motor_length">Length</string>
<string name="simulationConditionSelectMotors">Select Motors</string>
<string name="simulationConditionWind">Wind speed</string>
<string name="simulationConditionsRodLength">Launch Rod Length</string>
<string name="simulationConditionsLaunchRodAngle">Launch Rod Angle</string>
<string name="select_motor">Select Motor</string>
<string name="select_delay">Delay</string>
</resources>

View File

@ -0,0 +1,112 @@
package net.sf.openrocket.android.motor;
import java.util.ArrayList;
import net.sf.openrocket.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class MotorDelayDialogFragment extends DialogFragment
implements View.OnClickListener, TextView.OnEditorActionListener {
public interface OnDelaySelectedListener {
public void onDelaySelected( double delay );
}
private OnDelaySelectedListener delaySelectedListener;
public void setDelaySelectedListener(OnDelaySelectedListener delaySelectedListener) {
this.delaySelectedListener = delaySelectedListener;
}
private final static String delaysArg = "delaysArg";
public static MotorDelayDialogFragment newInstance( double[] delays ) {
MotorDelayDialogFragment f = new MotorDelayDialogFragment();
Bundle b = new Bundle();
b.putDoubleArray(delaysArg, delays);
f.setArguments(b);
return f;
}
@Override
public void onClick(View v) {
String s = ((TextView)v).getText().toString();
long value = Long.parseLong(s);
if ( delaySelectedListener != null ) {
delaySelectedListener.onDelaySelected(value);
}
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ( event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_ENTER ) {
String s = v.getText().toString();
if ( s != null ) { // note requires ems=10
long value = Long.parseLong(s);
if ( delaySelectedListener != null ) {
delaySelectedListener.onDelaySelected(value);
}
}
return true;
}
return false;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (savedInstanceState == null ) {
savedInstanceState = getArguments();
}
double[] delays = savedInstanceState.getDoubleArray(delaysArg);
ArrayList<Long> delayList = new ArrayList<Long>(delays.length);
for( int i =0; i< delays.length; i++ ) {
delayList.add( Math.round(delays[i]) );
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Enter or Choose Delay");
LayoutInflater li = getActivity().getLayoutInflater();
View v = li.inflate(R.layout.motor_config_delay_dialog, null);
builder.setView(v);
ArrayAdapter<Long> listAdapter = new ArrayAdapter<Long>(getActivity(),android.R.layout.simple_list_item_1,delayList) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if ( convertView == null ) {
convertView = getActivity().getLayoutInflater().inflate( android.R.layout.simple_list_item_1, null);
}
TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
tv.setText( String.valueOf(getItem(position)) );
tv.setOnClickListener( MotorDelayDialogFragment.this );
return convertView;
}
};
ListView lv = (ListView) v.findViewById(R.id.motor_config_delay_diag_list);
lv.setAdapter(listAdapter);
EditText et = (EditText) v.findViewById(R.id.motor_config_delay_diag_edit);
et.setOnEditorActionListener(MotorDelayDialogFragment.this);
return builder.create();
}
}

View File

@ -0,0 +1,154 @@
package net.sf.openrocket.android.motor;
import net.sf.openrocket.R;
import net.sf.openrocket.android.db.DbAdapter;
import net.sf.openrocket.android.db.MotorDao;
import net.sf.openrocket.android.util.AndroidLogWrapper;
import net.sf.openrocket.android.util.PersistentExpandableListView;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ResourceCursorTreeAdapter;
import android.widget.TextView;
public class MotorListDialogFragment extends DialogFragment
implements ExpandableListView.OnChildClickListener
{
public interface OnMotorSelectedListener {
public void onMotorSelected( long motorId );
}
private final static String groupColumn = MotorDao.DIAMETER;
private DbAdapter mDbHelper;
private ExpandableListView list;
private OnMotorSelectedListener motorSelectedListener;
public void setMotorSelectedListener(
OnMotorSelectedListener motorSelectedListener) {
this.motorSelectedListener = motorSelectedListener;
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
if( motorSelectedListener != null ) {
motorSelectedListener.onMotorSelected(id);
}
return true;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Select Motor");
list = new PersistentExpandableListView(getActivity());
list.setOnChildClickListener( this );
refreshData();
builder.setView( list );
return builder.create();
}
@Override
public void onPause() {
super.onPause();
mDbHelper.close();
}
public void refreshData() {
if ( mDbHelper == null ) {
mDbHelper = new DbAdapter(getActivity());
}
mDbHelper.open();
Cursor motorCounter = mDbHelper.getMotorDao().fetchAllMotors();
int motorCount = motorCounter.getCount();
motorCounter.close();
if ( motorCount == 0 ) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("No Motors Found");
builder.setMessage("Motors can be downloaded from thrustcurve");
builder.setCancelable(true);
builder.create().show();
}
Cursor motorCursor = mDbHelper.getMotorDao().fetchGroups(groupColumn);
MotorHierarchicalListAdapter mAdapter = new MotorHierarchicalListAdapter(
getActivity(),
motorCursor,
R.layout.motor_list_group,
R.layout.motor_list_child);
list.setAdapter(mAdapter);
}
public class MotorHierarchicalListAdapter extends ResourceCursorTreeAdapter
{
// Note that the constructor does not take a Cursor. This is done to avoid querying the
// database on the main thread.
public MotorHierarchicalListAdapter(Context context, Cursor cursor, int groupLayout,
int childLayout ) {
super(context, cursor, groupLayout, childLayout);
}
@Override
protected Cursor getChildrenCursor(Cursor arg0) {
AndroidLogWrapper.d(MotorListFragment.class,"getChildrenCursor");
String group = arg0.getString(arg0.getColumnIndex(groupColumn));
Cursor c = mDbHelper.getMotorDao().fetchAllInGroups(groupColumn,group);
return c;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
/* (non-Javadoc)
* @see android.widget.CursorTreeAdapter#bindChildView(android.view.View, android.content.Context, android.database.Cursor, boolean)
*/
@Override
protected void bindChildView(View arg0, Context arg1, Cursor arg2,
boolean arg3) {
TextView manu = (TextView) arg0.findViewById(R.id.motorChildManu);
manu.setText( arg2.getString(arg2.getColumnIndex(MotorDao.MANUFACTURER)));
TextView desig = (TextView) arg0.findViewById(R.id.motorChildName);
desig.setText( arg2.getString(arg2.getColumnIndex(MotorDao.DESIGNATION)));
TextView delays = (TextView) arg0.findViewById(R.id.motorChildDelays);
delays.setText( arg2.getString(arg2.getColumnIndex(MotorDao.DELAYS)));
TextView totImpulse = (TextView) arg0.findViewById(R.id.motorChildImpulse);
totImpulse.setText( arg2.getString(arg2.getColumnIndex(MotorDao.TOTAL_IMPULSE)));
}
/* (non-Javadoc)
* @see android.widget.CursorTreeAdapter#bindGroupView(android.view.View, android.content.Context, android.database.Cursor, boolean)
*/
@Override
protected void bindGroupView(View view, Context context, Cursor cursor,
boolean isExpanded) {
TextView v = (TextView) view.findViewById(R.id.motorGroup);
if ( MotorDao.DIAMETER.equals(groupColumn)) {
double d = cursor.getDouble( cursor.getColumnIndex(groupColumn));
v.setText( String.valueOf(Math.round(d * 1000.0)) + " mm");
} else {
v.setText( cursor.getString( cursor.getColumnIndex(groupColumn)));
}
}
}
}

View File

@ -0,0 +1,280 @@
package net.sf.openrocket.android.rocket;
import java.util.List;
import net.sf.openrocket.R;
import net.sf.openrocket.android.Application;
import net.sf.openrocket.android.db.DbAdapter;
import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;
import net.sf.openrocket.android.motor.MotorDelayDialogFragment;
import net.sf.openrocket.android.motor.MotorListDialogFragment;
import net.sf.openrocket.android.util.AndroidLogWrapper;
import net.sf.openrocket.android.util.ExpandableListFragment;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.unit.UnitGroup;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.TextView;
public class Configurations extends ExpandableListFragment {
private final static String wizardFrag = "wizardFrag";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.rocket_configurations, container, false);
Button b = (Button) v.findViewById(R.id.openrocketviewerAddConfiguration);
b.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
((Application)getActivity().getApplication()).getRocketDocument().getRocket().newMotorConfigurationID();
Configurations.this.setup();
}
});
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setup();
}
private static class MotorMountInfo {
private RocketComponent mmt;
private String config;
private ExtendedThrustCurveMotor motor;
private double delay;
String getMotorMountDescription() {
String mmtDesc = mmt.getComponentName();
mmtDesc += " (" + UnitGroup.UNITS_MOTOR_DIMENSIONS.toStringUnit( ((MotorMount)mmt).getMotorMountDiameter()) + ")";
return mmtDesc;
}
String getMotorDescription() {
return motor.getManufacturer().getDisplayName() + " " + motor.getDesignation();
}
}
class ChildViewHolder {
MotorMountInfo info;
TextView motorMountName;
Button motorDescription;
Button motorDelay;
void setMotor( ExtendedThrustCurveMotor motor ) {
this.info.motor = motor;
((MotorMount)info.mmt).setMotor(info.config, motor);
}
void setDelay( double delay ) {
this.info.delay = delay;
((MotorMount)info.mmt).setMotorDelay(info.config, delay);
}
}
private void setup() {
final OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();
ExpandableListAdapter configurationAdapter = new BaseExpandableListAdapter() {
List<MotorMount> mmts = rocketDocument.getRocket().getMotorMounts();
@Override
public int getGroupCount() {
return rocketDocument.getRocket().getMotorConfigurationIDs().length;
}
@Override
public int getChildrenCount(int groupPosition) {
return mmts.size();
}
@Override
public Object getGroup(int groupPosition) {
String config = rocketDocument.getRocket().getMotorConfigurationIDs()[groupPosition];
return config;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
MotorMountInfo info = new MotorMountInfo();
info.mmt = (RocketComponent)(mmts.get(childPosition));
String config = (String) getGroup(groupPosition);
info.config = config;
info.motor = (ExtendedThrustCurveMotor) ((MotorMount)info.mmt).getMotor(config);
if ( info.motor != null ) {
info.delay = ((MotorMount)info.mmt).getMotorDelay(config);
} else {
info.delay = -1;
}
return info;
}
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if ( convertView == null ) {
convertView = getActivity().getLayoutInflater().inflate(android.R.layout.simple_expandable_list_item_1,null);
}
String configDescription = rocketDocument.getRocket().getMotorConfigurationNameOrDescription((String) getGroup(groupPosition));
((TextView)convertView.findViewById(android.R.id.text1)).setText( configDescription );
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if ( convertView == null ) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.motor_config_item,null);
ChildViewHolder holder = new ChildViewHolder();
holder.motorMountName = (TextView) convertView.findViewById(R.id.motor_config_motor_mount_name);
holder.motorDescription = (Button) convertView.findViewById(R.id.motor_config_motor_desc);
holder.motorDelay = (Button) convertView.findViewById(R.id.motor_config_motor_delay);
holder.info = (MotorMountInfo) getChild(groupPosition,childPosition);
convertView.setTag(holder);
}
ChildViewHolder cvHolder = (ChildViewHolder) convertView.getTag();
cvHolder.motorMountName.setText(cvHolder.info.getMotorMountDescription());
cvHolder.motorDescription.setOnClickListener( new MotorWizardOnClickListener() );
if ( cvHolder.info.motor == null ) {
cvHolder.motorDelay.setClickable(false);
cvHolder.motorDelay.setOnClickListener(null);
cvHolder.motorDescription.setText(R.string.select_motor);
} else {
cvHolder.motorDelay.setClickable(true);
cvHolder.motorDelay.setOnClickListener( new MotorDelayOnClickListener(cvHolder.info.motor) );
cvHolder.motorDescription.setText(cvHolder.info.getMotorDescription());
}
if( cvHolder.info.delay >=0 ) {
if( cvHolder.info.delay == Motor.PLUGGED ) {
cvHolder.motorDelay.setText("P");
} else {
cvHolder.motorDelay.setText( String.valueOf(Math.round(cvHolder.info.delay)));
}
} else {
cvHolder.motorDelay.setText(R.string.select_delay);
}
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition,
int childPosition) {
// TODO Auto-generated method stub
return false;
}
};
setListAdapter(configurationAdapter);
}
private class MotorWizardOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
final ViewGroup parent = (ViewGroup) v.getParent();
final ChildViewHolder cvHolder = (ChildViewHolder) parent.getTag();
final MotorListDialogFragment f = new MotorListDialogFragment();
f.setMotorSelectedListener( new MotorListDialogFragment.OnMotorSelectedListener() {
@Override
public void onMotorSelected(long motorId) {
DbAdapter mdbHelper = new DbAdapter(getActivity());
mdbHelper.open();
try {
ExtendedThrustCurveMotor motor = mdbHelper.getMotorDao().fetchMotor(motorId);
cvHolder.setMotor( motor );
((BaseExpandableListAdapter)Configurations.this.getExpandableListAdapter()).notifyDataSetInvalidated();
} catch (Exception ex) {
AndroidLogWrapper.d(Configurations.class, "BlewUp looking for motor", ex);
} finally {
mdbHelper.close();
}
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(f);
ft.commit();
}
});
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.add(f, wizardFrag);
ft.commit();
}
}
private class MotorDelayOnClickListener implements View.OnClickListener {
double[] standardDelays;
public MotorDelayOnClickListener(ExtendedThrustCurveMotor motor) {
super();
this.standardDelays = motor.getStandardDelays();
}
@Override
public void onClick(View v) {
final View parent = (View) v.getParent();
final ChildViewHolder cvHolder = (ChildViewHolder) parent.getTag();
final MotorDelayDialogFragment f = MotorDelayDialogFragment.newInstance(standardDelays);
f.setDelaySelectedListener( new MotorDelayDialogFragment.OnDelaySelectedListener() {
@Override
public void onDelaySelected(double delay) {
cvHolder.setDelay( delay );
((BaseExpandableListAdapter)Configurations.this.getExpandableListAdapter()).notifyDataSetInvalidated();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(f);
ft.commit();
}
});
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.add(f, wizardFrag);
ft.commit();
}
}
}

View File

@ -123,7 +123,7 @@ implements Simulations.OnSimulationSelectedListener
}
@Override
public int getCount() {
return 3;
return 4;
}
@Override
public Fragment getItem( int position ) {
@ -134,6 +134,8 @@ implements Simulations.OnSimulationSelectedListener
return new Component();
case 2:
return new Simulations();
case 3:
return new Configurations();
}
return null;
}
@ -146,6 +148,8 @@ implements Simulations.OnSimulationSelectedListener
return "Components";
case 2:
return "Simulations";
case 3:
return "Configurations";
}
return null;
}

View File

@ -0,0 +1,46 @@
package net.sf.openrocket.android.simulation;
import net.sf.openrocket.R;
import net.sf.openrocket.android.ActivityHelpers;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
/**
* An activity that encapsulates a graphical view of the chart.
*/
public class SimulationRunActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int simulationNumber = getIntent().getIntExtra("Simulation", -1);
Fragment graph = SimulationRunFragment.newInstance(simulationNumber);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(android.R.id.content, graph);
ft.commit();
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case R.id.preference_menu_option:
ActivityHelpers.startPreferences(this);
return true;
}
return super.onMenuItemSelected(featureId, item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem prefItem = menu.add(Menu.NONE, R.id.preference_menu_option, Menu.CATEGORY_SYSTEM, R.string.Preferences);
prefItem.setIcon(R.drawable.ic_menu_preferences);
return true;
}
}

View File

@ -0,0 +1,90 @@
package net.sf.openrocket.android.simulation;
import net.sf.openrocket.R;
import net.sf.openrocket.android.Application;
import net.sf.openrocket.android.rocket.MotorConfigSpinnerAdapter;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.unit.UnitGroup;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Spinner;
/**
* An activity that encapsulates a graphical view of the chart.
*/
public class SimulationRunFragment extends DialogFragment {
int simulationId;
EditText windspeedField;
EditText rodlengthField;
EditText rodangleField;
Spinner motorSpinner;
public static SimulationRunFragment newInstance( int simulationId ) {
SimulationRunFragment frag = new SimulationRunFragment();
Bundle b = new Bundle();
b.putInt("simulationId", simulationId);
frag.setArguments(b);
return frag;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE,getTheme());
if ( savedInstanceState != null ) {
simulationId = savedInstanceState.getInt("simulationId");
} else {
Bundle b = getArguments();
simulationId = b.getInt("simulationId");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.simulation_condition_dialog, container, false);
windspeedField = (EditText) v.findViewById(R.id.simulation_condition_windspeed);
rodlengthField = (EditText) v.findViewById(R.id.simulation_condition_rodlength);
rodangleField = (EditText) v.findViewById(R.id.simulation_condition_rodangle);
motorSpinner = (Spinner) v.findViewById(R.id.simulationConditionConfigurationSpinner);
OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();
Simulation sim = rocketDocument.getSimulation(simulationId);
windspeedField.setText( UnitGroup.UNITS_VELOCITY.toString(sim.getSimulatedConditions().getWindSpeedAverage()) );
rodlengthField.setText( UnitGroup.UNITS_LENGTH.toString(sim.getSimulatedConditions().getLaunchRodLength()));
rodangleField.setText( String.valueOf( sim.getSimulatedConditions().getLaunchRodLength() ));
MotorConfigSpinnerAdapter spinnerAdapter = new MotorConfigSpinnerAdapter(getActivity(),rocketDocument.getRocket());
motorSpinner.setAdapter(spinnerAdapter);
/* TODO - enable saving.
((Button) v.findViewById(R.id.motorDetailsSaveButton)).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
MotorDetailsFragment.this.saveChanges();
}
});
*/
return v;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("simulationId", simulationId);
}
}

View File

@ -0,0 +1,89 @@
package net.sf.openrocket.android.util;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
public class PersistentExpandableListView extends ExpandableListView {
public PersistentExpandableListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public PersistentExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PersistentExpandableListView(Context context) {
super(context);
}
@Override
public Parcelable onSaveInstanceState() {
Bundle b = new Bundle();
long[] expandedIds = getExpandedIds();
b.putLongArray("ExpandedIds", expandedIds);
return b;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
Bundle b = (Bundle) state;
long[] expandedIds = b.getLongArray("ExpandedIds");
restoreExpandedState(expandedIds);
}
private long[] getExpandedIds() {
ExpandableListAdapter adapter = getExpandableListAdapter();
if (adapter != null) {
int length = adapter.getGroupCount();
ArrayList<Long> expandedIds = new ArrayList<Long>();
for(int i=0; i < length; i++) {
if(this.isGroupExpanded(i)) {
expandedIds.add(adapter.getGroupId(i));
}
}
return toLongArray(expandedIds);
} else {
return null;
}
}
private static long[] toLongArray(List<Long> list) {
long[] ret = new long[list.size()];
int i = 0;
for (Long e : list)
ret[i++] = e.longValue();
return ret;
}
private void restoreExpandedState(long[] expandedIds) {
if (expandedIds != null) {
ExpandableListAdapter adapter = getExpandableListAdapter();
if (adapter != null) {
for (int i=0; i<adapter.getGroupCount(); i++) {
long id = adapter.getGroupId(i);
if (inArray(expandedIds, id)) this.expandGroup(i);
}
}
}
}
private static boolean inArray(long[] array, long element) {
for (long l : array) {
if (l == element) {
return true;
}
}
return false;
}
}