OSDN Git Service

fix first draw bug
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / imageshow / ImageDraw.java
1
2 package com.android.gallery3d.filtershow.imageshow;
3
4 import android.content.Context;
5 import android.content.res.Resources;
6 import android.graphics.Bitmap;
7 import android.graphics.BitmapFactory;
8 import android.graphics.BitmapShader;
9 import android.graphics.Canvas;
10 import android.graphics.Color;
11 import android.graphics.Matrix;
12 import android.graphics.Paint;
13 import android.graphics.PorterDuff;
14 import android.graphics.PorterDuffColorFilter;
15 import android.graphics.RectF;
16 import android.graphics.Shader;
17 import android.graphics.drawable.Drawable;
18 import android.graphics.drawable.NinePatchDrawable;
19 import android.os.Handler;
20 import android.util.AttributeSet;
21 import android.view.MotionEvent;
22
23 import com.android.gallery3d.R;
24 import com.android.gallery3d.filtershow.editors.EditorDraw;
25 import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation;
26 import com.android.gallery3d.filtershow.filters.ImageFilterDraw;
27
28 public class ImageDraw extends ImageShow {
29
30     private static final String LOGTAG = "ImageDraw";
31     private int mCurrentColor = Color.RED;
32     final static float INITAL_STROKE_RADIUS = 40;
33     private float mCurrentSize = INITAL_STROKE_RADIUS;
34     private byte mType = 0;
35     private FilterDrawRepresentation mFRep;
36     private EditorDraw mEditorDraw;
37     private long mTimeout;
38     private Paint mCheckerdPaint = makeCheckedPaint();
39     private Paint mShadowPaint = new Paint();
40     private Paint mIconPaint = new Paint();
41     private Paint mBorderPaint = new Paint();
42     private Handler mHandler;
43     private FilterDrawRepresentation.StrokeData mTmpStrokData =
44             new FilterDrawRepresentation.StrokeData();
45     private Bitmap mBitmap;
46     private float mDisplayRound;
47     private float mDisplayBorder;
48     private int DISPLAY_TIME = 500;
49     private Matrix mRotateToScreen = new Matrix();
50     private Matrix mToOrig;
51     private int mBorderColor;
52     private int mBorderShadowSize;
53     private NinePatchDrawable mShadow;
54
55     Runnable mUpdateRunnable = new Runnable() {
56         @Override
57         public void run() {
58            invalidate();
59         }
60     };
61
62
63     public ImageDraw(Context context, AttributeSet attrs) {
64         super(context, attrs);
65         resetParameter();
66         setupConstants(context);
67         setupTimer();
68     }
69
70     public ImageDraw(Context context) {
71         super(context);
72         resetParameter();
73         setupConstants(context);
74         setupTimer();
75     }
76
77     private void setupConstants(Context context){
78         Resources res = context.getResources();
79         mDisplayRound = res.getDimensionPixelSize(R.dimen.draw_rect_round);
80         mDisplayBorder = res.getDimensionPixelSize(R.dimen.draw_rect_border);
81         mBorderShadowSize = res.getDimensionPixelSize(R.dimen.draw_rect_shadow);
82         float edge = res.getDimensionPixelSize(R.dimen.draw_rect_border_edge);
83
84         mBorderColor = res.getColor(R.color.draw_rect_border);
85         mBorderPaint.setColor(mBorderColor);
86         mBorderPaint.setStyle(Paint.Style.STROKE);
87         mBorderPaint.setStrokeWidth(edge);
88         mShadowPaint.setStyle(Paint.Style.FILL);
89         mShadowPaint.setColor(Color.BLACK);
90         mShadowPaint.setShadowLayer(mBorderShadowSize,mBorderShadowSize,
91                 mBorderShadowSize,Color.BLACK);
92         mShadow = (NinePatchDrawable) res.getDrawable(R.drawable.geometry_shadow);
93     }
94
95     public void setEditor(EditorDraw editorDraw) {
96         mEditorDraw = editorDraw;
97     }
98
99     public void setFilterDrawRepresentation(FilterDrawRepresentation fr) {
100         mFRep = fr;
101         mTmpStrokData =
102                 new FilterDrawRepresentation.StrokeData();
103     }
104
105     public Drawable getIcon(Context context) {
106
107         return null;
108     }
109
110     @Override
111     public void resetParameter() {
112         if (mFRep != null) {
113             mFRep.clear();
114         }
115     }
116
117     public void setColor(int color) {
118         mCurrentColor = color;
119     }
120
121     public void setSize(int size) {
122         mCurrentSize = size;
123     }
124
125     public void setStyle(byte style) {
126         mType = (byte) (style % ImageFilterDraw.NUMBER_OF_STYLES);
127     }
128
129     public int getStyle() {
130         return mType;
131     }
132
133     public int getSize() {
134         return (int) mCurrentSize;
135     }
136
137     float[] mTmpPoint = new float[2]; // so we do not malloc
138     @Override
139     public boolean onTouchEvent(MotionEvent event) {
140         if (event.getPointerCount() > 1) {
141             boolean ret = super.onTouchEvent(event);
142             if (mFRep.getCurrentDrawing() != null) {
143                 mFRep.clearCurrentSection();
144                 mEditorDraw.commitLocalRepresentation();
145             }
146             return ret;
147         }
148         if (event.getAction() != MotionEvent.ACTION_DOWN) {
149             if (mFRep.getCurrentDrawing() == null) {
150                 return super.onTouchEvent(event);
151             }
152         }
153
154         if (event.getAction() == MotionEvent.ACTION_DOWN) {
155             calcScreenMapping();
156             mTmpPoint[0] = event.getX();
157             mTmpPoint[1] = event.getY();
158             mToOrig.mapPoints(mTmpPoint);
159             mFRep.startNewSection( mTmpPoint[0], mTmpPoint[1]);
160         }
161
162         if (event.getAction() == MotionEvent.ACTION_MOVE) {
163
164             int historySize = event.getHistorySize();
165             for (int h = 0; h < historySize; h++) {
166                 int p = 0;
167                 {
168                     mTmpPoint[0] = event.getHistoricalX(p, h);
169                     mTmpPoint[1] = event.getHistoricalY(p, h);
170                     mToOrig.mapPoints(mTmpPoint);
171                     mFRep.addPoint(mTmpPoint[0], mTmpPoint[1]);
172                 }
173             }
174         }
175
176         if (event.getAction() == MotionEvent.ACTION_UP) {
177             mTmpPoint[0] = event.getX();
178             mTmpPoint[1] = event.getY();
179             mToOrig.mapPoints(mTmpPoint);
180             mFRep.endSection(mTmpPoint[0], mTmpPoint[1]);
181         }
182         mEditorDraw.commitLocalRepresentation();
183         invalidate();
184         return true;
185     }
186
187     private void calcScreenMapping() {
188         mToOrig = getScreenToImageMatrix(true);
189         mToOrig.invert(mRotateToScreen);
190     }
191
192     private static Paint makeCheckedPaint(){
193         int[] colors = new int[16 * 16];
194         for (int i = 0; i < colors.length; i++) {
195             int y = i / (16 * 8);
196             int x = (i / 8) % 2;
197             colors[i] = (x == y) ? 0xFF777777 : 0xFF222222;
198         }
199         Bitmap bitmap = Bitmap.createBitmap(colors, 16, 16, Bitmap.Config.ARGB_8888);
200         BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
201         Paint p = new Paint();
202         p.setShader(bs);
203         return p;
204     }
205
206     private void setupTimer() {
207         mHandler = new Handler(getActivity().getMainLooper());
208     }
209
210     private void scheduleWakeup(int delay) {
211         mHandler.removeCallbacks(mUpdateRunnable);
212         mHandler.postDelayed(mUpdateRunnable, delay);
213     }
214
215     public Bitmap getBrush(int brushid) {
216         Bitmap bitmap;
217         BitmapFactory.Options opt = new BitmapFactory.Options();
218         opt.inPreferredConfig = Bitmap.Config.ALPHA_8;
219         bitmap = BitmapFactory.decodeResource(getActivity().getResources(), brushid, opt);
220         bitmap = bitmap.extractAlpha();
221
222         return bitmap;
223     }
224
225     public Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) {
226         Matrix m = new Matrix();
227         m.setScale(dstWidth / (float) src.getWidth(), dstHeight / (float) src.getHeight());
228         Bitmap result = Bitmap.createBitmap(dstWidth, dstHeight, src.getConfig());
229         Canvas canvas = new Canvas(result);
230
231         Paint paint = new Paint();
232         paint.setFilterBitmap(filter);
233         canvas.drawBitmap(src, m, paint);
234
235         return result;
236
237     }
238
239     public void displayDrawLook() {
240         if (mFRep == null) {
241             return;
242         }
243         int color = mTmpStrokData.mColor;
244         byte type = mTmpStrokData.mType;
245         float radius = mTmpStrokData.mRadius;
246         mFRep.fillStrokeParameters(mTmpStrokData);
247         if (type != mTmpStrokData.mType || radius != mTmpStrokData.mRadius) {
248             mBitmap = getBrush(mEditorDraw.getBrushIcon(mTmpStrokData.mType));
249             float size = mRotateToScreen.mapRadius(mTmpStrokData.mRadius) * 2;
250             mBitmap = createScaledBitmap(mBitmap, (int) size, (int) size, true);
251         }
252
253         if (color == mTmpStrokData.mColor
254                 && type == mTmpStrokData.mType
255                 && radius == mTmpStrokData.mRadius) {
256             return;
257         }
258
259         mTimeout = DISPLAY_TIME + System.currentTimeMillis();
260         scheduleWakeup(DISPLAY_TIME);
261     }
262
263     public void drawLook(Canvas canvas) {
264         if (mFRep == null) {
265             return;
266         }
267         int cw = canvas.getWidth();
268         int ch = canvas.getHeight();
269         int centerx = cw / 2;
270         int centery = ch / 2;
271
272         mFRep.fillStrokeParameters(mTmpStrokData);
273         mIconPaint.setAntiAlias(true);
274         mIconPaint.setColor(mTmpStrokData.mColor);
275
276         mIconPaint.setColorFilter(new PorterDuffColorFilter(mTmpStrokData.mColor,
277                 PorterDuff.Mode.MULTIPLY));
278         float rad = mRotateToScreen.mapRadius(mTmpStrokData.mRadius);
279         RectF rec = new RectF();
280         rec.set(centerx - mDisplayBorder - rad,
281                 centery - mDisplayBorder - rad,
282                 centerx + mDisplayBorder + rad,
283                 centery + mDisplayBorder + rad);
284         mShadow.setBounds((int) (mBorderShadowSize + rec.left),
285                 (int) (mBorderShadowSize + rec.top),
286                 (int) (mBorderShadowSize + rec.right),
287                 (int) (mBorderShadowSize + rec.bottom));
288         mShadow.draw(canvas);
289         canvas.drawRoundRect(rec, mDisplayRound, mDisplayRound, mCheckerdPaint);
290         canvas.drawRoundRect(rec, mDisplayRound, mDisplayRound, mBorderPaint);
291         canvas.drawBitmap(mBitmap,
292                 centerx - mBitmap.getWidth() / 2,
293                 centery - mBitmap.getHeight() / 2, mIconPaint);
294     }
295
296     @Override
297     public void onDraw(Canvas canvas) {
298         super.onDraw(canvas);
299         calcScreenMapping();
300         if (System.currentTimeMillis() < mTimeout) {
301             drawLook(canvas);
302         }
303     }
304
305 }