• 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.example.android.apis.graphics;
18 
19 import android.app.Activity;
20 import android.content.Context;
21 import android.graphics.*;
22 import android.os.Bundle;
23 import android.view.Menu;
24 import android.view.MenuItem;
25 import android.view.MotionEvent;
26 import android.view.View;
27 
28 public class FingerPaint extends GraphicsActivity
29         implements ColorPickerDialog.OnColorChangedListener {
30 
31     @Override
onCreate(Bundle savedInstanceState)32     protected void onCreate(Bundle savedInstanceState) {
33         super.onCreate(savedInstanceState);
34         setContentView(new MyView(this));
35 
36         mPaint = new Paint();
37         mPaint.setAntiAlias(true);
38         mPaint.setDither(true);
39         mPaint.setColor(0xFFFF0000);
40         mPaint.setStyle(Paint.Style.STROKE);
41         mPaint.setStrokeJoin(Paint.Join.ROUND);
42         mPaint.setStrokeCap(Paint.Cap.ROUND);
43         mPaint.setStrokeWidth(12);
44 
45         mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
46                                        0.4f, 6, 3.5f);
47 
48         mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
49     }
50 
51     private Paint       mPaint;
52     private MaskFilter  mEmboss;
53     private MaskFilter  mBlur;
54 
colorChanged(int color)55     public void colorChanged(int color) {
56         mPaint.setColor(color);
57     }
58 
59     public class MyView extends View {
60 
61         private static final float MINP = 0.25f;
62         private static final float MAXP = 0.75f;
63 
64         private Bitmap  mBitmap;
65         private Canvas  mCanvas;
66         private Path    mPath;
67         private Paint   mBitmapPaint;
68 
MyView(Context c)69         public MyView(Context c) {
70             super(c);
71 
72             mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
73             mCanvas = new Canvas(mBitmap);
74             mPath = new Path();
75             mBitmapPaint = new Paint(Paint.DITHER_FLAG);
76         }
77 
78         @Override
onSizeChanged(int w, int h, int oldw, int oldh)79         protected void onSizeChanged(int w, int h, int oldw, int oldh) {
80             super.onSizeChanged(w, h, oldw, oldh);
81         }
82 
83         @Override
onDraw(Canvas canvas)84         protected void onDraw(Canvas canvas) {
85             canvas.drawColor(0xFFAAAAAA);
86 
87             canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
88 
89             canvas.drawPath(mPath, mPaint);
90         }
91 
92         private float mX, mY;
93         private static final float TOUCH_TOLERANCE = 4;
94 
touch_start(float x, float y)95         private void touch_start(float x, float y) {
96             mPath.reset();
97             mPath.moveTo(x, y);
98             mX = x;
99             mY = y;
100         }
touch_move(float x, float y)101         private void touch_move(float x, float y) {
102             float dx = Math.abs(x - mX);
103             float dy = Math.abs(y - mY);
104             if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
105                 mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
106                 mX = x;
107                 mY = y;
108             }
109         }
touch_up()110         private void touch_up() {
111             mPath.lineTo(mX, mY);
112             // commit the path to our offscreen
113             mCanvas.drawPath(mPath, mPaint);
114             // kill this so we don't double draw
115             mPath.reset();
116         }
117 
118         @Override
onTouchEvent(MotionEvent event)119         public boolean onTouchEvent(MotionEvent event) {
120             float x = event.getX();
121             float y = event.getY();
122 
123             switch (event.getAction()) {
124                 case MotionEvent.ACTION_DOWN:
125                     touch_start(x, y);
126                     invalidate();
127                     break;
128                 case MotionEvent.ACTION_MOVE:
129                     touch_move(x, y);
130                     invalidate();
131                     break;
132                 case MotionEvent.ACTION_UP:
133                     touch_up();
134                     invalidate();
135                     break;
136             }
137             return true;
138         }
139     }
140 
141     private static final int COLOR_MENU_ID = Menu.FIRST;
142     private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
143     private static final int BLUR_MENU_ID = Menu.FIRST + 2;
144     private static final int ERASE_MENU_ID = Menu.FIRST + 3;
145     private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
146 
147     @Override
onCreateOptionsMenu(Menu menu)148     public boolean onCreateOptionsMenu(Menu menu) {
149         super.onCreateOptionsMenu(menu);
150 
151         menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
152         menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
153         menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
154         menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
155         menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');
156 
157         /****   Is this the mechanism to extend with filter effects?
158         Intent intent = new Intent(null, getIntent().getData());
159         intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
160         menu.addIntentOptions(
161                               Menu.ALTERNATIVE, 0,
162                               new ComponentName(this, NotesList.class),
163                               null, intent, 0, null);
164         *****/
165         return true;
166     }
167 
168     @Override
onPrepareOptionsMenu(Menu menu)169     public boolean onPrepareOptionsMenu(Menu menu) {
170         super.onPrepareOptionsMenu(menu);
171         return true;
172     }
173 
174     @Override
onOptionsItemSelected(MenuItem item)175     public boolean onOptionsItemSelected(MenuItem item) {
176         mPaint.setXfermode(null);
177         mPaint.setAlpha(0xFF);
178 
179         switch (item.getItemId()) {
180             case COLOR_MENU_ID:
181                 new ColorPickerDialog(this, this, mPaint.getColor()).show();
182                 return true;
183             case EMBOSS_MENU_ID:
184                 if (mPaint.getMaskFilter() != mEmboss) {
185                     mPaint.setMaskFilter(mEmboss);
186                 } else {
187                     mPaint.setMaskFilter(null);
188                 }
189                 return true;
190             case BLUR_MENU_ID:
191                 if (mPaint.getMaskFilter() != mBlur) {
192                     mPaint.setMaskFilter(mBlur);
193                 } else {
194                     mPaint.setMaskFilter(null);
195                 }
196                 return true;
197             case ERASE_MENU_ID:
198                 mPaint.setXfermode(new PorterDuffXfermode(
199                                                         PorterDuff.Mode.CLEAR));
200                 return true;
201             case SRCATOP_MENU_ID:
202                 mPaint.setXfermode(new PorterDuffXfermode(
203                                                     PorterDuff.Mode.SRC_ATOP));
204                 mPaint.setAlpha(0x80);
205                 return true;
206         }
207         return super.onOptionsItemSelected(item);
208     }
209 }
210