Project

General

Profile

Download (10.2 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / dynamic / DynamicSpeedSurfaceView.java @ 87006e8d

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.examples.dynamic;
21

    
22
import android.content.Context;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25
import android.graphics.Rect;
26
import android.util.AttributeSet;
27
import android.view.SurfaceHolder;
28
import android.view.SurfaceView;
29

    
30
import org.distorted.library.type.Dynamic;
31

    
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

    
34
class DynamicSpeedSurfaceView extends SurfaceView implements SurfaceHolder.Callback
35
{
36
    private static final int FRAME_INTERVAL = 70;
37
    private static final int NUM_POINTS     = 400;
38

    
39
    private static boolean refreshScreen = true;
40
    private GraphicsThread mThread;
41
    private int mWidth, mHeight, mMargin;
42
    private int mMode, mNumRedPoints, mPointSize;
43
    private float mFontHeight;
44
    private Paint mPaint;
45
    private float[] mPoints = new float[NUM_POINTS];
46
    private float mMultiplier;
47

    
48
/////////////////////////////////////////////////////////////////////////////////////////
49

    
50
    private class GraphicsThread extends Thread
51
      {
52
      private final SurfaceHolder mSurfaceHolder;
53
      private final DynamicSpeedSurfaceView mPicker;
54
      private boolean mRun = false;
55

    
56
      ///////////////////////////////////////////////////////////////////////////////////////
57

    
58
      GraphicsThread(SurfaceHolder surfaceHolder, DynamicSpeedSurfaceView p)
59
        {
60
        mSurfaceHolder = surfaceHolder;
61
        mPicker = p;
62
        }
63

    
64
      ///////////////////////////////////////////////////////////////////////////////////////
65

    
66
      void setRunning(boolean run)
67
        {
68
        mRun = run;
69
        }
70

    
71
      ///////////////////////////////////////////////////////////////////////////////////////
72

    
73
      public void run()
74
        {
75
        Canvas c;
76
        long time;
77

    
78
        while (mRun)
79
          {
80
          c = null;
81
          time = 0;
82

    
83
          if( refreshScreen )
84
            {
85
            refreshScreen=false;
86
            time = System.currentTimeMillis();
87

    
88
            try
89
              {
90
              c = mSurfaceHolder.lockCanvas(null);
91
              synchronized (mSurfaceHolder) { mPicker.render(c); }
92
              }
93
            finally
94
              {
95
              if (c != null)  mSurfaceHolder.unlockCanvasAndPost(c);
96
              }
97

    
98
            time = System.currentTimeMillis() -time;
99
            }
100

    
101
          if( time<FRAME_INTERVAL )
102
            {
103
            try { Thread.sleep(FRAME_INTERVAL-time); }
104
            catch(InterruptedException ex) {}
105
            }
106
          }
107
        }
108
      }
109

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

    
112
    public DynamicSpeedSurfaceView(Context context, AttributeSet attrs)
113
      {
114
      super(context,attrs);
115

    
116
      mNumRedPoints = 0;
117

    
118
      mPaint = new Paint();
119
      mPaint.setAntiAlias(true);
120
      mPaint.setFakeBoldText(true);
121
      mPaint.setStyle(Paint.Style.FILL);
122

    
123
      clearPoints();
124

    
125
      getHolder().addCallback(this);
126
      }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
    private void stopThread()
131
      {
132
      if( mThread!=null )
133
        {
134
        boolean retry = true;
135
        mThread.setRunning(false);
136

    
137
        while (retry)
138
          {
139
          try
140
            {
141
            mThread.join();
142
            retry = false;
143
            }
144
          catch (InterruptedException e) { android.util.Log.e( "DynamicSpeed", "Joining thread interrupted!"); }
145
          }
146

    
147
        mThread=null;
148
        }
149
      }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
    private void render(Canvas c)
154
      {
155
      if( c!=null )
156
        {
157
        mPaint.setColor(0xff007d00);
158
        c.drawRect(0, 0, mWidth, mHeight, mPaint);
159
        drawAxis(c);
160
        drawSpeedGraph(c);
161
        drawRedPoints(c);
162
        mPaint.setColor(0xff000000);
163
        c.drawText( "Speed", mWidth*0.5f, mMargin, mPaint);
164
        }
165
      }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
    private void drawAxis(Canvas c)
170
      {
171
      mPaint.setColor(0xff000000);
172

    
173
      c.drawLine( mMargin, mHeight-mMargin, mWidth-mMargin, mHeight-mMargin, mPaint);
174
      c.drawLine( mMargin, mHeight-mMargin,        mMargin,         mMargin, mPaint);
175
      }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
    private void drawRedPoints(Canvas c)
180
      {
181
      if( mNumRedPoints==1 )
182
        {
183
        drawRedPoint(c,"0", mMargin, mHeight-mMargin);
184
        }
185
      else if( mNumRedPoints>1 )
186
        {
187
        int len = mMode== Dynamic.MODE_LOOP ? mNumRedPoints+1 : mNumRedPoints;
188
        String label;
189
        float x;
190

    
191
        for(int curr=0; curr<len; curr++)
192
          {
193
          label = curr==mNumRedPoints ? "0" : curr+"";
194
          x = mMargin + curr*((float)(mWidth-2*mMargin))/(len-1);
195
          drawRedPoint(c,label, x, mHeight-mMargin);
196
          }
197
        }
198
      }
199

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

    
202
    private void drawRedPoint(Canvas c, String label, float width, float height)
203
      {
204
      mPaint.setColor(0xffff0000);
205
      c.drawCircle( width, height, mPointSize, mPaint);
206
      mPaint.setColor(0xffffffff);
207
      c.drawText(label, width,height-mFontHeight, mPaint);
208
      }
209

    
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

    
212
    private void drawSpeedGraph(Canvas c)
213
      {
214
      mPaint.setColor(0xffffffff);
215
      float x,y, highiest=0.0f;
216

    
217
      for(int i=0; i<NUM_POINTS; i++)
218
        {
219
        x = ((float)(i*(mWidth-2*mMargin)))/NUM_POINTS;
220
        y = mPoints[i];
221
        c.drawCircle( mMargin+x, mHeight-mMargin-mMultiplier*y , mPointSize*0.3f, mPaint );
222

    
223
        if( y>highiest ) highiest = y;
224
        }
225

    
226
      mMultiplier = (mHeight-3*mMargin)/highiest;
227
      }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
    void setMode(int mode)
232
      {
233
      mMode = mode;
234
      refreshScreen = true;
235
      }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
    void clearPoints()
240
      {
241
      for(int i=0; i<NUM_POINTS; i++)
242
         {
243
         mPoints[i] = -100.0f;
244
         }
245
      refreshScreen = true;
246
      }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
    void addPoint(float x, float y)
251
      {
252
      if( x>=0.0f && x<=1.0f )
253
        {
254
        if( mMode==Dynamic.MODE_PATH ) x = x>0.5f ? 2-2*x : 2*x;
255
        int pos = (int)((NUM_POINTS-1)*x);
256
        mPoints[pos] =y;
257
        refreshScreen = true;
258
        }
259
      else
260
        {
261
        android.util.Log.e("speed", "ERROR adding new Speed Point, x="+x);
262
        }
263
      }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
    void setNumRedPoints(int numRedPoints)
268
      {
269
      mNumRedPoints = numRedPoints;
270
      refreshScreen = true;
271
      }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
    void onPause()
276
      {
277
      if( mThread!=null ) mThread.setRunning(false);
278
      }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
    void onResume()
283
      {
284
      if( mThread!=null ) mThread.setRunning(true);
285
      }
286

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

    
289
    @Override
290
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
291
      {
292
      mWidth = width;
293
      mHeight= height;
294
      mMargin= height/10;
295

    
296
      mPointSize = (mWidth+mHeight)/80;
297
      mPaint.setTextSize((mWidth+mHeight)/60);
298
      mPaint.setTextAlign(Paint.Align.CENTER);
299

    
300
      final Rect textBounds = new Rect();
301
      String text = "1";
302
      mPaint.getTextBounds(text, 0, text.length(), textBounds);
303
      mFontHeight = textBounds.exactCenterY();
304

    
305
      refreshScreen = true;
306
      }
307

    
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309

    
310
    @Override
311
    public void surfaceCreated(SurfaceHolder holder)
312
      {
313
      mThread = new GraphicsThread(getHolder(), this);
314
      mThread.setRunning(true);
315
      mThread.start();
316
      }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
    @Override
321
    public void surfaceDestroyed(SurfaceHolder holder)
322
      {
323
      stopThread();
324
      }
325
}
326

    
(3-3/4)