]> git.gag.com Git - debian/openrocket/commitdiff
Rewrite the simulation graph component. It is now implemented as a fragment with...
authorkruland2607 <kruland2607@180e2498-e6e9-4542-8430-84ac67f01cd8>
Thu, 26 Jan 2012 15:36:15 +0000 (15:36 +0000)
committerkruland2607 <kruland2607@180e2498-e6e9-4542-8430-84ac67f01cd8>
Thu, 26 Jan 2012 15:36:15 +0000 (15:36 +0000)
SimulationChart now implements a flyweight pattern containing the simulationId so it can be serialized allows the os to pause the application and restore most of the state of the graph.  Currently the selected serieses are not persisted so the graph gets reset to the default.

The simulation view is operated in two different modes.  On tablets in landscape the graph appears in the right sidepane and the list on the left.  When a new simulation is selected, the old graph is pushed to the back stack.  When in portrait mode or on smaller sceens, the simluation graph is in a separate activity.

git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@376 180e2498-e6e9-4542-8430-84ac67f01cd8

15 files changed:
android/AndroidManifest.xml
android/res/layout-xlarge-land/openrocketviewer.xml [new file with mode: 0644]
android/res/layout/simulation_detail.xml [deleted file]
android/res/layout/simulation_event_dialog.xml [new file with mode: 0644]
android/res/layout/simulation_graph_activity.xml [new file with mode: 0644]
android/res/layout/simulation_series_dialog.xml [new file with mode: 0644]
android/res/menu/simulation_option_menu.xml
android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java
android/src/net/sf/openrocket/android/simulation/GraphicalActivity.java [deleted file]
android/src/net/sf/openrocket/android/simulation/SimulationChart.java
android/src/net/sf/openrocket/android/simulation/SimulationEventsDialog.java [new file with mode: 0644]
android/src/net/sf/openrocket/android/simulation/SimulationFragment.java [new file with mode: 0644]
android/src/net/sf/openrocket/android/simulation/SimulationSeriesDialog.java [new file with mode: 0644]
android/src/net/sf/openrocket/android/simulation/SimulationViewActivity.java [new file with mode: 0644]
android/src/net/sf/openrocket/android/simulation/SimulationViewer.java [deleted file]

index 9bc6a4c1886b5f93964ae82c7a7e4bfaeff2d74d..de2637f05f7a3ccc9f9cfdda91377f82a5ace970 100644 (file)
@@ -74,8 +74,7 @@
         <activity android:name=".android.motor.MotorHierarchicalBrowser" />\r
         <activity android:name=".android.motor.MotorDetails" />\r
         <activity android:name=".android.thrustcurve.TCQueryActivity" />\r
-        <activity android:name=".android.simulation.SimulationViewer" />\r
-        <activity android:name=".android.simulation.GraphicalActivity" />\r
+        <activity android:name=".android.simulation.SimulationViewActivity" />\r
         <activity android:name=".android.filebrowser.SimpleFileBrowser" />\r
     </application>\r
 \r
