Project

General

Profile

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

examples / src / main / java / org / distorted / examples / dynamic / DynamicSpeedSurfaceView.java @ e52efe17

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     = DynamicSurfaceView.NUM_POINTS;
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[2*NUM_POINTS];
46
    private int mPosition;
47
    private float mMultiplier;
48

    
49
/////////////////////////////////////////////////////////////////////////////////////////
50

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

    
57
      ///////////////////////////////////////////////////////////////////////////////////////
58

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

    
65
      ///////////////////////////////////////////////////////////////////////////////////////
66

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

    
72
      ///////////////////////////////////////////////////////////////////////////////////////
73

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

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

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

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

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

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

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

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

    
117
      mNumRedPoints = 0;
118
      mPosition     = 0;
119

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

    
125
      clearPoints();
126

    
127
      getHolder().addCallback(this);
128
      }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

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

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

    
149
        mThread=null;
150
        }
151
      }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

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

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

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

    
175
      c.drawLine( mMargin, mHeight-mMargin, mWidth-mMargin, mHeight-mMargin, mPaint);
176
      c.drawLine( mMargin, mHeight-mMargin,        mMargin,         mMargin, mPaint);
177
      }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

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

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

    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203

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

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

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

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

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

    
227
      mMultiplier = (mHeight-2*mMargin)/highiest;
228
      }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

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

    
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239

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

    
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250

    
251
    void addPoint(float x, float y)
252
      {
253
      mPoints[2*mPosition  ] =x;
254
      mPoints[2*mPosition+1] =y;
255

    
256
      if ( ++mPosition >= NUM_POINTS ) mPosition=0;
257

    
258
      refreshScreen = true;
259
      }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
    void setNumRedPoints(int numRedPoints)
264
      {
265
      mNumRedPoints = numRedPoints;
266
      refreshScreen = true;
267
      }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
    void onPause()
272
      {
273
      if( mThread!=null ) mThread.setRunning(false);
274
      }
275

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
    void onResume()
279
      {
280
      if( mThread!=null ) mThread.setRunning(true);
281
      }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
    @Override
286
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
287
      {
288
      mWidth = width;
289
      mHeight= height;
290
      mMargin= height/10;
291

    
292
      mPointSize = (mWidth+mHeight)/80;
293
      mPaint.setTextSize((mWidth+mHeight)/60);
294
      mPaint.setTextAlign(Paint.Align.CENTER);
295

    
296
      final Rect textBounds = new Rect();
297
      String text = "1";
298
      mPaint.getTextBounds(text, 0, text.length(), textBounds);
299
      mFontHeight = textBounds.exactCenterY();
300

    
301
      refreshScreen = true;
302
      }
303

    
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305

    
306
    @Override
307
    public void surfaceCreated(SurfaceHolder holder)
308
      {
309
      mThread = new GraphicsThread(getHolder(), this);
310
      mThread.setRunning(true);
311
      mThread.start();
312
      }
313

    
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315

    
316
    @Override
317
    public void surfaceDestroyed(SurfaceHolder holder)
318
      {
319
      stopThread();
320
      }
321
}
322

    
(3-3/4)