• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.gallery3d.photoeditor.actions;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Canvas;
22 import android.graphics.Matrix;
23 import android.graphics.Paint;
24 import android.graphics.Path;
25 import android.graphics.PointF;
26 import android.graphics.RectF;
27 import android.util.AttributeSet;
28 import android.view.MotionEvent;
29 
30 /**
31  * A view that tracks touch motions as paths and paints them as doodles.
32  */
33 class DoodleView extends FullscreenToolView {
34 
35     /**
36      * Listener of doodle paths.
37      */
38     public interface OnDoodleChangeListener {
39 
onDoodleChanged(Doodle doodle)40         void onDoodleChanged(Doodle doodle);
41 
onDoodleFinished(Doodle doodle)42         void onDoodleFinished(Doodle doodle);
43     }
44 
45     private final Paint bitmapPaint = new Paint(Paint.DITHER_FLAG);
46     private final Paint doodlePaint = Doodle.createPaint();
47     private final PointF lastPoint = new PointF();
48     private final Path drawingPath = new Path();
49     private final Matrix drawingMatrix = new Matrix();
50     private final Matrix displayMatrix = new Matrix();
51 
52     private Bitmap bitmap;
53     private Canvas bitmapCanvas;
54     private Doodle doodle;
55     private int color;
56     private OnDoodleChangeListener listener;
57 
DoodleView(Context context, AttributeSet attrs)58     public DoodleView(Context context, AttributeSet attrs) {
59         super(context, attrs);
60     }
61 
setOnDoodleChangeListener(OnDoodleChangeListener listener)62     public void setOnDoodleChangeListener(OnDoodleChangeListener listener) {
63         this.listener = listener;
64     }
65 
66     @Override
onSizeChanged(int w, int h, int oldw, int oldh)67     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
68         super.onSizeChanged(w, h, oldw, oldh);
69 
70         RectF r = new RectF(0, 0, getPhotoWidth(), getPhotoHeight());
71         if ((bitmap == null) && !r.isEmpty()) {
72             bitmap = Bitmap.createBitmap((int) r.width(), (int) r.height(),
73                     Bitmap.Config.ARGB_8888);
74             bitmapCanvas = new Canvas(bitmap);
75 
76             // Set up a matrix that maps back normalized paths to be drawn on the bitmap or canvas.
77             drawingMatrix.setRectToRect(new RectF(0, 0, 1, 1), r, Matrix.ScaleToFit.FILL);
78         }
79         displayMatrix.setRectToRect(r, displayBounds, Matrix.ScaleToFit.FILL);
80     }
81 
drawDoodle(Canvas canvas)82     private void drawDoodle(Canvas canvas) {
83         if ((canvas != null) && (doodle != null)) {
84             doodlePaint.setColor(doodle.getColor());
85             doodle.getDrawingPath(drawingMatrix, drawingPath);
86             canvas.drawPath(drawingPath, doodlePaint);
87         }
88     }
89 
setColor(int color)90     public void setColor(int color) {
91         // Restart doodle to draw in a new color.
92         this.color = color;
93         finishDoodle();
94         startDoodle();
95     }
96 
startDoodle()97     private void startDoodle() {
98         doodle = new Doodle(color, new PointF(lastPoint.x, lastPoint.y));
99     }
100 
finishDoodle()101     private void finishDoodle() {
102         if ((doodle != null) && !doodle.isEmpty()) {
103             // Update the finished non-empty doodle to the bitmap.
104             drawDoodle(bitmapCanvas);
105             if (listener != null) {
106                 listener.onDoodleFinished(doodle);
107             }
108             invalidate();
109         }
110         doodle = null;
111     }
112 
addLastPointIntoDoodle()113     private void addLastPointIntoDoodle() {
114         if (doodle != null) {
115             doodle.addControlPoint(new PointF(lastPoint.x, lastPoint.y));
116             if (listener != null) {
117                 listener.onDoodleChanged(doodle);
118             }
119             invalidate();
120         }
121     }
122 
123     @Override
onTouchEvent(MotionEvent event)124     public boolean onTouchEvent(MotionEvent event) {
125         super.onTouchEvent(event);
126 
127         if (isEnabled()) {
128             float x = event.getX();
129             float y = event.getY();
130 
131             switch (event.getAction()) {
132                 case MotionEvent.ACTION_DOWN:
133                     mapPhotoPoint(x, y, lastPoint);
134                     startDoodle();
135                     break;
136 
137                 case MotionEvent.ACTION_MOVE:
138                     mapPhotoPoint(x, y, lastPoint);
139                     addLastPointIntoDoodle();
140                     break;
141 
142                 case MotionEvent.ACTION_CANCEL:
143                 case MotionEvent.ACTION_UP:
144                     // Line to last position with offset to draw at least dots for single clicks.
145                     mapPhotoPoint(x + 1, y + 1, lastPoint);
146                     addLastPointIntoDoodle();
147                     finishDoodle();
148                     break;
149             }
150         }
151         return true;
152     }
153 
154     @Override
onDraw(Canvas canvas)155     protected void onDraw(Canvas canvas) {
156         super.onDraw(canvas);
157 
158         canvas.save();
159         canvas.clipRect(displayBounds);
160         canvas.concat(displayMatrix);
161         if (bitmap != null) {
162             canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
163         }
164         drawDoodle(canvas);
165         canvas.restore();
166     }
167 }
168