diff --git a/android/res/layout-xlarge-land/openrocketviewer.xml b/android/res/layout-xlarge-land/openrocketviewer.xml
new file mode 100644 (file)
index 0000000..5ecb9d7
--- /dev/null
@@ -0,0 +1,45 @@
+<?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="horizontal" >\r
+\r
+    <TabHost\r
+        android:id="@android:id/tabhost"\r
+        android:layout_width="match_parent"\r
+        android:layout_weight="4"\r
+        android:layout_height="match_parent" >\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="match_parent"\r
+            android:orientation="vertical" >\r
+\r
+            <TabWidget\r
+                android:id="@android:id/tabs"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="wrap_content"\r
+                android:layout_weight="0"\r
+                android:orientation="horizontal" />\r
+\r
+            <FrameLayout\r
+                android:id="@android:id/tabcontent"\r
+                android:layout_width="0dp"\r
+                android:layout_height="0dp"\r
+                android:layout_weight="0" />\r
+\r
+            <android.support.v4.view.ViewPager\r
+                android:id="@+id/pager"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="0dp"\r
+                android:layout_weight="1" />\r
+        </LinearLayout>\r
+    </TabHost>\r
+    \r
+    <LinearLayout android:id="@+id/sidepane"\r
+        android:layout_width="wrap_content"\r
+        android:layout_weight="1"\r
+        android:layout_height="wrap_content"\r
+        android:orientation="vertical"/>\r
+\r
+</LinearLayout>
\ No newline at end of file
diff --git a/android/res/layout/simulation_detail.xml b/android/res/layout/simulation_detail.xml
deleted file mode 100644 (file)
index c612fda..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-<?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" >
-
-    <TabHost
-        android:id="@+id/simulationConfigurationForm"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:background="@android:color/black" >
-
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="fill_parent"
-            android:orientation="vertical" >
-
-            <TabWidget
-                android:id="@android:id/tabs"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content" />
-
-            <FrameLayout
-                android:id="@android:id/tabcontent"
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent" >
-
-                <ListView
-                    android:id="@+id/simulationEventsList"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content" />
-
-                <LinearLayout
-                    android:id="@+id/simulationSeriesSelection"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="vertical" >
-
-                    <TextView
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:text="@string/simulationSeries1Label" />
-
-                    <Spinner
-                        android:id="@+id/simulationSeries1"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:drawSelectorOnTop="true" />
-
-                    <TextView
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:text="@string/simulationSeries2Label" />
-
-                    <Spinner
-                        android:id="@+id/simulationSeries2"
-                        android:layout_width="fill_parent"
-                        android:layout_height="wrap_content"
-                        android:drawSelectorOnTop="true" />
-
-                    <Button
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:onClick="draw"
-                        android:text="Draw" />
-                </LinearLayout>
-            </FrameLayout>
-        </LinearLayout>
-    </TabHost>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/android/res/layout/simulation_event_dialog.xml b/android/res/layout/simulation_event_dialog.xml
new file mode 100644 (file)
index 0000000..1fc4426
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <ListView
+        android:id="@+id/simulationEventsList"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/android/res/layout/simulation_graph_activity.xml b/android/res/layout/simulation_graph_activity.xml
new file mode 100644 (file)
index 0000000..c742b66
--- /dev/null
@@ -0,0 +1,13 @@
+<?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 android:layout_width="wrap_content" android:layout_height="wrap_content"/>\r
+    <LinearLayout\r
+    android:layout_width="match_parent"\r
+    android:id="@+id/sidepane"\r
+    android:layout_height="match_parent"\r
+    android:orientation="vertical" />\r
+</LinearLayout>
\ No newline at end of file
diff --git a/android/res/layout/simulation_series_dialog.xml b/android/res/layout/simulation_series_dialog.xml
new file mode 100644 (file)
index 0000000..5640418
--- /dev/null
@@ -0,0 +1,43 @@
+<?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" >
+
+    <!--  shim to get dialog correct size ?? -->
+    <View
+        android:layout_width="2000dp"
+        android:layout_height="0px"
+        android:layout_margin="0px"
+        android:orientation="horizontal" />
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/simulationSeries1Label" />
+
+    <Spinner
+        android:id="@+id/simulationSeries1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:drawSelectorOnTop="true" />
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/simulationSeries2Label" />
+
+    <Spinner
+        android:id="@+id/simulationSeries2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:drawSelectorOnTop="true" />
+
+    <Button
+        android:id="@+id/simulationOkButton"
+        android:layout_width="70dp"
+        android:layout_height="70dp"
+        android:layout_gravity="center_horizontal"
+        android:text="ok" />
+
+</LinearLayout>
\ No newline at end of file
index f964fb12852aec05a02b943ca6eacdf7f1a3cb86..5f7411b3abd50103987ac3b38de38f8f896bfa64 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu
   xmlns:android="http://schemas.android.com/apk/res/android">
-  <item android:title="Select Events" android:id="@+id/simulation_select_events_menu_option"/>
   <item android:title="Select Series" android:id="@+id/simulation_select_series_menu_option"/>
-  <item android:title="Preferences" android:id="@+id/preference_menu_option"/>
+  <item android:title="View Event" android:id="@+id/simulation_select_events_menu_option"/>
 </menu>
index 17b4209d652e9cf3d15c2d5c533fa50b39484f92..7a99eb1dee69abb2afa0e670411289d7106fce7c 100644 (file)
@@ -4,20 +4,26 @@ package net.sf.openrocket.android.rocket;
 import net.sf.openrocket.R;\r
 import net.sf.openrocket.android.ActivityHelpers;\r
 import net.sf.openrocket.android.Application;\r
-import net.sf.openrocket.android.simulation.SimulationViewer;\r
+import net.sf.openrocket.android.simulation.SimulationChart;\r
+import net.sf.openrocket.android.simulation.SimulationFragment;\r
+import net.sf.openrocket.android.simulation.SimulationViewActivity;\r
 import net.sf.openrocket.android.util.TabsAdapter;\r
 import net.sf.openrocket.document.OpenRocketDocument;\r
+import net.sf.openrocket.document.Simulation;\r
 import net.sf.openrocket.rocketcomponent.Configuration;\r
 import android.content.Intent;\r
 import android.content.SharedPreferences;\r
 import android.os.Bundle;\r
 import android.preference.PreferenceManager;\r
+import android.support.v4.app.Fragment;\r
 import android.support.v4.app.FragmentActivity;\r
+import android.support.v4.app.FragmentTransaction;\r
 import android.support.v4.view.ViewPager;\r
 import android.util.Log;\r
 import android.view.Menu;\r
 import android.view.MenuInflater;\r
 import android.view.MenuItem;\r
+import android.view.View;\r
 import android.widget.TabHost;\r
 \r
 public class OpenRocketViewer extends FragmentActivity\r
@@ -88,20 +94,6 @@ Simulations.OnSimulationSelectedListener
                return true;\r
        }\r
 \r
