--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent"\r
+ android:orientation="vertical" >
+\r
+ <EditText\r
+ android:id="@+id/motor_config_delay_diag_edit"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:inputType="number" >\r
+\r
+ <requestFocus />\r
+ </EditText>
+\r
+ <ListView\r
+ android:id="@+id/motor_config_delay_diag_list"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content" >\r
+ </ListView>\r
+\r
+</LinearLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent"\r
+ android:focusable="false" >\r
+\r
+ <TextView\r
+ android:id="@+id/motor_config_motor_mount_name"\r
+ style="@style/labelTextStyle"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:focusable="false"\r
+ android:text="Stage" />\r
+\r\r
+ <Button\r
+ android:id="@+id/motor_config_motor_desc"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_below="@id/motor_config_motor_mount_name"\r
+ android:layout_margin="0dp"\r
+ android:layout_toLeftOf="@+id/motor_config_motor_dash"\r
+ android:text="@string/select_motor"\r
+ android:textAppearance="@style/valueTextStyle" />\r
+\r
+ <TextView\r
+ android:id="@+id/motor_config_motor_dash"\r
+ style="@style/valueTextStyle"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_alignBaseline="@id/motor_config_motor_desc"\r
+ android:layout_below="@id/motor_config_motor_mount_name"\r
+ android:layout_toLeftOf="@+id/motor_config_motor_delay"\r
+ android:gravity="right"\r
+ android:text="-" />\r
+\r\r
+ <Button\r
+ android:id="@+id/motor_config_motor_delay"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_alignBaseline="@id/motor_config_motor_desc"\r
+ android:layout_alignParentRight="true"\r
+ android:layout_below="@id/motor_config_motor_mount_name"\r
+ android:text="@string/select_delay"\r
+ android:textAppearance="@style/valueTextStyle" />\r
+\r
+</RelativeLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent"\r
+ android:orientation="vertical" >\r
+\r
+ <fragment\r
+ android:id="@+id/motor_list"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent"\r
+ class="net.sf.openrocket.motor.MotorListFragment" />\r
+\r
+</LinearLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent"\r
+ android:orientation="vertical" >\r
+\r
+ <LinearLayout\r
+ android:layout_width="match_parent"\r
+ android:layout_height="0dp"\r
+ android:layout_weight="1"\r
+ android:orientation="vertical" >\r
+\r
+ <!-- Note because my implementation of ExpandableListFragment is stupid, the id\r
+ of the ExpandableListView must be @android:id/list -->\r
+ <ExpandableListView\r
+ android:id="@android:id/list"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content" />\r
+ </LinearLayout>\r
+\r
+ <Button\r
+ android:id="@+id/openrocketviewerAddConfiguration"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:layout_gravity="center_horizontal"\r
+ android:text="Add" />\r
+\r
+</LinearLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="match_parent"\r
+ android:orientation="vertical" >\r
+\r
+ <TextView\r
+ style="@style/labelTextStyle"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:text="@string/simulationConditionWind" />\r
+\r
+ <EditText\r
+ android:id="@+id/simulation_condition_windspeed"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:gravity="right"\r
+ android:inputType="number"\r
+ android:text="0" >\r
+\r
+ <requestFocus />\r
+ </EditText>\r
+\r
+ <TextView\r
+ style="@style/labelTextStyle"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:text="@string/simulationConditionsRodLength" />\r
+\r
+ <EditText\r
+ android:id="@+id/simulation_condition_rodlength"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:gravity="right"\r
+ android:inputType="number"\r
+ android:text="0" />\r
+\r
+ <TextView\r
+ style="@style/labelTextStyle"\r
+ android:layout_width="wrap_content"\r
+ android:layout_height="wrap_content"\r
+ android:text="@string/simulationConditionsLaunchRodAngle" />\r
+\r
+ <EditText\r
+ android:id="@+id/simulation_condition_rodangle"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:ems="10"\r
+ android:gravity="right"\r
+ android:inputType="number"\r
+ android:text="0" />\r
+\r
+ <Spinner\r
+ android:id="@+id/simulationConditionConfigurationSpinner"\r
+ android:layout_width="match_parent"\r
+ android:layout_height="wrap_content"\r
+ android:prompt="@string/simulationConditionSelectMotors" />\r
+\r
+</LinearLayout>
\ No newline at end of file
<string name="motor_impulseclass">Impulse Class</string>\r
<string name="motor_diameter">Diameter</string>\r
<string name="motor_length">Length</string>\r
+ <string name="simulationConditionSelectMotors">Select Motors</string>\r
+ <string name="simulationConditionWind">Wind speed</string>\r
+ <string name="simulationConditionsRodLength">Launch Rod Length</string>\r
+ <string name="simulationConditionsLaunchRodAngle">Launch Rod Angle</string>\r
+ <string name="select_motor">Select Motor</string>\r
+ <string name="select_delay">Delay</string>\r
\r
</resources>
\ No newline at end of file
--- /dev/null
+package net.sf.openrocket.android.motor;\r
+\r
+import java.util.ArrayList;\r
+\r
+import net.sf.openrocket.R;\r
+import android.app.AlertDialog;\r
+import android.app.Dialog;\r
+import android.os.Bundle;\r
+import android.support.v4.app.DialogFragment;\r
+import android.view.KeyEvent;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.ArrayAdapter;\r
+import android.widget.EditText;\r
+import android.widget.ListView;\r
+import android.widget.TextView;\r
+\r
+public class MotorDelayDialogFragment extends DialogFragment \r
+implements View.OnClickListener, TextView.OnEditorActionListener {\r
+\r
+ public interface OnDelaySelectedListener {\r
+ public void onDelaySelected( double delay );\r
+ }\r
+\r
+ private OnDelaySelectedListener delaySelectedListener;\r
+\r
+ public void setDelaySelectedListener(OnDelaySelectedListener delaySelectedListener) {\r
+ this.delaySelectedListener = delaySelectedListener;\r
+ }\r
+\r
+ private final static String delaysArg = "delaysArg";\r
+ \r
+ public static MotorDelayDialogFragment newInstance( double[] delays ) {\r
+ MotorDelayDialogFragment f = new MotorDelayDialogFragment();\r
+ Bundle b = new Bundle();\r
+ b.putDoubleArray(delaysArg, delays);\r
+ f.setArguments(b);\r
+ return f;\r
+ }\r
+\r
+ @Override\r
+ public void onClick(View v) {\r
+ String s = ((TextView)v).getText().toString();\r
+ long value = Long.parseLong(s);\r
+ if ( delaySelectedListener != null ) {\r
+ delaySelectedListener.onDelaySelected(value);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {\r
+ if ( event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_ENTER ) {\r
+ String s = v.getText().toString();\r
+ if ( s != null ) { // note requires ems=10\r
+ long value = Long.parseLong(s);\r
+ if ( delaySelectedListener != null ) {\r
+ delaySelectedListener.onDelaySelected(value);\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public Dialog onCreateDialog(Bundle savedInstanceState) {\r
+ \r
+ if (savedInstanceState == null ) {\r
+ savedInstanceState = getArguments();\r
+ }\r
+ double[] delays = savedInstanceState.getDoubleArray(delaysArg);\r
+ ArrayList<Long> delayList = new ArrayList<Long>(delays.length);\r
+ for( int i =0; i< delays.length; i++ ) {\r
+ delayList.add( Math.round(delays[i]) );\r
+ }\r
+ \r
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());\r
+ builder.setTitle("Enter or Choose Delay");\r
+ \r
+ LayoutInflater li = getActivity().getLayoutInflater();\r
+ View v = li.inflate(R.layout.motor_config_delay_dialog, null);\r
+ builder.setView(v);\r
+ \r
+ ArrayAdapter<Long> listAdapter = new ArrayAdapter<Long>(getActivity(),android.R.layout.simple_list_item_1,delayList) {\r
+\r
+ @Override\r
+ public View getView(int position, View convertView, ViewGroup parent) {\r
+ if ( convertView == null ) {\r
+ convertView = getActivity().getLayoutInflater().inflate( android.R.layout.simple_list_item_1, null);\r
+ }\r
+ TextView tv = (TextView) convertView.findViewById(android.R.id.text1);\r
+ tv.setText( String.valueOf(getItem(position)) );\r
+ tv.setOnClickListener( MotorDelayDialogFragment.this );\r
+ return convertView;\r
+ }\r
+ \r
+ \r
+ };\r
+ \r
+ ListView lv = (ListView) v.findViewById(R.id.motor_config_delay_diag_list);\r
+ lv.setAdapter(listAdapter);\r
+ \r
+ EditText et = (EditText) v.findViewById(R.id.motor_config_delay_diag_edit);\r
+ et.setOnEditorActionListener(MotorDelayDialogFragment.this);\r
+ return builder.create();\r
+ \r
+ }\r
+ \r
+ \r
+ \r
+}\r
--- /dev/null
+package net.sf.openrocket.android.motor;\r
+\r
+import net.sf.openrocket.R;\r
+import net.sf.openrocket.android.db.DbAdapter;\r
+import net.sf.openrocket.android.db.MotorDao;\r
+import net.sf.openrocket.android.util.AndroidLogWrapper;\r
+import net.sf.openrocket.android.util.PersistentExpandableListView;\r
+import android.app.AlertDialog;\r
+import android.app.Dialog;\r
+import android.content.Context;\r
+import android.database.Cursor;\r
+import android.os.Bundle;\r
+import android.support.v4.app.DialogFragment;\r
+import android.view.View;\r
+import android.widget.ExpandableListView;\r
+import android.widget.ResourceCursorTreeAdapter;\r
+import android.widget.TextView;\r
+\r
+public class MotorListDialogFragment extends DialogFragment \r
+implements ExpandableListView.OnChildClickListener\r
+{\r
+\r
+ public interface OnMotorSelectedListener {\r
+ public void onMotorSelected( long motorId );\r
+ }\r
+\r
+ private final static String groupColumn = MotorDao.DIAMETER;\r
+\r
+ private DbAdapter mDbHelper;\r
+\r
+ private ExpandableListView list;\r
+\r
+ private OnMotorSelectedListener motorSelectedListener;\r
+\r
+ public void setMotorSelectedListener(\r
+ OnMotorSelectedListener motorSelectedListener) {\r
+ this.motorSelectedListener = motorSelectedListener;\r
+ }\r
+\r
+ @Override\r
+ public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {\r
+ if( motorSelectedListener != null ) {\r
+ motorSelectedListener.onMotorSelected(id);\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public Dialog onCreateDialog(Bundle savedInstanceState) {\r
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());\r
+ builder.setTitle("Select Motor");\r
+ list = new PersistentExpandableListView(getActivity());\r
+ list.setOnChildClickListener( this );\r
+ refreshData();\r
+ builder.setView( list );\r
+ return builder.create();\r
+ }\r
+\r
+ @Override\r
+ public void onPause() {\r
+ super.onPause();\r
+ mDbHelper.close();\r
+ }\r
+\r
+ public void refreshData() {\r
+ if ( mDbHelper == null ) {\r
+ mDbHelper = new DbAdapter(getActivity());\r
+ }\r
+ mDbHelper.open();\r
+\r
+ Cursor motorCounter = mDbHelper.getMotorDao().fetchAllMotors();\r
+ int motorCount = motorCounter.getCount();\r
+ motorCounter.close();\r
+ \r
+ if ( motorCount == 0 ) {\r
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());\r
+ builder.setTitle("No Motors Found");\r
+ builder.setMessage("Motors can be downloaded from thrustcurve");\r
+ builder.setCancelable(true);\r
+ builder.create().show();\r
+ }\r
+\r
+ Cursor motorCursor = mDbHelper.getMotorDao().fetchGroups(groupColumn);\r
+ MotorHierarchicalListAdapter mAdapter = new MotorHierarchicalListAdapter( \r
+ getActivity(),\r
+ motorCursor,\r
+ R.layout.motor_list_group,\r
+ R.layout.motor_list_child);\r
+ list.setAdapter(mAdapter);\r
+ }\r
+\r
+ public class MotorHierarchicalListAdapter extends ResourceCursorTreeAdapter\r
+ {\r
+\r
+ // Note that the constructor does not take a Cursor. This is done to avoid querying the \r
+ // database on the main thread.\r
+ public MotorHierarchicalListAdapter(Context context, Cursor cursor, int groupLayout,\r
+ int childLayout ) {\r
+\r
+ super(context, cursor, groupLayout, childLayout);\r
+ }\r
+\r
+ @Override\r
+ protected Cursor getChildrenCursor(Cursor arg0) {\r
+ AndroidLogWrapper.d(MotorListFragment.class,"getChildrenCursor");\r
+ String group = arg0.getString(arg0.getColumnIndex(groupColumn));\r
+ Cursor c = mDbHelper.getMotorDao().fetchAllInGroups(groupColumn,group);\r
+ return c;\r
+ }\r
+\r
+ @Override\r
+ public long getGroupId(int groupPosition) {\r
+ return groupPosition;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see android.widget.CursorTreeAdapter#bindChildView(android.view.View, android.content.Context, android.database.Cursor, boolean)\r
+ */\r
+ @Override\r
+ protected void bindChildView(View arg0, Context arg1, Cursor arg2,\r
+ boolean arg3) {\r
+\r
+ TextView manu = (TextView) arg0.findViewById(R.id.motorChildManu);\r
+ manu.setText( arg2.getString(arg2.getColumnIndex(MotorDao.MANUFACTURER)));\r
+\r
+ TextView desig = (TextView) arg0.findViewById(R.id.motorChildName);\r
+ desig.setText( arg2.getString(arg2.getColumnIndex(MotorDao.DESIGNATION)));\r
+\r
+ TextView delays = (TextView) arg0.findViewById(R.id.motorChildDelays);\r
+ delays.setText( arg2.getString(arg2.getColumnIndex(MotorDao.DELAYS)));\r
+\r
+ TextView totImpulse = (TextView) arg0.findViewById(R.id.motorChildImpulse);\r
+ totImpulse.setText( arg2.getString(arg2.getColumnIndex(MotorDao.TOTAL_IMPULSE)));\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see android.widget.CursorTreeAdapter#bindGroupView(android.view.View, android.content.Context, android.database.Cursor, boolean)\r
+ */\r
+ @Override\r
+ protected void bindGroupView(View view, Context context, Cursor cursor,\r
+ boolean isExpanded) {\r
+ TextView v = (TextView) view.findViewById(R.id.motorGroup);\r
+ if ( MotorDao.DIAMETER.equals(groupColumn)) {\r
+ double d = cursor.getDouble( cursor.getColumnIndex(groupColumn));\r
+ v.setText( String.valueOf(Math.round(d * 1000.0)) + " mm");\r
+ } else {\r
+ v.setText( cursor.getString( cursor.getColumnIndex(groupColumn)));\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+package net.sf.openrocket.android.rocket;\r
+\r
+import java.util.List;\r
+\r
+import net.sf.openrocket.R;\r
+import net.sf.openrocket.android.Application;\r
+import net.sf.openrocket.android.db.DbAdapter;\r
+import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;\r
+import net.sf.openrocket.android.motor.MotorDelayDialogFragment;\r
+import net.sf.openrocket.android.motor.MotorListDialogFragment;\r
+import net.sf.openrocket.android.util.AndroidLogWrapper;\r
+import net.sf.openrocket.android.util.ExpandableListFragment;\r
+import net.sf.openrocket.document.OpenRocketDocument;\r
+import net.sf.openrocket.motor.Motor;\r
+import net.sf.openrocket.rocketcomponent.MotorMount;\r
+import net.sf.openrocket.rocketcomponent.RocketComponent;\r
+import net.sf.openrocket.unit.UnitGroup;\r
+import android.os.Bundle;\r
+import android.support.v4.app.FragmentTransaction;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.BaseExpandableListAdapter;\r
+import android.widget.Button;\r
+import android.widget.ExpandableListAdapter;\r
+import android.widget.TextView;\r
+\r
+public class Configurations extends ExpandableListFragment {\r
+\r
+ private final static String wizardFrag = "wizardFrag";\r
+ \r
+ @Override\r
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
+ Bundle savedInstanceState) {\r
+ View v = inflater.inflate(R.layout.rocket_configurations, container, false);\r
+\r
+ Button b = (Button) v.findViewById(R.id.openrocketviewerAddConfiguration);\r
+\r
+ b.setOnClickListener( new View.OnClickListener() {\r
+\r
+ @Override\r
+ public void onClick(View v) {\r
+ ((Application)getActivity().getApplication()).getRocketDocument().getRocket().newMotorConfigurationID();\r
+ Configurations.this.setup();\r
+ }\r
+ });\r
+\r
+ return v;\r
+ }\r
+\r
+ @Override\r
+ public void onActivityCreated(Bundle savedInstanceState) {\r
+ super.onActivityCreated(savedInstanceState);\r
+\r
+ setup();\r
+\r
+ }\r
+\r
+ private static class MotorMountInfo {\r
+\r
+ private RocketComponent mmt;\r
+ private String config;\r
+ private ExtendedThrustCurveMotor motor;\r
+ private double delay;\r
+\r
+ String getMotorMountDescription() {\r
+ String mmtDesc = mmt.getComponentName();\r
+ mmtDesc += " (" + UnitGroup.UNITS_MOTOR_DIMENSIONS.toStringUnit( ((MotorMount)mmt).getMotorMountDiameter()) + ")";\r
+ return mmtDesc;\r
+ }\r
+\r
+ String getMotorDescription() {\r
+ return motor.getManufacturer().getDisplayName() + " " + motor.getDesignation();\r
+ }\r
+\r
+ }\r
+\r
+ class ChildViewHolder {\r
+ MotorMountInfo info;\r
+ TextView motorMountName;\r
+ Button motorDescription;\r
+ Button motorDelay;\r
+ void setMotor( ExtendedThrustCurveMotor motor ) {\r
+ this.info.motor = motor;\r
+ ((MotorMount)info.mmt).setMotor(info.config, motor);\r
+ }\r
+ void setDelay( double delay ) {\r
+ this.info.delay = delay;\r
+ ((MotorMount)info.mmt).setMotorDelay(info.config, delay);\r
+ }\r
+ }\r
+\r
+ private void setup() {\r
+ final OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();\r
+\r
+ ExpandableListAdapter configurationAdapter = new BaseExpandableListAdapter() {\r
+\r
+ List<MotorMount> mmts = rocketDocument.getRocket().getMotorMounts();\r
+\r
+ @Override\r
+ public int getGroupCount() {\r
+ return rocketDocument.getRocket().getMotorConfigurationIDs().length;\r
+ }\r
+\r
+ @Override\r
+ public int getChildrenCount(int groupPosition) {\r
+ return mmts.size();\r
+ }\r
+\r
+ @Override\r
+ public Object getGroup(int groupPosition) {\r
+ String config = rocketDocument.getRocket().getMotorConfigurationIDs()[groupPosition];\r
+ return config;\r
+ }\r
+\r
+ @Override\r
+ public Object getChild(int groupPosition, int childPosition) {\r
+ MotorMountInfo info = new MotorMountInfo();\r
+ info.mmt = (RocketComponent)(mmts.get(childPosition));\r
+\r
+ String config = (String) getGroup(groupPosition);\r
+ info.config = config;\r
+ info.motor = (ExtendedThrustCurveMotor) ((MotorMount)info.mmt).getMotor(config);\r
+\r
+ if ( info.motor != null ) {\r
+ info.delay = ((MotorMount)info.mmt).getMotorDelay(config);\r
+ } else {\r
+ info.delay = -1;\r
+ }\r
+\r
+ return info;\r
+ }\r
+\r
+ @Override\r
+ public long getGroupId(int groupPosition) {\r
+ // TODO Auto-generated method stub\r
+ return 0;\r
+ }\r
+\r
+ @Override\r
+ public long getChildId(int groupPosition, int childPosition) {\r
+ // TODO Auto-generated method stub\r
+ return 0;\r
+ }\r
+\r
+ @Override\r
+ public boolean hasStableIds() {\r
+ // TODO Auto-generated method stub\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public View getGroupView(int groupPosition, boolean isExpanded,\r
+ View convertView, ViewGroup parent) {\r
+ if ( convertView == null ) {\r
+ convertView = getActivity().getLayoutInflater().inflate(android.R.layout.simple_expandable_list_item_1,null);\r
+ }\r
+ String configDescription = rocketDocument.getRocket().getMotorConfigurationNameOrDescription((String) getGroup(groupPosition));\r
+ ((TextView)convertView.findViewById(android.R.id.text1)).setText( configDescription );\r
+ return convertView;\r
+ }\r
+\r
+ @Override\r
+ public View getChildView(int groupPosition, int childPosition,\r
+ boolean isLastChild, View convertView, ViewGroup parent) {\r
+ if ( convertView == null ) {\r
+ convertView = getActivity().getLayoutInflater().inflate(R.layout.motor_config_item,null);\r
+ ChildViewHolder holder = new ChildViewHolder();\r
+ holder.motorMountName = (TextView) convertView.findViewById(R.id.motor_config_motor_mount_name);\r
+ holder.motorDescription = (Button) convertView.findViewById(R.id.motor_config_motor_desc);\r
+ holder.motorDelay = (Button) convertView.findViewById(R.id.motor_config_motor_delay);\r
+ holder.info = (MotorMountInfo) getChild(groupPosition,childPosition);\r
+ convertView.setTag(holder);\r
+ }\r
+\r
+ ChildViewHolder cvHolder = (ChildViewHolder) convertView.getTag();\r
+\r
+ cvHolder.motorMountName.setText(cvHolder.info.getMotorMountDescription());\r
+ cvHolder.motorDescription.setOnClickListener( new MotorWizardOnClickListener() );\r
+ if ( cvHolder.info.motor == null ) {\r
+ cvHolder.motorDelay.setClickable(false);\r
+ cvHolder.motorDelay.setOnClickListener(null);\r
+ cvHolder.motorDescription.setText(R.string.select_motor);\r
+ } else {\r
+ cvHolder.motorDelay.setClickable(true);\r
+ cvHolder.motorDelay.setOnClickListener( new MotorDelayOnClickListener(cvHolder.info.motor) );\r
+ cvHolder.motorDescription.setText(cvHolder.info.getMotorDescription());\r
+ }\r
+ if( cvHolder.info.delay >=0 ) {\r
+ if( cvHolder.info.delay == Motor.PLUGGED ) {\r
+ cvHolder.motorDelay.setText("P");\r
+ } else {\r
+ cvHolder.motorDelay.setText( String.valueOf(Math.round(cvHolder.info.delay)));\r
+ }\r
+ } else {\r
+ cvHolder.motorDelay.setText(R.string.select_delay);\r
+ }\r
+\r
+ return convertView;\r
+ }\r
+\r
+ @Override\r
+ public boolean isChildSelectable(int groupPosition,\r
+ int childPosition) {\r
+ // TODO Auto-generated method stub\r
+ return false;\r
+ }\r
+\r
+ };\r
+\r
+ setListAdapter(configurationAdapter);\r
+ }\r
+\r
+ private class MotorWizardOnClickListener implements View.OnClickListener {\r
+ @Override\r
+ public void onClick(View v) {\r
+ final ViewGroup parent = (ViewGroup) v.getParent();\r
+ final ChildViewHolder cvHolder = (ChildViewHolder) parent.getTag();\r
+ final MotorListDialogFragment f = new MotorListDialogFragment();\r
+ f.setMotorSelectedListener( new MotorListDialogFragment.OnMotorSelectedListener() {\r
+\r
+ @Override\r
+ public void onMotorSelected(long motorId) {\r
+ DbAdapter mdbHelper = new DbAdapter(getActivity());\r
+ mdbHelper.open();\r
+ try {\r
+ ExtendedThrustCurveMotor motor = mdbHelper.getMotorDao().fetchMotor(motorId);\r
+ cvHolder.setMotor( motor );\r
+ ((BaseExpandableListAdapter)Configurations.this.getExpandableListAdapter()).notifyDataSetInvalidated();\r
+ } catch (Exception ex) {\r
+ AndroidLogWrapper.d(Configurations.class, "BlewUp looking for motor", ex);\r
+ } finally {\r
+ mdbHelper.close();\r
+ }\r
+ FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();\r
+ ft.remove(f);\r
+ ft.commit();\r
+\r
+ }\r
+ });\r
+ FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();\r
+ ft.add(f, wizardFrag);\r
+ ft.commit();\r
+ }\r
+\r
+ }\r
+\r
+ private class MotorDelayOnClickListener implements View.OnClickListener {\r
+\r
+ double[] standardDelays;\r
+\r
+ public MotorDelayOnClickListener(ExtendedThrustCurveMotor motor) {\r
+ super();\r
+ this.standardDelays = motor.getStandardDelays();\r
+ }\r
+\r
+ @Override\r
+ public void onClick(View v) {\r
+ final View parent = (View) v.getParent();\r
+ final ChildViewHolder cvHolder = (ChildViewHolder) parent.getTag();\r
+ final MotorDelayDialogFragment f = MotorDelayDialogFragment.newInstance(standardDelays);\r
+ f.setDelaySelectedListener( new MotorDelayDialogFragment.OnDelaySelectedListener() {\r
+\r
+ @Override\r
+ public void onDelaySelected(double delay) {\r
+ cvHolder.setDelay( delay );\r
+ ((BaseExpandableListAdapter)Configurations.this.getExpandableListAdapter()).notifyDataSetInvalidated();\r
+ FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();\r
+ ft.remove(f);\r
+ ft.commit();\r
+\r
+ }\r
+ });\r
+ FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();\r
+ ft.add(f, wizardFrag);\r
+ ft.commit();\r
+ }\r
+\r
+ }\r
+}\r
}\r
@Override\r
public int getCount() {\r
- return 3;\r
+ return 4;\r
}\r
@Override\r
public Fragment getItem( int position ) {\r
return new Component();\r
case 2:\r
return new Simulations();\r
+ case 3:\r
+ return new Configurations();\r
}\r
return null;\r
}\r
return "Components";\r
case 2:\r
return "Simulations";\r
+ case 3:\r
+ return "Configurations";\r
}\r
return null;\r
}\r
--- /dev/null
+package net.sf.openrocket.android.simulation;\r
+\r
+import net.sf.openrocket.R;\r
+import net.sf.openrocket.android.ActivityHelpers;\r
+import android.os.Bundle;\r
+import android.support.v4.app.Fragment;\r
+import android.support.v4.app.FragmentActivity;\r
+import android.support.v4.app.FragmentTransaction;\r
+import android.view.Menu;\r
+import android.view.MenuItem;\r
+\r
+/**\r
+ * An activity that encapsulates a graphical view of the chart.\r
+ */\r
+public class SimulationRunActivity extends FragmentActivity {\r
+\r
+ @Override\r
+ protected void onCreate(Bundle savedInstanceState) {\r
+ super.onCreate(savedInstanceState);\r
+ int simulationNumber = getIntent().getIntExtra("Simulation", -1);\r
+\r
+ Fragment graph = SimulationRunFragment.newInstance(simulationNumber);\r
+\r
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
+ ft.replace(android.R.id.content, graph);\r
+ ft.commit();\r
+ }\r
+\r
+ @Override\r
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {\r
+ switch (item.getItemId()) {\r
+ case R.id.preference_menu_option:\r
+ ActivityHelpers.startPreferences(this);\r
+ return true;\r
+ }\r
+ return super.onMenuItemSelected(featureId, item);\r
+ }\r
+\r
+ @Override\r
+ public boolean onCreateOptionsMenu(Menu menu) {\r
+ MenuItem prefItem = menu.add(Menu.NONE, R.id.preference_menu_option, Menu.CATEGORY_SYSTEM, R.string.Preferences);\r
+ prefItem.setIcon(R.drawable.ic_menu_preferences);\r
+ return true;\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+\r
+package net.sf.openrocket.android.simulation;\r
+\r
+import net.sf.openrocket.R;\r
+import net.sf.openrocket.android.Application;\r
+import net.sf.openrocket.android.rocket.MotorConfigSpinnerAdapter;\r
+import net.sf.openrocket.document.OpenRocketDocument;\r
+import net.sf.openrocket.document.Simulation;\r
+import net.sf.openrocket.unit.UnitGroup;\r
+import android.os.Bundle;\r
+import android.support.v4.app.DialogFragment;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.EditText;\r
+import android.widget.Spinner;\r
+\r
+/**\r
+ * An activity that encapsulates a graphical view of the chart.\r
+ */\r
+public class SimulationRunFragment extends DialogFragment {\r
+ \r
+ int simulationId;\r
+\r
+ EditText windspeedField;\r
+ EditText rodlengthField;\r
+ EditText rodangleField;\r
+ Spinner motorSpinner;\r
+\r
+ public static SimulationRunFragment newInstance( int simulationId ) {\r
+ SimulationRunFragment frag = new SimulationRunFragment();\r
+ Bundle b = new Bundle();\r
+ b.putInt("simulationId", simulationId);\r
+ frag.setArguments(b);\r
+ return frag;\r
+ }\r
+\r
+ @Override\r
+ public void onCreate(Bundle savedInstanceState) {\r
+ super.onCreate(savedInstanceState);\r
+ setStyle(DialogFragment.STYLE_NO_TITLE,getTheme());\r
+\r
+ if ( savedInstanceState != null ) {\r
+ simulationId = savedInstanceState.getInt("simulationId");\r
+ } else {\r
+ Bundle b = getArguments();\r
+ simulationId = b.getInt("simulationId");\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
+ Bundle savedInstanceState) {\r
+ View v = inflater.inflate(R.layout.simulation_condition_dialog, container, false);\r
+ windspeedField = (EditText) v.findViewById(R.id.simulation_condition_windspeed);\r
+ rodlengthField = (EditText) v.findViewById(R.id.simulation_condition_rodlength);\r
+ rodangleField = (EditText) v.findViewById(R.id.simulation_condition_rodangle);\r
+ \r
+ motorSpinner = (Spinner) v.findViewById(R.id.simulationConditionConfigurationSpinner);\r
+ \r
+ OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();\r
+\r
+ Simulation sim = rocketDocument.getSimulation(simulationId);\r
+ \r
+ windspeedField.setText( UnitGroup.UNITS_VELOCITY.toString(sim.getSimulatedConditions().getWindSpeedAverage()) );\r
+ rodlengthField.setText( UnitGroup.UNITS_LENGTH.toString(sim.getSimulatedConditions().getLaunchRodLength()));\r
+ rodangleField.setText( String.valueOf( sim.getSimulatedConditions().getLaunchRodLength() ));\r
+\r
+ MotorConfigSpinnerAdapter spinnerAdapter = new MotorConfigSpinnerAdapter(getActivity(),rocketDocument.getRocket());\r
+ motorSpinner.setAdapter(spinnerAdapter);\r
+ /* TODO - enable saving.\r
+ ((Button) v.findViewById(R.id.motorDetailsSaveButton)).setOnClickListener(\r
+ new View.OnClickListener() {\r
+ @Override\r
+ public void onClick(View v) {\r
+ MotorDetailsFragment.this.saveChanges();\r
+ }\r
+ });\r
+ */\r
+ return v;\r
+ }\r
+\r
+ @Override\r
+ public void onSaveInstanceState(Bundle outState) {\r
+ super.onSaveInstanceState(outState);\r
+ outState.putInt("simulationId", simulationId);\r
+\r
+ }\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+package net.sf.openrocket.android.util;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import android.content.Context;\r
+import android.os.Bundle;\r
+import android.os.Parcelable;\r
+import android.util.AttributeSet;\r
+import android.widget.ExpandableListAdapter;\r
+import android.widget.ExpandableListView;\r
+\r
+public class PersistentExpandableListView extends ExpandableListView {\r
+\r
+ public PersistentExpandableListView(Context context, AttributeSet attrs,\r
+ int defStyle) {\r
+ super(context, attrs, defStyle);\r
+ }\r
+\r
+ public PersistentExpandableListView(Context context, AttributeSet attrs) {\r
+ super(context, attrs);\r
+ }\r
+\r
+ public PersistentExpandableListView(Context context) {\r
+ super(context);\r
+ }\r
+\r
+ @Override\r
+ public Parcelable onSaveInstanceState() {\r
+ Bundle b = new Bundle();\r
+ long[] expandedIds = getExpandedIds();\r
+ b.putLongArray("ExpandedIds", expandedIds);\r
+ return b;\r
+ }\r
+\r
+ @Override\r
+ public void onRestoreInstanceState(Parcelable state) {\r
+ Bundle b = (Bundle) state;\r
+ long[] expandedIds = b.getLongArray("ExpandedIds");\r
+ restoreExpandedState(expandedIds);\r
+ }\r
+\r
+ private long[] getExpandedIds() {\r
+ ExpandableListAdapter adapter = getExpandableListAdapter();\r
+ if (adapter != null) {\r
+ int length = adapter.getGroupCount();\r
+ ArrayList<Long> expandedIds = new ArrayList<Long>();\r
+ for(int i=0; i < length; i++) {\r
+ if(this.isGroupExpanded(i)) {\r
+ expandedIds.add(adapter.getGroupId(i));\r
+ }\r
+ }\r
+ return toLongArray(expandedIds);\r
+ } else {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ private static long[] toLongArray(List<Long> list) {\r
+ long[] ret = new long[list.size()];\r
+ int i = 0;\r
+ for (Long e : list) \r
+ ret[i++] = e.longValue();\r
+ return ret;\r
+ }\r
+\r
+ private void restoreExpandedState(long[] expandedIds) {\r
+ if (expandedIds != null) {\r
+ ExpandableListAdapter adapter = getExpandableListAdapter();\r
+ if (adapter != null) {\r
+ for (int i=0; i<adapter.getGroupCount(); i++) {\r
+ long id = adapter.getGroupId(i);\r
+ if (inArray(expandedIds, id)) this.expandGroup(i);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private static boolean inArray(long[] array, long element) {\r
+ for (long l : array) {\r
+ if (l == element) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+\r
+}\r