Various changes to android application. Separate the loading of an ork file into...
[debian/openrocket] / android / src / net / sf / openrocket / android / motor / BurnPlotFragment.java
1 package net.sf.openrocket.android.motor;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.List;\r
5 import java.util.Vector;\r
6 \r
7 import net.sf.openrocket.R;\r
8 import android.app.Activity;\r
9 import android.graphics.Color;\r
10 import android.graphics.PointF;\r
11 import android.os.Bundle;\r
12 import android.support.v4.app.Fragment;\r
13 import android.util.Log;\r
14 import android.view.LayoutInflater;\r
15 import android.view.MotionEvent;\r
16 import android.view.ScaleGestureDetector;\r
17 import android.view.View;\r
18 import android.view.View.OnTouchListener;\r
19 import android.view.ViewGroup;\r
20 \r
21 import com.androidplot.xy.BoundaryMode;\r
22 import com.androidplot.xy.LineAndPointFormatter;\r
23 import com.androidplot.xy.LineAndPointRenderer;\r
24 import com.androidplot.xy.SimpleXYSeries;\r
25 import com.androidplot.xy.XYPlot;\r
26 import com.androidplot.xy.YValueMarker;\r
27 \r
28 public class BurnPlotFragment extends Fragment implements OnTouchListener {\r
29 \r
30         private final static String TAG = "BurnPlotFragment";\r
31 \r
32         private ExtendedThrustCurveMotor motor;\r
33 \r
34         private XYPlot mySimpleXYPlot;\r
35         private SimpleXYSeries mySeries;\r
36         private PointF minXY;\r
37         private PointF maxXY;\r
38 \r
39         private float absMinX;\r
40         private float absMaxX;\r
41 \r
42         private ScaleGestureDetector mScaleDetector;\r
43         private float mScaleFactor = 1.f;\r
44 \r
45         @Override\r
46         public void onCreate(Bundle savedInstanceState) {\r
47                 Log.d(TAG,"onCreate");\r
48                 super.onCreate(savedInstanceState);\r
49         }\r
50 \r
51         @Override\r
52         public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
53                         Bundle savedInstanceState) {\r
54                 Log.d(TAG,"onCreateView");\r
55                 View v = inflater.inflate(R.layout.motor_burn, container, false);\r
56                 mySimpleXYPlot = (XYPlot) v.findViewById(R.id.xyplot);\r
57                 mySimpleXYPlot.setOnTouchListener(this);\r
58                 mScaleDetector = new ScaleGestureDetector(v.getContext(), new ScaleListener());\r
59                 return v;\r
60         }\r
61 \r
62         private static List<Double> fromArray( double[] arry ) {\r
63                 List<Double> l = new ArrayList<Double>(arry.length);\r
64                 for( double d: arry ) {\r
65                         l.add(d);\r
66                 }\r
67                 return l;\r
68         }\r
69         void init( ExtendedThrustCurveMotor motor ) {\r
70 \r
71                 mySimpleXYPlot.setUserDomainOrigin(0);\r
72                 mySimpleXYPlot.setUserRangeOrigin(0);\r
73                 mySimpleXYPlot.setRangeLabel("impuse (n)");\r
74                 mySimpleXYPlot.setDomainLabel("time (s)");\r
75                 mySimpleXYPlot.addMarker(new YValueMarker(motor.getThrustCurveMotor().getAverageThrustEstimate(),"average" ));\r
76                 mySimpleXYPlot.disableAllMarkup();\r
77 \r
78 \r
79                 try {\r
80                         mySeries = new SimpleXYSeries( \r
81                                         fromArray(motor.getThrustCurveMotor().getTimePoints()),\r
82                                         fromArray(motor.getThrustCurveMotor().getThrustPoints()),\r
83                                         motor.getThrustCurveMotor().getDesignation());\r
84                 } catch ( Exception ex ) {\r
85 \r
86                         Vector<Double> data = new Vector<Double>();\r
87                         data.add(0.0);\r
88                         data.add(0.0);\r
89                         data.add(1.0);\r
90                         data.add(1.0);\r
91                         mySeries = new SimpleXYSeries(data, SimpleXYSeries.ArrayFormat.XY_VALS_INTERLEAVED,"no data");\r
92                 }\r
93 \r
94                 mySimpleXYPlot.addSeries(mySeries, LineAndPointRenderer.class,\r
95                                 new LineAndPointFormatter(Color.rgb(0, 255, 0), Color.rgb(200, 0, 0), null));\r
96 \r
97                 //Set of internal variables for keeping track of the boundaries\r
98                 mySimpleXYPlot.calculateMinMaxVals();\r
99 \r
100                 mySimpleXYPlot.redraw();\r
101 \r
102                 minXY=new PointF(mySimpleXYPlot.getCalculatedMinX().floatValue(),mySimpleXYPlot.getCalculatedMinY().floatValue());\r
103                 maxXY=new PointF(mySimpleXYPlot.getCalculatedMaxX().floatValue(),mySimpleXYPlot.getCalculatedMaxY().floatValue());\r
104 \r
105                 absMinX = minXY.x;\r
106                 absMaxX = maxXY.x;\r
107 \r
108         }\r
109 \r
110         private float mPosX;\r
111         private float mPosY;\r
112 \r
113         private float mLastTouchX;\r
114         private float mLastTouchY;\r
115 \r
116         private int mActivePointerId = -1;\r
117 \r
118         @Override\r
119         public boolean onTouch(View arg0, MotionEvent event) {\r
120                 mScaleDetector.onTouchEvent(event);\r
121 \r
122                 final int action = event.getAction();\r
123                 switch ( action & MotionEvent.ACTION_MASK ) {\r
124                 case MotionEvent.ACTION_DOWN: {\r
125                         final float x = event.getX();\r
126                         final float y = event.getY();\r
127 \r
128                         mLastTouchX = x;\r
129                         mLastTouchY = y;\r
130 \r
131                         mActivePointerId = event.getPointerId(0);\r
132                         break;\r
133                 }\r
134 \r
135                 case MotionEvent.ACTION_MOVE: {\r
136                         final int pointerIndex = event.findPointerIndex(mActivePointerId);\r
137                         final float x = event.getX(pointerIndex);\r
138                         final float y = event.getY(pointerIndex);\r
139 \r
140                         if (!mScaleDetector.isInProgress()) {\r
141                                 final float dx = x - mLastTouchX;\r
142                                 final float dy = y - mLastTouchY;\r
143 \r
144                                 mPosX += dx;\r
145                                 mPosY += dy;\r
146                                 scroll(dx);\r
147                                 // do scroll.\r
148 \r
149                         }\r
150                         mLastTouchX = x;\r
151                         mLastTouchY = y;\r
152 \r
153                         break;\r
154                 }\r
155 \r
156                 case MotionEvent.ACTION_UP: {\r
157                         mActivePointerId = -1;\r
158                         break;\r
159                 }\r
160 \r
161                 case MotionEvent.ACTION_CANCEL: {\r
162                         mActivePointerId = -1;\r
163                         break;\r
164                 }\r
165 \r
166                 case MotionEvent.ACTION_POINTER_UP: {\r
167                         final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;\r
168                         final int pointerId = event.getPointerId(pointerIndex);\r
169                         if (pointerId == mActivePointerId) {\r
170                                 // This was our active pointer going up.  choose a new active pointer and adjust accordingly.\r
171                                 final int newPointerIndex = pointerIndex ==0 ? 1:0;\r
172                                 mLastTouchX = event.getX(newPointerIndex);\r
173                                 mLastTouchY = event.getY(newPointerIndex);\r
174                                 mActivePointerId = event.getPointerId(newPointerIndex);\r
175                         }\r
176                         break;\r
177                 }\r
178                 }       \r
179                 return true;\r
180         }\r
181 \r
182         private void zoom(float scale) {\r
183                 Log.d(TAG,"zoom by " + scale);\r
184                 float domainSpan = absMaxX      - absMinX;\r
185                 Log.d(TAG,"domainSpan = " + domainSpan);\r
186                 float domainMidPoint = absMaxX          - domainSpan / 2.0f;\r
187                 Log.d(TAG,"domainMidPoint = " + domainMidPoint);\r
188                 float offset = domainSpan / scale;\r
189                 Log.d(TAG,"offset " + offset);\r
190                 minXY.x=domainMidPoint- offset;\r
191                 Log.d(TAG,"min X " + minXY.x);\r
192                 maxXY.x=domainMidPoint+offset;\r
193                 Log.d(TAG,"max X " + maxXY.x);\r
194                 checkBoundaries();\r
195                 mySimpleXYPlot.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO);\r
196                 mySimpleXYPlot.redraw();\r
197         }\r
198 \r
199         private void scroll(float pan) {\r
200                 float domainSpan = maxXY.x      - minXY.x;\r
201                 float step = domainSpan / mySimpleXYPlot.getWidth();\r
202                 float offset = pan * step;\r
203                 minXY.x+= offset;\r
204                 maxXY.x+= offset;\r
205                 checkBoundaries();\r
206                 mySimpleXYPlot.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO);\r
207                 mySimpleXYPlot.redraw();\r
208         }\r
209 \r
210         private void checkBoundaries() {\r
211 \r
212                 if ( minXY.x < absMinX) \r
213                         minXY.x = absMinX;\r
214                 //              else if ( minXY.x > maxNoError )\r
215                 //                      minXY.x = maxNoError;\r
216 \r
217                 if ( maxXY.x > absMaxX)\r
218                         maxXY.x = absMaxX;\r
219                 //              else if ( maxXY.x < minNoError)\r
220                 //                      maxXY.x = minNoError;\r
221         }\r
222         private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {\r
223                 @Override\r
224                 public boolean onScale( ScaleGestureDetector detector ) {\r
225                         mScaleFactor *= detector.getScaleFactor();\r
226 \r
227                         mScaleFactor = Math.max(1.0f, Math.min(mScaleFactor, 5.0f));\r
228                         zoom(mScaleFactor);\r
229                         return true;\r
230                 }\r
231         }\r
232 }\r
233 \r