-       @Override\r
-       public boolean onOptionsItemSelected(MenuItem item) {\r
-               switch ( item.getItemId() ) {\r
-               /*              case android.R.id.home:\r
-                       Intent i = new Intent( this, Main.class );\r
-                       i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);\r
-                       startActivity(i);\r
-                       return true;\r
-                */\r
-               default:\r
-                       return super.onOptionsItemSelected(item);\r
-               }\r
-       }\r
-\r
        @Override\r
        public boolean onMenuItemSelected(int featureId, MenuItem item) {\r
                Log.d(TAG,"onMenuItemSelected" + item.getItemId());\r
@@ -118,9 +110,27 @@ Simulations.OnSimulationSelectedListener
 \r
        @Override\r
        public void onSimulationSelected(int simulationId) {\r
-               Intent i = new Intent(this, SimulationViewer.class);\r
-               i.putExtra("Simulation",simulationId);\r
-               startActivity(i);\r
+               View sidepane = findViewById(R.id.sidepane);\r
+               if ( /* if multi pane */ sidepane != null ) {\r
+                       Simulation sim = app.getRocketDocument().getSimulation(simulationId);\r
+                       SimulationChart chart = new SimulationChart(simulationId);\r
+\r
+                       Fragment graph = SimulationFragment.newInstance(chart);\r
+\r
+                       FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
+                       ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);\r
+                       // probably only want to update back stack for first time.\r
+                       ft.addToBackStack("simulationplot");\r
+                       ft.replace(R.id.sidepane, graph);\r
+                       ft.show(graph);\r
+                       ft.commit();\r
+\r
+\r
+               } else {\r
+                       Intent i = new Intent(this, SimulationViewActivity.class);\r
+                       i.putExtra("Simulation",simulationId);\r
+                       startActivity(i);\r
                }\r
+       }\r
 \r
 }\r
diff --git a/android/src/net/sf/openrocket/android/simulation/GraphicalActivity.java b/android/src/net/sf/openrocket/android/simulation/GraphicalActivity.java
deleted file mode 100644 (file)
index 8335bd8..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**\r
- * Copyright (C) 2009, 2010 SC 4ViewSoft SRL\r
- *  \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *  \r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *  \r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package net.sf.openrocket.android.simulation;\r
-\r
-import org.achartengine.ChartFactory;\r
-import org.achartengine.GraphicalView;\r
-import org.achartengine.chart.AbstractChart;\r
-\r
-import android.app.Activity;\r
-import android.os.Bundle;\r
-import android.view.Window;\r
-\r
-/**\r
- * An activity that encapsulates a graphical view of the chart.\r
- */\r
-public class GraphicalActivity extends Activity {\r
-  /** The encapsulated graphical view. */\r
-  private GraphicalView mView;\r
-  /** The chart to be drawn. */\r
-  private AbstractChart mChart;\r
-\r
-  @Override\r
-  protected void onCreate(Bundle savedInstanceState) {\r
-    super.onCreate(savedInstanceState);\r
-    requestWindowFeature(Window.FEATURE_NO_TITLE);\r
-    Bundle extras = getIntent().getExtras();\r
-    mChart = (AbstractChart) extras.getSerializable(ChartFactory.CHART);\r
-    mView = new GraphicalView(this, mChart);\r
-    String title = extras.getString(ChartFactory.TITLE);\r
-    if (title == null) {\r
-      requestWindowFeature(Window.FEATURE_NO_TITLE);\r
-    } else if (title.length() > 0) {\r
-      setTitle(title);\r
-    }\r
-    setContentView(mView);\r
-  }\r
-\r
-}
\ No newline at end of file
index e0b22bd860eb2406b2b2d6dc3b62b8acba3c5f48..00209457bdd31904428f7085a99fe44cca8c6e11 100644 (file)
  */\r
 package net.sf.openrocket.android.simulation;\r
 \r
+import java.io.Serializable;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
 \r
+import net.sf.openrocket.document.OpenRocketDocument;\r
+import net.sf.openrocket.document.Simulation;\r
 import net.sf.openrocket.simulation.FlightDataBranch;\r
 import net.sf.openrocket.simulation.FlightDataType;\r
-import net.sf.openrocket.simulation.FlightEvent;\r
 import net.sf.openrocket.unit.Unit;\r
 \r
-import org.achartengine.ChartFactory;\r
 import org.achartengine.chart.LineChart;\r
 import org.achartengine.chart.PointStyle;\r
 import org.achartengine.chart.XYChart;\r
@@ -32,78 +33,76 @@ import org.achartengine.model.XYSeries;
 import org.achartengine.renderer.XYMultipleSeriesRenderer;\r
 import org.achartengine.renderer.XYSeriesRenderer;\r
 \r
