Project

General

Profile

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

examples / src / main / java / org / distorted / examples / earth / EarthSurfaceViewPicker.java @ 1585ba24

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
      float longitude = (float)((xf-0.5f)*2.0f*Math.PI);
199
      float latitude  = (float)((yf-0.5f)*Math.PI);
200

    
201
      mAct.get().addNewPoint(longitude,latitude,mCurrentEffect);
202
      }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

    
206
    void save(Bundle bundle)
207
      {
208
      bundle.putIntegerArrayList("x", mPointsX);
209
      bundle.putIntegerArrayList("y", mPointsY);
210
      bundle.putIntegerArrayList("e", mPointsE);
211
      }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

    
215
    void restore(Bundle bundle)
216
      {
217
      mPointsX = bundle.getIntegerArrayList("x");
218
      mPointsY = bundle.getIntegerArrayList("y");
219
      mPointsE = bundle.getIntegerArrayList("e");
220
      }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
    void clearPoints()
225
      {
226
      mPointsX.clear();
227
      mPointsY.clear();
228
      mPointsE.clear();
229

    
230
      refreshScreen = true;
231
      }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

    
235
    private void render(Canvas c)
236
      {
237
      if( c!=null )
238
        {
239
        c.drawBitmap(mBitmap, null, mDst, null);
240

    
241
        int x,y,size = mPointsX.size();
242

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

    
248
          c.drawCircle( x, y, mRadius, mPointPaint);
249
          }
250
        }
251
      }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

    
255
    void onPause()
256
      {
257
      if( mThread!=null ) mThread.setRunning(false);
258
      }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
    void onResume()
263
      {
264
      if( mThread!=null ) mThread.setRunning(true);
265
      }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
    @Override
270
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
271
      {
272
      mWidth = width;
273
      mHeight= height;
274

    
275
      mDst.bottom = height;
276
      mDst.right  = width;
277
      mDst.left   = 0;
278
      mDst.top    = 0;
279

    
280
      mRadius = (width+height)/60;
281

    
282
      refreshScreen = true;
283
      }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

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

    
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296

    
297
    @Override
298
    public void surfaceDestroyed(SurfaceHolder holder)
299
      {
300
      stopThread();
301
      }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

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

    
(4-4/4)