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