Project

General

Profile

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

examples / src / main / java / org / distorted / examples / earth / EarthSurfaceViewPicker.java @ 296d2e73

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.earth;
21

    
22
import android.content.Context;
23
import android.graphics.Bitmap;
24
import android.graphics.BitmapFactory;
25
import android.graphics.Canvas;
26
import android.graphics.Paint;
27
import android.graphics.Rect;
28
import android.os.Bundle;
29
import android.util.AttributeSet;
30
import android.view.MotionEvent;
31
import android.view.SurfaceHolder;
32
import android.view.SurfaceView;
33

    
34
import org.distorted.examples.R;
35
import org.distorted.library.effect.EffectName;
36

    
37
import java.io.IOException;
38
import java.io.InputStream;
39
import java.lang.ref.WeakReference;
40
import java.util.ArrayList;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
class EarthSurfaceViewPicker extends SurfaceView implements SurfaceHolder.Callback
45
{
46
    private static final int FRAME_INTERVAL = 70;
47
    private static final int MULTIPLIER   = 1000;
48

    
49
    private static boolean refreshScreen = true;
50
    private GraphicsThread mThread;
51
    private EffectName mCurrentEffect;
52
    private ArrayList<Integer> mPointsX, mPointsY, mPointsE;
53
    private WeakReference<EarthActivity> mAct;
54
    private int mRadius;
55
    private Bitmap mBitmap;
56
    private Paint mPointPaint;
57
    private Rect mDst;
58
    private int mWidth, mHeight;
59

    
60
/////////////////////////////////////////////////////////////////////////////////////////
61

    
62
    private class GraphicsThread extends Thread
63
      {
64
      private final SurfaceHolder mSurfaceHolder;
65
      private final EarthSurfaceViewPicker mPicker;
66
      private boolean mRun = false;
67

    
68
      ///////////////////////////////////////////////////////////////////////////////////////
69

    
70
      GraphicsThread(SurfaceHolder surfaceHolder, EarthSurfaceViewPicker p)
71
        {
72
        mSurfaceHolder = surfaceHolder;
73
        mPicker = p;
74
        }
75

    
76
      ///////////////////////////////////////////////////////////////////////////////////////
77

    
78
      void setRunning(boolean run)
79
        {
80
        mRun = run;
81
        }
82

    
83
      ///////////////////////////////////////////////////////////////////////////////////////
84

    
85
      public void run()
86
        {
87
        Canvas c;
88
        long time;
89

    
90
        while (mRun)
91
          {
92
          c = null;
93
          time = 0;
94

    
95
          if( refreshScreen )
96
            {
97
            refreshScreen=false;
98
            time = System.currentTimeMillis();
99

    
100
            try
101
              {
102
              c = mSurfaceHolder.lockCanvas(null);
103
              synchronized (mSurfaceHolder) { mPicker.render(c); }
104
              }
105
            finally
106
              {
107
              if (c != null)  mSurfaceHolder.unlockCanvasAndPost(c);
108
              }
109

    
110
            time = System.currentTimeMillis() -time;
111
            }
112

    
113
          if( time<FRAME_INTERVAL )
114
            {
115
            try { Thread.sleep(FRAME_INTERVAL-time); }
116
            catch(InterruptedException ex) {}
117
            }
118
          }
119
        }
120
      }
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
    public EarthSurfaceViewPicker(Context context, AttributeSet attrs)
125
      {
126
      super(context,attrs);
127

    
128
      InputStream is = context.getResources().openRawResource(R.raw.world);
129

    
130
      try
131
        {
132
        mBitmap = BitmapFactory.decodeStream(is);
133
        }
134
      finally
135
        {
136
        try
137
          {
138
          is.close();
139
          }
140
        catch(IOException e) { }
141
        }
142

    
143
      EarthActivity act = (EarthActivity)context;
144
      mAct = new WeakReference<>(act);
145

    
146
      mDst = new Rect();
147
      mPointsX = new ArrayList<>();
148
      mPointsY = new ArrayList<>();
149
      mPointsE = new ArrayList<>();
150

    
151
      mPointPaint = new Paint();
152
      mPointPaint.setARGB(255,0,0,0);
153

    
154
      getHolder().addCallback(this);
155
      }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
    private void stopThread()
160
      {
161
      if( mThread!=null )
162
        {
163
        boolean retry = true;
164
        mThread.setRunning(false);
165

    
166
        while (retry)
167
          {
168
          try
169
            {
170
            mThread.join();
171
            retry = false;
172
            }
173
          catch (InterruptedException e) { android.util.Log.e( "EarthPicker", "Joining thread interrupted!"); }
174
          }
175

    
176
        mThread=null;
177
        }
178
      }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
    void setEffectMode(EffectName effect)
183
      {
184
      mCurrentEffect = effect;
185
      }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
    private void addNewPoint(int x, int y)
190
      {
191
      float xf = (float)x/mWidth;
192
      float yf = (float)y/mHeight;
193

    
194
      mPointsX.add( (int)(MULTIPLIER*xf) );
195
      mPointsY.add( (int)(MULTIPLIER*yf) );
196
      mPointsE.add(mCurrentEffect.ordinal());
197

    
198
      mAct.get().addNewPoint(xf,yf,mCurrentEffect);
199
      }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
    void save(Bundle bundle)
204
      {
205
      bundle.putIntegerArrayList("x", mPointsX);
206
      bundle.putIntegerArrayList("y", mPointsY);
207
      bundle.putIntegerArrayList("e", mPointsE);
208
      }
209

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

    
212
    void restore(Bundle bundle)
213
      {
214
      mPointsX = bundle.getIntegerArrayList("x");
215
      mPointsY = bundle.getIntegerArrayList("y");
216
      mPointsE = bundle.getIntegerArrayList("e");
217
      }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
    void clearPoints()
222
      {
223
      mPointsX.clear();
224
      mPointsY.clear();
225
      mPointsE.clear();
226

    
227
      refreshScreen = true;
228
      }
229

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

    
232
    private void render(Canvas c)
233
      {
234
      if( c!=null )
235
        {
236
        c.drawBitmap(mBitmap, null, mDst, null);
237

    
238
        int x,y,size = mPointsX.size();
239

    
240
        for(int point=0; point<size; point++)
241
          {
242
          x = (int)(((float)mPointsX.get(point)/MULTIPLIER)*mWidth );
243
          y = (int)(((float)mPointsY.get(point)/MULTIPLIER)*mHeight);
244

    
245
          c.drawCircle( x, y, mRadius, mPointPaint);
246
          }
247
        }
248
      }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
    void onPause()
253
      {
254
      if( mThread!=null ) mThread.setRunning(false);
255
      }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
    void onResume()
260
      {
261
      if( mThread!=null ) mThread.setRunning(true);
262
      }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
    @Override
267
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
268
      {
269
      mWidth = width;
270
      mHeight= height;
271

    
272
      mDst.bottom = height;
273
      mDst.right  = width;
274
      mDst.left   = 0;
275
      mDst.top    = 0;
276

    
277
      mRadius = (width+height)/60;
278

    
279
      refreshScreen = true;
280
      }
281

    
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283

    
284
    @Override
285
    public void surfaceCreated(SurfaceHolder holder)
286
      {
287
      mThread = new GraphicsThread(getHolder(), this);
288
      mThread.setRunning(true);
289
      mThread.start();
290
      }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
    @Override
295
    public void surfaceDestroyed(SurfaceHolder holder)
296
      {
297
      stopThread();
298
      }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
    @Override
303
    public boolean onTouchEvent(MotionEvent event)
304
      {
305
      int action = event.getAction();
306
      int x = (int)event.getX();
307
      int y = (int)event.getY();
308
           
309
      switch(action)
310
         {
311
         case MotionEvent.ACTION_DOWN: addNewPoint(x,y);
312
                                       refreshScreen = true;
313
                                       break;
314
         }
315
             
316
      return true;
317
      }
318
}
319

    
(4-4/4)