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:
parent
6185091ee1
commit
02d9954ff1
23
android/res/layout/motor_config_delay_dialog.xml
Normal file
23
android/res/layout/motor_config_delay_dialog.xml
Normal 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>
|
46
android/res/layout/motor_config_item.xml
Normal file
46
android/res/layout/motor_config_item.xml
Normal 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>
|
13
android/res/layout/motor_list_dialog.xml
Normal file
13
android/res/layout/motor_list_dialog.xml
Normal 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>
|
28
android/res/layout/rocket_configurations.xml
Normal file
28
android/res/layout/rocket_configurations.xml
Normal 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>
|
61
android/res/layout/simulation_condition_dialog.xml
Normal file
61
android/res/layout/simulation_condition_dialog.xml
Normal 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>
|
@ -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>
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
280
android/src/net/sf/openrocket/android/rocket/Configurations.java
Normal file
280
android/src/net/sf/openrocket/android/rocket/Configurations.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user