Home | History | Annotate | Download | only in graphicslab
      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 {
     30     public GraphicsLab() {}
     31 
     32     private int mCurrView = 1;
     33 
     34     public void onCreate(Bundle icicle) {
     35         super.onCreate(icicle);
     36         setContentView(new SampleView(this));
     37 //        setTitle("Graphics Lab");
     38     }
     39 
     40     @Override
     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 
     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
    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 
    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 
    143         private void rebuildPatch() {
    144             mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
    145         }
    146 
    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 
    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 
    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 
    248     private void rebuildPatch() {
    249         mPatch.setCubicBoundary(mCubics, 0, ROWS, COLS);
    250     }
    251 
    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 
    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 
    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