• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.graphicslab;
18 
19 import java.util.Map;
20 
21 import android.app.Activity;
22 import android.content.Context;
23 import android.graphics.*;
24 import android.graphics.utils.*;
25 import android.os.Bundle;
26 import android.os.SystemClock;
27 import android.view.*;
28 
29 public class GraphicsLab extends Activity {
GraphicsLab()30     public GraphicsLab() {}
31 
32     private int mCurrView = 1;
33 
onCreate(Bundle icicle)34     public void onCreate(Bundle icicle) {
35         super.onCreate(icicle);
36         setContentView(new SampleView(this));
37 //        setTitle("Graphics Lab");
38     }
39 
40     @Override
onKeyDown(int keyCode, KeyEvent event)41     public boolean onKeyDown(int keyCode, KeyEvent event) {
42         switch(keyCode) {
43             case KeyEvent.KEYCODE_DPAD_CENTER:
44                 if (mCurrView == 1) {
45                     setContentView(new SampleView2(this));
46                     mCurrView = 2;
47                 } else {
48                     setContentView(new SampleView(this));
49                     mCurrView = 1;
50                 }
51         }
52         return super.onKeyDown(keyCode, event);
53     }
54 
55     private static class SampleView2 extends View {
56         private static final int ROWS = 16;
57         private static final int COLS = 16;
58         private static final int UNSTRETCH_MSEC = 250;
59 
60         private Interpolator mInterp;
61         private BoundaryPatch mPatch;
62         private float[] mCubics;
63         private float[] mOrig = new float[24];
64         private Paint mPaint0;
65         private Paint mPaint1;
66         private int mCurrIndex = -1;
67         private float mPrevX;
68         private float mPrevY;
69 
SampleView2(Context context)70         public SampleView2(Context context) {
71             super(context);
72             setFocusable(true);
73 
74             Bitmap bm = BitmapFactory.decodeResource(getResources(),
75                                                      R.drawable.news_img);
76 
77             mPatch = new BoundaryPatch();
78             mPatch.setTexture(bm);
79 
80             float unit = 90;
81             mCubics = new float[] {
82                 0, 0, 1, 0, 2, 0,
83                 3, 0, 3, 1, 3, 2,
84                 3, 3, 2, 3, 1, 3,
85                 0, 3, 0, 2, 0, 1
86             };
87             for (int i = 0; i < 24; i++) {
88                 mCubics[i] *= 90;
89                 mCubics[i] += 20;
90             }
91             rebuildPatch();
92 
93             mPaint0 = new Paint();
94             mPaint0.setAntiAlias(true);
95             mPaint0.setStrokeWidth(12);
96             mPaint0.setStrokeCap(Paint.Cap.ROUND);
97             mPaint1 = new Paint(mPaint0);
98             mPaint1.setColor(0xFFFFFFFF);
99             mPaint1.setStrokeWidth(10);
100         }
101 
102         @Override
onSizeChanged(int nw, int nh, int ow, int oh)103         protected void onSizeChanged(int nw, int nh, int ow, int oh) {
104             float[] pts = mCubics;
105             float x1 = nw*0.3333f;
106             float y1 = nh*0.3333f;
107             float x2 = nw*0.6667f;
108             float y2 = nh*0.6667f;
109             pts[0*2+0] = 0;  pts[0*2+1] = 0;
110             pts[1*2+0] = x1; pts[1*2+1] = 0;
111             pts[2*2+0] = x2; pts[2*2+1] = 0;
112 
113             pts[3*2+0] = nw; pts[3*2+1] = 0;
114             pts[4*2+0] = nw; pts[4*2+1] = y1;
115             pts[5*2+0] = nw; pts[5*2+1] = y2;
116 
117             pts[6*2+0] = nw; pts[6*2+1] = nh;
118             pts[7*2+0] = x2; pts[7*2+1] = nh;
119             pts[8*2+0] = x1; pts[8*2+1] = nh;
120 
121             pts[9*2+0] = 0;  pts[9*2+1] = nh;
122             pts[10*2+0] = 0; pts[10*2+1] = y2;
123             pts[11*2+0] = 0; pts[11*2+1] = y1;
124 
125             System.arraycopy(pts, 0, mOrig, 0, 24);
126             rebuildPatch();
127         }
128 
onDraw(Canvas canvas)129         @Override protected void onDraw(Canvas canvas) {
130             if (mInterp != null) {
131                 int now = (int)SystemClock.uptimeMillis();
132                 Interpolator.Result result = mInterp.timeToValues(now, mCubics);
133                 if (result != Interpolator.Result.NORMAL) {
134                     mInterp = null;
135                 } else {
136                     invalidate();
137                 }
138                 rebuildPatch();
139             }
140             mPatch.draw(canvas);
141         }
142 
rebuildPatch()143         private void rebuildPatch() {
144             mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
145         }
146 
onTouchEvent(MotionEvent event)147         @Override public boolean onTouchEvent(MotionEvent event) {
148             float x = event.getX();
149             float y = event.getY();
150             switch (event.getAction()) {
151                 case MotionEvent.ACTION_DOWN:
152                     System.arraycopy(mOrig, 0, mCubics, 0, 24);
153                     mPrevX = x;
154                     mPrevY = y;
155                     break;
156                 case MotionEvent.ACTION_MOVE: {
157                     float scale = 1.5f;
158                     float dx = (x - mPrevX) * scale;
159                     float dy = (y - mPrevY) * scale;
160                     int index;
161 
162                     if (dx < 0) {
163                         index = 10;
164                     } else {
165                         index = 4;
166                     }
167                     mCubics[index*2 + 0] = mOrig[index*2 + 0] + dx;
168                     mCubics[index*2 + 2] = mOrig[index*2 + 2] + dx;
169 
170                     if (dy < 0) {
171                         index = 1;
172                     } else {
173                         index = 7;
174                     }
175                     mCubics[index*2 + 1] = mOrig[index*2 + 1] + dy;
176                     mCubics[index*2 + 3] = mOrig[index*2 + 3] + dy;
177 
178                     rebuildPatch();
179                     invalidate();
180                 } break;
181                 case MotionEvent.ACTION_UP:
182                 case MotionEvent.ACTION_CANCEL: {
183                     int start = (int)SystemClock.uptimeMillis();
184                     mInterp = new Interpolator(24);
185                     mInterp.setKeyFrame(0, start, mCubics,
186                                         new float[] { 0, 0.5f, 0.5f, 1 });
187                     mInterp.setKeyFrame(1, start + UNSTRETCH_MSEC, mOrig
188                                         );
189                     invalidate();
190                 } break;
191             }
192             return true;
193         }
194     }
195 
196     private static class SampleView extends View {
197         private static final int ROWS = 16;
198         private static final int COLS = 16;
199 
200         private BoundaryPatch mPatch;
201         private float[] mCubics;
202         private float[] mOrig = new float[24];
203         private Paint mPaint0;
204         private Paint mPaint1;
205         private int mCurrIndex = -1;
206         private float mPrevX;
207         private float mPrevY;
208 
SampleView(Context context)209         public SampleView(Context context) {
210         super(context);
211         setFocusable(true);
212 
213         Bitmap bm = BitmapFactory.decodeResource(getResources(),
214                                                  R.drawable.beach);
215 
216         mPatch = new BoundaryPatch();
217         mPatch.setTexture(bm);
218 
219         float unit = 90;
220         mCubics = new float[] {
221             0, 0, 1, 0, 2, 0,
222             3, 0, 3, 1, 3, 2,
223             3, 3, 2, 3, 1, 3,
224             0, 3, 0, 2, 0, 1
225         };
226         for (int i = 0; i < 24; i++) {
227             mCubics[i] *= 90;
228             mCubics[i] += 20;
229         }
230         rebuildPatch();
231 
232         mPaint0 = new Paint();
233         mPaint0.setAntiAlias(true);
234         mPaint0.setStrokeWidth(12);
235         mPaint0.setStrokeCap(Paint.Cap.ROUND);
236         mPaint1 = new Paint(mPaint0);
237         mPaint1.setColor(0xFFFFFFFF);
238         mPaint1.setStrokeWidth(10);
239     }
240 
onDraw(Canvas canvas)241     @Override protected void onDraw(Canvas canvas) {
242         canvas.drawColor(0xFFCCCCCC);
243         mPatch.draw(canvas);
244         canvas.drawPoints(mCubics, mPaint0);
245         canvas.drawPoints(mCubics, mPaint1);
246     }
247 
rebuildPatch()248     private void rebuildPatch() {
249         mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
250     }
251 
findPtIndex(float x, float y)252     private int findPtIndex(float x, float y) {
253         final float tolerance = 25;
254         final float[] pts = mCubics;
255         for (int i = 0; i < (pts.length >> 1); i++) {
256             if (Math.abs(pts[i*2 + 0] - x) <= tolerance &&
257                 Math.abs(pts[i*2 + 1] - y) <= tolerance) {
258                 return i*2;
259             }
260         }
261         return -1;
262     }
263 
offsetPts(float dx, float dy)264     private void offsetPts(float dx, float dy) {
265         final float[] pts = mCubics;
266         for (int i = 0; i < (pts.length >> 1); i++) {
267             pts[i*2 + 0] += dx;
268             pts[i*2 + 1] += dy;
269         }
270         rebuildPatch();
271     }
272 
onTouchEvent(MotionEvent event)273     @Override public boolean onTouchEvent(MotionEvent event) {
274         float x = event.getX();
275         float y = event.getY();
276         switch (event.getAction()) {
277             case MotionEvent.ACTION_DOWN:
278                 mCurrIndex = findPtIndex(x, y);
279                 mPrevX = x;
280                 mPrevY = y;
281                 break;
282             case MotionEvent.ACTION_MOVE:
283                 if (mCurrIndex >= 0) {
284                     mCubics[mCurrIndex + 0] = x;
285                     mCubics[mCurrIndex + 1] = y;
286                     mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
287                 } else {
288                     offsetPts(x - mPrevX, y - mPrevY);
289                     mPrevX = x;
290                     mPrevY = y;
291                 }
292                 invalidate();
293                 break;
294         }
295         return true;
296     }
297 }
298 }
299 
300