1 package net.sf.openrocket.android.rocket;
\r
6 import net.sf.openrocket.R;
\r
7 import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
\r
8 import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
\r
9 import net.sf.openrocket.aerodynamics.FlightConditions;
\r
10 import net.sf.openrocket.aerodynamics.WarningSet;
\r
11 import net.sf.openrocket.android.Application;
\r
12 import net.sf.openrocket.android.PreferencesActivity;
\r
13 import net.sf.openrocket.android.motor.MotorHierarchicalBrowser;
\r
14 import net.sf.openrocket.android.rocket.RocketComponentTreeAdapter.RocketComponentWithId;
\r
15 import net.sf.openrocket.android.simulation.SimulationViewer;
\r
16 import net.sf.openrocket.document.OpenRocketDocument;
\r
17 import net.sf.openrocket.document.Simulation;
\r
18 import net.sf.openrocket.masscalc.BasicMassCalculator;
\r
19 import net.sf.openrocket.masscalc.MassCalculator;
\r
20 import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
\r
21 import net.sf.openrocket.rocketcomponent.Configuration;
\r
22 import net.sf.openrocket.rocketcomponent.Rocket;
\r
23 import net.sf.openrocket.rocketcomponent.RocketComponent;
\r
24 import net.sf.openrocket.rocketcomponent.RocketUtils;
\r
25 import net.sf.openrocket.unit.Unit;
\r
26 import net.sf.openrocket.unit.UnitGroup;
\r
27 import net.sf.openrocket.util.Coordinate;
\r
28 import pl.polidea.treeview.InMemoryTreeStateManager;
\r
29 import pl.polidea.treeview.TreeBuilder;
\r
30 import pl.polidea.treeview.TreeStateManager;
\r
31 import pl.polidea.treeview.TreeViewList;
\r
32 import android.app.Activity;
\r
33 import android.app.ProgressDialog;
\r
34 import android.content.Intent;
\r
35 import android.content.SharedPreferences;
\r
36 import android.net.Uri;
\r
37 import android.os.Bundle;
\r
38 import android.preference.PreferenceManager;
\r
39 import android.util.Log;
\r
40 import android.view.LayoutInflater;
\r
41 import android.view.Menu;
\r
42 import android.view.MenuInflater;
\r
43 import android.view.MenuItem;
\r
44 import android.view.View;
\r
45 import android.view.ViewGroup;
\r
46 import android.widget.AdapterView;
\r
47 import android.widget.AdapterView.OnItemClickListener;
\r
48 import android.widget.ArrayAdapter;
\r
49 import android.widget.ListAdapter;
\r
50 import android.widget.ListView;
\r
51 import android.widget.Spinner;
\r
52 import android.widget.TabHost;
\r
53 import android.widget.TextView;
\r
55 public class OpenRocketViewer extends Activity
\r
56 implements SharedPreferences.OnSharedPreferenceChangeListener
\r
59 private static final String TAG = "OpenRocketViewer";
\r
61 private ProgressDialog progress;
\r
63 private Spinner configurationSpinner;
\r
64 private TreeViewList componentTree;
\r
65 private ListView simulationList;
\r
67 /* Calculation of CP and CG */
\r
68 private AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
\r
69 private MassCalculator massCalculator = new BasicMassCalculator();
\r
71 OpenRocketDocument rocketDocument;
\r
72 Configuration rocketConfiguration;
\r
74 private Application app;
\r
76 private final static int PICK_ORK_FILE_RESULT = 1;
\r
79 * @see android.app.Activity#onCreate(android.os.Bundle)
\r
82 protected void onCreate(Bundle savedInstanceState) {
\r
83 super.onCreate(savedInstanceState);
\r
85 Log.d(TAG,"In onCreate");
\r
87 app = (Application) this.getApplication();
\r
89 setContentView(R.layout.openrocketviewer);
\r
91 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
\r
92 prefs.registerOnSharedPreferenceChangeListener(this);
\r
94 TabHost tabs=(TabHost)findViewById(R.id.openrocketviewerTabHost);
\r
98 TabHost.TabSpec spec=tabs.newTabSpec("tag1");
\r
100 spec.setContent(R.id.openrocketviewerOverview);
\r
101 spec.setIndicator("Overview");
\r
104 spec=tabs.newTabSpec("tag2");
\r
105 spec.setContent(R.id.openrocketviewerComponentTree);
\r
106 spec.setIndicator("Components");
\r
107 tabs.addTab(spec);
\r
109 spec=tabs.newTabSpec("tag3");
\r
110 spec.setContent(R.id.openrocketviewerSimulationList);
\r
111 spec.setIndicator("Simulations");
\r
112 tabs.addTab(spec);
\r
114 configurationSpinner = (Spinner) findViewById(R.id.openrocketviewerConfigurationSpinner);
\r
115 componentTree = (TreeViewList) findViewById(R.id.openrocketviewerComponentTree);
\r
116 simulationList = (ListView) findViewById(R.id.openrocketviewerSimulationList);
\r
118 Intent i = getIntent();
\r
119 Uri file = i.getData();
\r
121 if ( file == null ) {
\r
122 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
\r
123 intent.setType("file/*");
\r
124 startActivityForResult(intent,PICK_ORK_FILE_RESULT);
\r
132 protected void onDestroy() {
\r
133 if ( progress != null ) {
\r
134 if ( progress.isShowing() ) {
\r
135 progress.dismiss();
\r
143 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
\r
144 // TODO Auto-generated method stub
\r
145 switch(requestCode){
\r
146 case PICK_ORK_FILE_RESULT:
\r
147 if(resultCode==RESULT_OK){
\r
148 Uri file = data.getData();
\r
155 private void loadOrkFile( Uri file ) {
\r
156 Log.d(TAG,"Use ork file: " + file);
\r
157 String path = file.getPath();
\r
158 File orkFile = new File(path);
\r
159 progress = ProgressDialog.show(this, "Loading file", "");
\r
161 final OpenRocketLoaderTask task = new OpenRocketLoaderTask() {
\r
164 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
\r
167 protected void onPostExecute(OpenRocketDocument result) {
\r
168 super.onPostExecute(result);
\r
169 app.setRocketDocument( result );
\r
175 task.execute(orkFile);
\r
180 * @see android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged(android.content.SharedPreferences, java.lang.String)
\r
183 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
\r
184 // just in case the user changed the units, we redraw.
\r
185 PreferencesActivity.initializePreferences(getApplication(), PreferenceManager.getDefaultSharedPreferences(this));
\r
189 private void updateContents() {
\r
191 rocketDocument = app.getRocketDocument();
\r
192 rocketConfiguration = rocketDocument.getDefaultConfiguration();
\r
193 Rocket rocket = rocketDocument.getRocket();
\r
195 setTitle(rocket.getName());
\r
197 String[] motorConfigs = rocket.getMotorConfigurationIDs();
\r
198 ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item);
\r
199 for( String config: motorConfigs ) {
\r
200 spinnerAdapter.add(rocket.getMotorConfigurationNameOrDescription(config));
\r
203 configurationSpinner.setAdapter(spinnerAdapter);
\r
204 configurationSpinner.setOnItemSelectedListener( new AdapterView.OnItemSelectedListener() {
\r
207 * @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long)
\r
210 public void onItemSelected(AdapterView<?> arg0, View arg1,
\r
211 int arg2, long arg3) {
\r
213 String selectedConfigId = rocketDocument.getRocket().getMotorConfigurationIDs()[arg2];
\r
214 rocketConfiguration.setMotorConfigurationID(selectedConfigId);
\r
215 Coordinate cp = aerodynamicCalculator.getWorstCP(rocketConfiguration,
\r
216 new FlightConditions(rocketConfiguration),
\r
219 Coordinate cg = massCalculator.getCG(rocketConfiguration, MassCalcType.LAUNCH_MASS);
\r
221 Unit lengthUnit = UnitGroup.UNITS_LENGTH.getDefaultUnit();
\r
222 Unit massUnit = UnitGroup.UNITS_MASS.getDefaultUnit();
\r
223 Unit stabilityUnit = UnitGroup.stabilityUnits(rocketConfiguration).getDefaultUnit();
\r
225 ((TextView)findViewById(R.id.openrocketviewerCP)).setText(lengthUnit.toStringUnit(cp.x));
\r
226 ((TextView)findViewById(R.id.openrocketviewerCG)).setText(lengthUnit.toStringUnit(cg.x));
\r
227 ((TextView)findViewById(R.id.openrocketviewerLiftOffWeight)).setText(massUnit.toStringUnit(cg.weight));
\r
228 ((TextView)findViewById(R.id.openrocketviewerStabilityMargin)).setText(stabilityUnit.toStringUnit(cp.x-cg.x));
\r
233 * @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView)
\r
236 public void onNothingSelected(AdapterView<?> arg0) {
\r
237 ((TextView)findViewById(R.id.openrocketviewerCP)).setText("");
\r
238 ((TextView)findViewById(R.id.openrocketviewerCG)).setText("");
\r
239 ((TextView)findViewById(R.id.openrocketviewerLiftOffWeight)).setText("");
\r
240 ((TextView)findViewById(R.id.openrocketviewerStabilityMargin)).setText("");
\r
245 Unit lengthUnit = UnitGroup.UNITS_LENGTH.getDefaultUnit();
\r
246 Unit massUnit = UnitGroup.UNITS_MASS.getDefaultUnit();
\r
248 Coordinate cg = RocketUtils.getCG(rocket, MassCalcType.NO_MOTORS);
\r
249 double length = RocketUtils.getLength(rocket);
\r
250 ((TextView)findViewById(R.id.openrocketviewerDesigner)).setText(rocket.getDesigner());
\r
251 ((TextView)findViewById(R.id.openrocketviewerLength)).setText(lengthUnit.toStringUnit(length));
\r
252 ((TextView)findViewById(R.id.openrocketviewerMass)).setText(massUnit.toStringUnit(cg.weight));
\r
253 ((TextView)findViewById(R.id.openrocketviewerStageCount)).setText(String.valueOf(rocket.getStageCount()));
\r
256 ArrayAdapter<Simulation> sims = new ArrayAdapter<Simulation>(this,android.R.layout.simple_list_item_2,rocketDocument.getSimulations()) {
\r
259 public View getView(int position, View convertView, ViewGroup parent) {
\r
260 View v = convertView;
\r
262 LayoutInflater li = getLayoutInflater();
\r
263 v = li.inflate(android.R.layout.simple_list_item_2,null);
\r
265 Simulation sim = this.getItem(position);
\r
266 ((TextView)v.findViewById(android.R.id.text1)).setText( sim.getName() );
\r
267 StringBuilder sb = new StringBuilder();
\r
268 sb.append("motors: ").append(sim.getConfiguration().getMotorConfigurationDescription());
\r
269 Unit distanceUnit = UnitGroup.UNITS_DISTANCE.getDefaultUnit();
\r
270 sb.append(" apogee: ").append( distanceUnit.toStringUnit(sim.getSimulatedData().getMaxAltitude()));
\r
271 sb.append(" time: ").append(sim.getSimulatedData().getFlightTime()).append("s");
\r
272 ((TextView)v.findViewById(android.R.id.text2)).setText( sb.toString() );
\r
277 simulationList.setOnItemClickListener( new OnItemClickListener() {
\r
279 public void onItemClick(AdapterView l, View v, int position, long id) {
\r
280 Intent i = new Intent(OpenRocketViewer.this, SimulationViewer.class);
\r
281 Log.d(TAG,"onItemClick simulation number " + id );
\r
282 i.putExtra("Simulation",(int)id);
\r
287 simulationList.setAdapter(sims);
\r
289 componentTree.setAdapter( buildAdapter( rocket ) );
\r
291 if ( progress.isShowing() ) {
\r
292 progress.dismiss();
\r
297 public boolean onCreateOptionsMenu(Menu menu) {
\r
298 MenuInflater inflater = getMenuInflater();
\r
299 inflater.inflate(R.menu.rocket_viewer_option_menu, menu);
\r
304 public boolean onMenuItemSelected(int featureId, MenuItem item) {
\r
305 Log.d(TAG,"onMenuItemSelected" + item.getItemId());
\r
306 switch(item.getItemId()) {
\r
307 case R.id.motor_list_menu_option:
\r
308 startMotorBrowser();
\r
310 case R.id.preference_menu_option:
\r
311 Intent intent = new Intent().setClass(this, PreferencesActivity.class);
\r
312 this.startActivity(intent);
\r
315 return super.onMenuItemSelected(featureId, item);
\r
318 public void startMotorBrowser() {
\r
319 Log.d(TAG,"motorBrowserButton clicked");
\r
320 Intent i = new Intent(OpenRocketViewer.this, MotorHierarchicalBrowser.class);
\r
324 private ListAdapter buildAdapter( Rocket rocket ) {
\r
326 final int[] DEMO_NODES = new int[] { 0, 0, 1, 1, 1, 2, 2, 1,
\r
327 1, 2, 1, 0, 0, 0, 1, 2, 3, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1 };
\r
328 final int LEVEL_NUMBER = 4;
\r
330 TreeStateManager<Long> manager = new InMemoryTreeStateManager<Long>();
\r
331 final TreeBuilder<Long> treeBuilder = new TreeBuilder<Long>(manager);
\r
332 for (int i = 0; i < DEMO_NODES.length; i++) {
\r
333 treeBuilder.sequentiallyAddNextNode((long) i, DEMO_NODES[i]);
\r
336 return new SimpleStandardAdapter(this, manager, LEVEL_NUMBER);
\r
339 TreeStateManager<RocketComponentWithId> manager = new InMemoryTreeStateManager<RocketComponentWithId>();
\r
340 TreeBuilder<RocketComponentWithId> treeBuilder = new TreeBuilder<RocketComponentWithId>(manager);
\r
342 int depth = buildRecursive( rocket, treeBuilder, 0 );
\r
343 return new RocketComponentTreeAdapter(this, manager, depth+1);
\r
347 private int buildRecursive( RocketComponent comp, TreeBuilder<RocketComponentWithId> builder, int depth ) {
\r
350 int maxDepth = depth;
\r
352 RocketComponentWithId rcid = new RocketComponentWithId(comp, id++);
\r
354 // Add this component.
\r
355 builder.sequentiallyAddNextNode(rcid, depth);
\r
357 if ( comp.allowsChildren() ) {
\r
359 for( RocketComponent child : comp.getChildren() ) {
\r
360 int childDepth = buildRecursive( child, builder, depth+1);
\r
361 if ( childDepth > maxDepth) {
\r
362 maxDepth = childDepth;
\r