diff --git a/apps/GraphicsLab/res/drawable/news_img.jpg b/apps/GraphicsLab/res/drawable/news_img.jpg new file mode 100644 index 000000000..16a5ecb94 Binary files /dev/null and b/apps/GraphicsLab/res/drawable/news_img.jpg differ diff --git a/apps/GraphicsLab/src/com/android/graphicslab/GraphicsLab.java b/apps/GraphicsLab/src/com/android/graphicslab/GraphicsLab.java index f1f2f42af..dd5ac5bc4 100644 --- a/apps/GraphicsLab/src/com/android/graphicslab/GraphicsLab.java +++ b/apps/GraphicsLab/src/com/android/graphicslab/GraphicsLab.java @@ -23,35 +23,56 @@ import android.content.Context; import android.graphics.*; import android.graphics.utils.*; import android.os.Bundle; +import android.os.SystemClock; import android.view.*; public class GraphicsLab extends Activity { public GraphicsLab() {} + private int mCurrView = 1; + public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(new SampleView(this)); // setTitle("Graphics Lab"); } - - private static class SampleView extends View { + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + switch(keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + if (mCurrView == 1) { + setContentView(new SampleView2(this)); + mCurrView = 2; + } else { + setContentView(new SampleView(this)); + mCurrView = 1; + } + } + return super.onKeyDown(keyCode, event); + } + + private static class SampleView2 extends View { private static final int ROWS = 16; private static final int COLS = 16; + private static final int UNSTRETCH_MSEC = 250; + private Interpolator mInterp; private BoundaryPatch mPatch; private float[] mCubics; + private float[] mOrig = new float[24]; private Paint mPaint0; private Paint mPaint1; private int mCurrIndex = -1; private float mPrevX; private float mPrevY; - public SampleView(Context context) { + public SampleView2(Context context) { super(context); setFocusable(true); Bitmap bm = BitmapFactory.decodeResource(getResources(), - R.drawable.beach); + R.drawable.news_img); mPatch = new BoundaryPatch(); mPatch.setTexture(bm); @@ -78,62 +99,201 @@ public class GraphicsLab extends Activity { mPaint1.setStrokeWidth(10); } + @Override + protected void onSizeChanged(int nw, int nh, int ow, int oh) { + float[] pts = mCubics; + float x1 = nw*0.3333f; + float y1 = nh*0.3333f; + float x2 = nw*0.6667f; + float y2 = nh*0.6667f; + pts[0*2+0] = 0; pts[0*2+1] = 0; + pts[1*2+0] = x1; pts[1*2+1] = 0; + pts[2*2+0] = x2; pts[2*2+1] = 0; + + pts[3*2+0] = nw; pts[3*2+1] = 0; + pts[4*2+0] = nw; pts[4*2+1] = y1; + pts[5*2+0] = nw; pts[5*2+1] = y2; + + pts[6*2+0] = nw; pts[6*2+1] = nh; + pts[7*2+0] = x2; pts[7*2+1] = nh; + pts[8*2+0] = x1; pts[8*2+1] = nh; + + pts[9*2+0] = 0; pts[9*2+1] = nh; + pts[10*2+0] = 0; pts[10*2+1] = y2; + pts[11*2+0] = 0; pts[11*2+1] = y1; + + System.arraycopy(pts, 0, mOrig, 0, 24); + rebuildPatch(); + } + @Override protected void onDraw(Canvas canvas) { - canvas.drawColor(0xFFCCCCCC); + if (mInterp != null) { + int now = (int)SystemClock.uptimeMillis(); + Interpolator.Result result = mInterp.timeToValues(now, mCubics); + if (result != Interpolator.Result.NORMAL) { + mInterp = null; + } else { + invalidate(); + } + rebuildPatch(); + } mPatch.draw(canvas); - canvas.drawPoints(mCubics, mPaint0); - canvas.drawPoints(mCubics, mPaint1); } private void rebuildPatch() { mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS); } - private int findPtIndex(float x, float y) { - final float tolerance = 25; - final float[] pts = mCubics; - for (int i = 0; i < (pts.length >> 1); i++) { - if (Math.abs(pts[i*2 + 0] - x) <= tolerance && - Math.abs(pts[i*2 + 1] - y) <= tolerance) { - return i*2; - } - } - return -1; - } - - private void offsetPts(float dx, float dy) { - final float[] pts = mCubics; - for (int i = 0; i < (pts.length >> 1); i++) { - pts[i*2 + 0] += dx; - pts[i*2 + 1] += dy; - } - rebuildPatch(); - } - @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: - mCurrIndex = findPtIndex(x, y); + System.arraycopy(mOrig, 0, mCubics, 0, 24); mPrevX = x; mPrevY = y; break; - case MotionEvent.ACTION_MOVE: - if (mCurrIndex >= 0) { - mCubics[mCurrIndex + 0] = x; - mCubics[mCurrIndex + 1] = y; - mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS); + case MotionEvent.ACTION_MOVE: { + float scale = 1.5f; + float dx = (x - mPrevX) * scale; + float dy = (y - mPrevY) * scale; + int index; + + if (dx < 0) { + index = 10; } else { - offsetPts(x - mPrevX, y - mPrevY); - mPrevX = x; - mPrevY = y; + index = 4; } + mCubics[index*2 + 0] = mOrig[index*2 + 0] + dx; + mCubics[index*2 + 2] = mOrig[index*2 + 2] + dx; + + if (dy < 0) { + index = 1; + } else { + index = 7; + } + mCubics[index*2 + 1] = mOrig[index*2 + 1] + dy; + mCubics[index*2 + 3] = mOrig[index*2 + 3] + dy; + + rebuildPatch(); invalidate(); - break; + } break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: { + int start = (int)SystemClock.uptimeMillis(); + mInterp = new Interpolator(24); + mInterp.setKeyFrame(0, start, mCubics, + new float[] { 0, 0.5f, 0.5f, 1 }); + mInterp.setKeyFrame(1, start + UNSTRETCH_MSEC, mOrig + ); + invalidate(); + } break; } return true; } } + + private static class SampleView extends View { + private static final int ROWS = 16; + private static final int COLS = 16; + + private BoundaryPatch mPatch; + private float[] mCubics; + private float[] mOrig = new float[24]; + private Paint mPaint0; + private Paint mPaint1; + private int mCurrIndex = -1; + private float mPrevX; + private float mPrevY; + + public SampleView(Context context) { + super(context); + setFocusable(true); + + Bitmap bm = BitmapFactory.decodeResource(getResources(), + R.drawable.beach); + + mPatch = new BoundaryPatch(); + mPatch.setTexture(bm); + + float unit = 90; + mCubics = new float[] { + 0, 0, 1, 0, 2, 0, + 3, 0, 3, 1, 3, 2, + 3, 3, 2, 3, 1, 3, + 0, 3, 0, 2, 0, 1 + }; + for (int i = 0; i < 24; i++) { + mCubics[i] *= 90; + mCubics[i] += 20; + } + rebuildPatch(); + + mPaint0 = new Paint(); + mPaint0.setAntiAlias(true); + mPaint0.setStrokeWidth(12); + mPaint0.setStrokeCap(Paint.Cap.ROUND); + mPaint1 = new Paint(mPaint0); + mPaint1.setColor(0xFFFFFFFF); + mPaint1.setStrokeWidth(10); + } + + @Override protected void onDraw(Canvas canvas) { + canvas.drawColor(0xFFCCCCCC); + mPatch.draw(canvas); + canvas.drawPoints(mCubics, mPaint0); + canvas.drawPoints(mCubics, mPaint1); + } + + private void rebuildPatch() { + mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS); + } + + private int findPtIndex(float x, float y) { + final float tolerance = 25; + final float[] pts = mCubics; + for (int i = 0; i < (pts.length >> 1); i++) { + if (Math.abs(pts[i*2 + 0] - x) <= tolerance && + Math.abs(pts[i*2 + 1] - y) <= tolerance) { + return i*2; + } + } + return -1; + } + + private void offsetPts(float dx, float dy) { + final float[] pts = mCubics; + for (int i = 0; i < (pts.length >> 1); i++) { + pts[i*2 + 0] += dx; + pts[i*2 + 1] += dy; + } + rebuildPatch(); + } + + @Override public boolean onTouchEvent(MotionEvent event) { + float x = event.getX(); + float y = event.getY(); + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mCurrIndex = findPtIndex(x, y); + mPrevX = x; + mPrevY = y; + break; + case MotionEvent.ACTION_MOVE: + if (mCurrIndex >= 0) { + mCubics[mCurrIndex + 0] = x; + mCubics[mCurrIndex + 1] = y; + mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS); + } else { + offsetPts(x - mPrevX, y - mPrevY); + mPrevX = x; + mPrevY = y; + } + invalidate(); + break; + } + return true; + } +} }