-import android.content.Context;\r
-import android.content.Intent;\r
 import android.graphics.Color;\r
 import android.graphics.Paint.Align;\r
 import android.util.Log;\r
 \r
 /**\r
- * Multiple temperature demo chart.\r
+ * This is really a flyweight object so we can serialize the\r
+ * values behind a simulation chart.  Since OpenRocketDocument, FlightDataBranch,\r
+ * FlightDataType, Unit and all the other underlying types are not serializable,\r
+ * we have to resort to persisting just the bare minimum of information.\r
+ * \r
+ * This also means without further changes to FlightDataType, we cannot actually\r
+ * restore the displayed series.\r
+ * \r
+ * TODO make FlightDataBranch serializable or at least reconstructable from\r
+ * from some the name.\r
+ * \r
  */\r
-public class SimulationChart {\r
+public class SimulationChart implements Serializable {\r
        \r
        private final static String TAG = "SimulationChart";\r
 \r
-       private FlightDataBranch flightDataBranch;\r
-       private FlightDataType series1;\r
-       private FlightDataType series2;\r
-       private final FlightDataType time = FlightDataType.TYPE_TIME;\r
-       private List<FlightEvent> flightEvents;\r
-       private String simulationName;\r
-\r
+       private final int simulationIndex;\r
+       private transient FlightDataType series1;\r
+       private transient FlightDataType series2;\r
+       \r
        // Define 4 different colors and point styles to use for the series.\r
        // For now only 2 series are supported though.\r
        private final static int[] colors = new int[] { Color.BLUE, Color.YELLOW, Color.GREEN, Color.RED };\r
        private final static PointStyle[] styles = new PointStyle[] { PointStyle.CIRCLE, PointStyle.DIAMOND,\r
                PointStyle.TRIANGLE, PointStyle.SQUARE };\r
 \r
-       /**\r
-        * @param simulationName the simulationName to set\r
-        */\r
-       public void setSimulationName(String simulationName) {\r
-               this.simulationName = simulationName;\r
+       public SimulationChart(int simulationIndex) {\r
+               super();\r
+               this.simulationIndex = simulationIndex;\r
        }\r
 \r
-       /**\r
-        * @param flightDataBranch the flightDataBranch to set\r
-        */\r
-       public void setFlightDataBranch(FlightDataBranch flightDataBranch) {\r
-               this.flightDataBranch = flightDataBranch;\r
+       private static String formatFlightDataTypeAxisLabel( FlightDataType fdt ) {\r
+               return fdt.getName() + " (" + fdt.getUnitGroup().getDefaultUnit().toString() + ")";\r
        }\r
 \r
-       /**\r
-        * @param series1 the series1 to set\r
-        */\r
        public void setSeries1(FlightDataType series1) {\r
                this.series1 = series1;\r
        }\r
 \r
-       /**\r
-        * @param series2 the series2 to set\r
-        */\r
        public void setSeries2(FlightDataType series2) {\r
                this.series2 = series2;\r
        }\r
 \r
-       /**\r
-        * @param flightEvents the flightEvents to set\r
-        */\r
-       public void setFlightEvents(List<FlightEvent> flightEvents) {\r
-               this.flightEvents = flightEvents;\r
+       public FlightDataBranch getFlightDataBranch( OpenRocketDocument rocketDocument ) {\r
+               Simulation sim = rocketDocument.getSimulation(simulationIndex);\r
+               FlightDataBranch flightDataBranch = sim.getSimulatedData().getBranch(0);\r
+               return flightDataBranch;\r
        }\r
-\r
-       private static String formatFlightDataTypeAxisLabel( FlightDataType fdt ) {\r
-               return fdt.getName() + " (" + fdt.getUnitGroup().getDefaultUnit().toString() + ")";\r
-       }\r
-\r
        /**\r
         * Executes the chart demo.\r
         * \r
         * @param context the context\r
         * @return the built intent\r
         */\r
-       public Intent execute(Context context) {\r
+       public XYChart buildChart(OpenRocketDocument rocketDocument) {\r
+\r
+               Simulation sim = rocketDocument.getSimulation(simulationIndex);\r
+               FlightDataBranch flightDataBranch = sim.getSimulatedData().getBranch(0);\r
+               FlightDataType time = FlightDataType.TYPE_TIME;\r
+               if (series1== null) {\r
+                       series1 = flightDataBranch.getTypes()[1];\r
+               }\r
+               if (series2== null) {\r
+                       series2 = flightDataBranch.getTypes()[2];\r
+               }\r
 \r
                /*\r
                 * TODO -\r
@@ -126,7 +125,7 @@ public class SimulationChart {
                renderer.setYLabels(10);\r
                renderer.setShowGrid(true);\r
                renderer.setZoomButtonsVisible(true);\r
-               renderer.setChartTitle(simulationName);\r
+               renderer.setChartTitle(sim.getName());\r
 \r
                renderer.setMargins(new int[] { 50, 30, 0, 20 });\r
                {\r
@@ -199,8 +198,9 @@ public class SimulationChart {
 \r
                        addXYSeries(dataset, series2.getName(), timevalues, series2values, 1);\r
                }\r
-               Intent intent = getLineChartIntent(context, dataset, renderer,"Simulation");\r
-               return intent;\r
+               XYChart chart = new LineChart(dataset, renderer);\r
+               \r
+               return chart;\r
        }\r
 \r
        private static void addXYSeries(XYMultipleSeriesDataset dataset, String titles, List<Double> xValues, List<Double> yValues, int scale) {\r
@@ -213,16 +213,6 @@ public class SimulationChart {
 \r
        }\r
 \r
-       private static Intent getLineChartIntent(Context context, XYMultipleSeriesDataset dataset,\r
-                       XYMultipleSeriesRenderer renderer, String activityTitle) {\r
-               //                  checkParameters(dataset, renderer);\r
-               Intent intent = new Intent(context, GraphicalActivity.class);\r
-               XYChart chart = new LineChart(dataset, renderer);\r
-               intent.putExtra(ChartFactory.CHART, chart);\r
-               intent.putExtra(ChartFactory.TITLE, activityTitle);\r
-               return intent;\r
-       }\r
-\r
        private static double computeMaxValueWithPadding( List<Double> list ) {\r
                double max = list.get(0);\r
                for( double v : list ) {\r
diff --git a/android/src/net/sf/openrocket/android/simulation/SimulationEventsDialog.java b/android/src/net/sf/openrocket/android/simulation/SimulationEventsDialog.java
new file mode 100644 (file)
index 0000000..21a7e78
--- /dev/null
@@ -0,0 +1,76 @@
+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.document.OpenRocketDocument;\r
+import net.sf.openrocket.simulation.FlightEvent;\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.ArrayAdapter;\r
+import android.widget.ListView;\r
+import android.widget.TextView;\r
+\r
+public class SimulationEventsDialog extends DialogFragment {\r
+\r
+       private SimulationChart chart;\r
+       private ListView eventList;\r
+\r
+       public static SimulationEventsDialog newInstance( SimulationChart chart ) {\r
+               SimulationEventsDialog d = new SimulationEventsDialog();\r
+               d.chart = chart;\r
+               return d;\r
+       }\r
+\r
+       @Override\r
+       public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\r
+\r
+               View v = inflater.inflate(R.layout.simulation_event_dialog, container, false);\r
+\r
+               eventList = (ListView) v.findViewById(R.id.simulationEventsList);\r
+\r
+               OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();\r
+               // Initialize the eventList\r
+               ArrayAdapter<FlightEvent> events = new ArrayAdapter<FlightEvent>(\r
+                               getActivity(),\r
+                               android.R.layout.simple_list_item_1,\r
+                               chart.getFlightDataBranch(rocketDocument).getEvents() ) {\r
+\r
+                       @Override\r
+                       public View getView(int position, View convertView,\r
+                                       ViewGroup parent) {\r
+                               View v = convertView;\r
+                               if ( v == null ) {\r
+                                       LayoutInflater li = inflater;\r
+                                       v = li.inflate(android.R.layout.simple_list_item_1,null);\r
+                               }\r
+                               FlightEvent event = this.getItem(position);\r
+                               ((TextView)v.findViewById(android.R.id.text1)).setText( event.getType().toString() + " " + event.getTime() + " (s)" );\r
+                               return v;\r
+                       }\r
+\r
+               };\r
+               // Events are not selectable for plotting right now.\r
+               //eventList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);\r
+               eventList.setAdapter(events);\r
+               return v;\r
+       }\r
+\r
+       @Override\r
+       public void onCreate(Bundle savedInstanceState) {\r
+               super.onCreate(savedInstanceState);\r
+               if (savedInstanceState != null ) {\r
+                       chart = (SimulationChart) savedInstanceState.getSerializable("chart");\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void onSaveInstanceState(Bundle arg0) {\r
+               super.onSaveInstanceState(arg0);\r
+               arg0.putSerializable("chart", chart);\r
+       }\r
+\r
+\r
+}\r
diff --git a/android/src/net/sf/openrocket/android/simulation/SimulationFragment.java b/android/src/net/sf/openrocket/android/simulation/SimulationFragment.java
new file mode 100644 (file)
index 0000000..dfcd571
--- /dev/null
@@ -0,0 +1,99 @@
+\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.document.OpenRocketDocument;\r
+\r
+import org.achartengine.GraphicalView;\r
+import org.achartengine.chart.XYChart;\r
+\r
+import android.os.Bundle;\r
+import android.support.v4.app.Fragment;\r
+import android.view.LayoutInflater;\r
+import android.view.Menu;\r
+import android.view.MenuInflater;\r
+import android.view.MenuItem;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+\r
+/**\r
+ * An activity that encapsulates a graphical view of the chart.\r
+ */\r
+public class SimulationFragment extends Fragment implements SimulationSeriesDialog.OnConfirmListener {\r
+       \r
+       SimulationChart chart;\r
+\r
+       ViewGroup container;\r
+       \r
+       /** The encapsulated graphical view. */\r
+       private GraphicalView mView;\r
+       /** The chart to be drawn. */\r
+       private XYChart mChart;\r
+\r
+       public static SimulationFragment newInstance( SimulationChart chart ) {\r
+               SimulationFragment frag = new SimulationFragment();\r
+               frag.chart = chart;\r
+               return frag;\r
+       }\r
+\r
+       @Override\r
+       public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\r
+               setRetainInstance(false);\r
+               setHasOptionsMenu(true);\r
+               OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();\r
+\r
+               this.container = container;\r
+               if (savedInstanceState != null ) {\r
+                       chart = (SimulationChart) savedInstanceState.getSerializable("chart");\r
+               }\r
+               mChart = chart.buildChart(rocketDocument);\r
+               mView = new GraphicalView(container.getContext(), mChart);\r
+               return mView;\r
+       }\r
+\r
+       @Override\r
+       public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {\r
+               // TODO without the clear it seems to create multiple copies\r
+               // of the menu items on orientation change.\r
+               menu.clear();\r
+               inflater.inflate(R.menu.simulation_option_menu, menu);\r
+       }\r
+\r
+       @Override\r
+       public boolean onOptionsItemSelected(MenuItem item) {\r
+               switch (item.getItemId())\r
+               {\r
+               case R.id.simulation_select_series_menu_option:\r
+                       SimulationSeriesDialog seriesDialog = SimulationSeriesDialog.newInstance(chart);\r
+                       seriesDialog.show(getFragmentManager(), "AbraCadaver");\r
+                       seriesDialog.setOnConfirmListener(this);\r
+                       return true;\r
+               case R.id.simulation_select_events_menu_option:\r
+                       SimulationEventsDialog eventsDialog = SimulationEventsDialog.newInstance(chart);\r
+                       eventsDialog.show(getFragmentManager(), "AbraCadaver");\r
+                       return true;\r
+               default:\r
+                       return super.onOptionsItemSelected(item);\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void onConfirm() {\r
+               OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();\r
+\r
+               mChart = chart.buildChart(rocketDocument);\r
+               ViewGroup parent = (ViewGroup) mView.getParent();\r
+               parent.removeView(mView);\r
+               mView = new GraphicalView(container.getContext(), mChart);\r
+               parent.addView(mView);\r
+       }\r
+\r
+       @Override\r
+       public void onSaveInstanceState(Bundle outState) {\r
+               super.onSaveInstanceState(outState);\r
+               outState.putSerializable("chart", chart);\r
+\r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/android/src/net/sf/openrocket/android/simulation/SimulationSeriesDialog.java b/android/src/net/sf/openrocket/android/simulation/SimulationSeriesDialog.java
new file mode 100644 (file)
index 0000000..f3622c5
--- /dev/null
@@ -0,0 +1,113 @@
+package net.sf.openrocket.android.simulation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import net.sf.openrocket.R;\r
+import net.sf.openrocket.android.Application;\r
+import net.sf.openrocket.document.OpenRocketDocument;\r
+import net.sf.openrocket.simulation.FlightDataType;\r
+import android.content.DialogInterface;\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.ArrayAdapter;\r
+import android.widget.Button;\r
+import android.widget.Spinner;\r
+import android.widget.TextView;\r
+\r
+public class SimulationSeriesDialog extends DialogFragment {\r
+       \r
+       public interface OnConfirmListener {\r
+               public void onConfirm();\r
+       }\r
+\r
+       private Spinner series1Spinner;\r
+       private Spinner series2Spinner;\r
+\r
+       private SimulationChart chart;\r
+       private OnConfirmListener listener;\r
+\r
+       public static SimulationSeriesDialog newInstance( SimulationChart chart ) {\r
+               SimulationSeriesDialog d = new SimulationSeriesDialog();\r
+               d.chart = chart;\r
+               return d;\r
+       }\r
+\r
+       public void setOnConfirmListener(OnConfirmListener listener) {\r
+               this.listener = listener;\r
+       }\r
+\r
+       @Override\r
+       public void onCreate(Bundle savedInstanceState) {\r
+               super.onCreate(savedInstanceState);\r
+               if (savedInstanceState != null ) {\r
+                       chart = (SimulationChart) savedInstanceState.getSerializable("chart");\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void onSaveInstanceState(Bundle arg0) {\r
+               super.onSaveInstanceState(arg0);\r
+               arg0.putSerializable("chart", chart);\r
+       }\r
+\r
+       @Override\r
+       public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\r
+\r
+               View v = inflater.inflate(R.layout.simulation_series_dialog, container, false);\r
+               \r
+               OpenRocketDocument rocketDocument = ((Application)getActivity().getApplication()).getRocketDocument();\r
+\r
+               Button okButton = (Button) v.findViewById(R.id.simulationOkButton);\r
+               okButton.setOnClickListener( new View.OnClickListener() {\r
+\r
+                       @Override\r
+                       public void onClick(View v) {\r
+                               chart.setSeries1((FlightDataType)series1Spinner.getSelectedItem());\r
+                               chart.setSeries2((FlightDataType)series2Spinner.getSelectedItem());\r
+\r
+                               if ( listener != null ) {\r
+                                       listener.onConfirm();\r
+                               }\r
+                               SimulationSeriesDialog.this.dismiss();\r
+                       }\r
+                       \r
+               });\r
+\r
+               series1Spinner = (Spinner) v.findViewById(R.id.simulationSeries1);\r
+               series2Spinner = (Spinner) v.findViewById(R.id.simulationSeries2);\r
+\r
+               List<FlightDataType> selectableSeries = new ArrayList<FlightDataType>();\r
+               for( FlightDataType fdt : chart.getFlightDataBranch(rocketDocument).getTypes() ) {\r
+                       if ( fdt == FlightDataType.TYPE_TIME ) { \r
+\r
+                       } else {\r
+                               selectableSeries.add(fdt);\r
+                       }\r
+               }\r
+               ArrayAdapter<FlightDataType> serieses = new ArrayAdapter<FlightDataType>(getActivity(),android.R.layout.simple_spinner_item,selectableSeries) {\r
+\r
+                       @Override\r
+                       public View getView(int position, View convertView,     ViewGroup parent) {\r
+                               View v = convertView;\r
+                               if ( v == null ) {\r
+                                       LayoutInflater li = inflater;\r
+                                       v = li.inflate(android.R.layout.simple_spinner_item,null);\r
+                               }\r
+                               FlightDataType fdt = this.getItem(position);\r
+                               ((TextView)v.findViewById(android.R.id.text1)).setText( fdt.toString() );\r
+                               return v;\r
+                       }\r
+\r
+               };\r
+               series1Spinner.setAdapter(serieses);\r
+               series2Spinner.setAdapter(serieses);\r
+\r
+\r
+               return v;\r
+       }\r
+\r
+}\r
diff --git a/android/src/net/sf/openrocket/android/simulation/SimulationViewActivity.java b/android/src/net/sf/openrocket/android/simulation/SimulationViewActivity.java
new file mode 100644 (file)
index 0000000..ec0895d
--- /dev/null
@@ -0,0 +1,52 @@
+/**\r
+ * Copyright (C) 2009, 2010 SC 4ViewSoft SRL\r
+ *  \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *  \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *  \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package net.sf.openrocket.android.simulation;\r
+\r
+import net.sf.openrocket.android.Application;\r
+import net.sf.openrocket.document.OpenRocketDocument;\r
+import net.sf.openrocket.document.Simulation;\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
+\r
+/**\r
+ * An activity that encapsulates a graphical view of the chart.\r
+ */\r
+public class SimulationViewActivity extends FragmentActivity {\r
+\r
+       @Override\r
+       protected void onCreate(Bundle savedInstanceState) {\r
+               super.onCreate(savedInstanceState);\r
+               //setContentView(R.layout.simulation_graph_activity);\r
+               int simulationNumber = getIntent().getIntExtra("Simulation", 0);\r
+\r
+               final OpenRocketDocument rocketDocument = ((Application)getApplication()).getRocketDocument();\r
+\r
+               Simulation sim = rocketDocument.getSimulation(simulationNumber);\r
+               \r
+               SimulationChart chart = new SimulationChart( simulationNumber);\r
+               chart.setSeries1(sim.getSimulatedData().getBranch(0).getTypes()[1]);\r
+               chart.setSeries2(sim.getSimulatedData().getBranch(0).getTypes()[2]);\r
+\r
+               Fragment graph = SimulationFragment.newInstance(chart);\r
+\r
+               FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
+               ft.add(android.R.id.content, graph);\r
+               ft.commit();\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/android/src/net/sf/openrocket/android/simulation/SimulationViewer.java b/android/src/net/sf/openrocket/android/simulation/SimulationViewer.java
deleted file mode 100644 (file)
index 97c2568..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-package net.sf.openrocket.android.simulation;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import net.sf.openrocket.R;\r
-import net.sf.openrocket.android.Application;\r
-import net.sf.openrocket.document.Simulation;\r
-import net.sf.openrocket.simulation.FlightDataBranch;\r
-import net.sf.openrocket.simulation.FlightDataType;\r
-import net.sf.openrocket.simulation.FlightEvent;\r
-import android.app.Activity;\r
-import android.content.Intent;\r
-import android.os.Bundle;\r
-import android.util.Log;\r
-import android.util.SparseBooleanArray;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.ViewGroup;\r
-import android.widget.ArrayAdapter;\r
-import android.widget.ListView;\r
-import android.widget.Spinner;\r
-import android.widget.TabHost;\r
-import android.widget.TextView;\r
-\r
-public class SimulationViewer extends Activity {\r
-\r
-       private final static String TAG = "SimulationViewer";\r
-\r
-       private ListView eventList;\r
-       private Spinner series1Spinner;\r
-       private Spinner series2Spinner;\r
-\r
-       private Simulation sim;\r
-       private FlightDataBranch data;\r
-\r
-       @Override\r
-       public void onCreate(Bundle savedInstanceState) {\r
-               super.onCreate(savedInstanceState);\r
-               Log.d(TAG,"onCreate Bundle = "+ String.valueOf(savedInstanceState));\r
-               setContentView(R.layout.simulation_detail);\r
-\r
-               Intent i = getIntent();\r
-               int simnumber = i.getIntExtra("Simulation", 0);\r
-               sim = ((Application)this.getApplication()).getRocketDocument().getSimulation(simnumber);\r
-               data = sim.getSimulatedData().getBranch(0);\r
-\r
-               TabHost tabs=(TabHost)findViewById(R.id.simulationConfigurationForm);\r
-\r
-               tabs.setup();\r
-\r
-               TabHost.TabSpec spec=tabs.newTabSpec("tag1");\r
-\r
-               spec.setContent(R.id.simulationEventsList);\r
-               spec.setIndicator("Events");\r
-               tabs.addTab(spec);\r
-\r
-               spec=tabs.newTabSpec("tag2");\r
-               spec.setContent(R.id.simulationSeriesSelection);\r
-               spec.setIndicator("Series");\r
-               tabs.addTab(spec);      \r
-\r
-               eventList = (ListView) findViewById(R.id.simulationEventsList);\r
-\r
-               // Initialize the eventList\r
-               ArrayAdapter<FlightEvent> events = new ArrayAdapter<FlightEvent>(this,android.R.layout.simple_list_item_1,data.getEvents()) {\r
-\r
-                       @Override\r
-                       public View getView(int position, View convertView,\r
-                                       ViewGroup parent) {\r
-                               View v = convertView;\r
-                               if ( v == null ) {\r
-                                       LayoutInflater li = getLayoutInflater();\r
-                                       v = li.inflate(android.R.layout.simple_list_item_1,null);\r
-                               }\r
-                               FlightEvent event = this.getItem(position);\r
-                               ((TextView)v.findViewById(android.R.id.text1)).setText( event.getType().toString() + " " + event.getTime() + " (s)" );\r
-                               return v;\r
-                       }\r
-\r
-               };\r
-               // Events are not selectable for plotting right now.\r
-               //eventList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);\r
-               eventList.setAdapter(events);\r
-\r
-               series1Spinner = (Spinner) findViewById(R.id.simulationSeries1);\r
-               series2Spinner = (Spinner) findViewById(R.id.simulationSeries2);\r
-\r
-               List<FlightDataType> selectableSeries = new ArrayList<FlightDataType>();\r
-               for( FlightDataType fdt : data.getTypes() ) {\r
-                       if ( fdt == FlightDataType.TYPE_TIME ) { \r
-\r
-                       } else {\r
-                               selectableSeries.add(fdt);\r
-                       }\r
-               }\r
-               ArrayAdapter<FlightDataType> serieses = new ArrayAdapter<FlightDataType>(this,android.R.layout.simple_spinner_item,selectableSeries) {\r
-\r
-                       @Override\r
-                       public View getView(int position, View convertView,\r
-                                       ViewGroup parent) {\r
-                               View v = convertView;\r
-                               if ( v == null ) {\r
-                                       LayoutInflater li = getLayoutInflater();\r
-                                       v = li.inflate(android.R.layout.simple_spinner_item,null);\r
-                               }\r
-                               FlightDataType fdt = this.getItem(position);\r
-                               ((TextView)v.findViewById(android.R.id.text1)).setText( fdt.toString() );\r
-                               return v;\r
-                       }\r
-\r
-               };\r
-               series1Spinner.setAdapter(serieses);\r
-               series2Spinner.setAdapter(serieses);\r
-\r
-       }\r
-\r
-       public void draw( View v ) {\r
-               List<FlightEvent> eventsToShow = new ArrayList<FlightEvent>();\r
-               /* Events are not selectable for plotting right now.\r
-               {\r
-                       SparseBooleanArray eventsSelected = eventList.getCheckedItemPositions();\r
-                       List<FlightEvent> flightEvents = data.getEvents();\r
-                       for( int i=0; i< flightEvents.size(); i++ ) {\r
-                               if ( eventsSelected.get(i) ) {\r
-                                       eventsToShow.add(flightEvents.get(i) );\r
-                               }\r
-                       }\r
-               }\r
-               */\r
-               FlightDataType series1 = (FlightDataType) series1Spinner.getSelectedItem();\r
-               Log.d(TAG,"sereis1 = " + series1.toString());\r
-               FlightDataType series2 = (FlightDataType) series2Spinner.getSelectedItem();\r
-               Log.d(TAG,"series2 = " + series2.toString());\r
-\r
-               SimulationChart chart = new SimulationChart();\r
-               chart.setSimulationName( sim.getName() );\r
-               chart.setFlightDataBranch(data);\r
-               chart.setSeries1(series1);\r
-               chart.setSeries2(series2);\r
-               chart.setFlightEvents(eventsToShow);\r
-               \r
-               startActivity(chart.execute(this));\r
-       }\r
-\r
-}\r