OSDN Git Service

Tweaks to make pointer location a little easier to see.
[android-x86/development.git] / apps / Development / src / com / android / development / PointerLocation.java
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.development;
18
19 import android.app.Activity;
20 import android.content.Context;
21 import android.graphics.Canvas;
22 import android.graphics.Paint;
23 import android.graphics.Paint.FontMetricsInt;
24 import android.os.Bundle;
25 import android.util.Log;
26 import android.view.MotionEvent;
27 import android.view.WindowManager;
28 import android.view.VelocityTracker;
29 import android.view.View;
30
31 import java.util.ArrayList;
32
33 /**
34  * Demonstrates wrapping a layout in a ScrollView.
35  *
36  */
37 public class PointerLocation extends Activity {
38     @Override
39     protected void onCreate(Bundle icicle) {
40         super.onCreate(icicle);
41         setContentView(new MyView(this));
42         
43         // Make the screen full bright for this activity.
44         WindowManager.LayoutParams lp = getWindow().getAttributes();
45         lp.screenBrightness = 1.0f;
46         getWindow().setAttributes(lp);
47     }
48     
49     public static class PointerState {
50         private final ArrayList<Float> mXs = new ArrayList<Float>();
51         private final ArrayList<Float> mYs = new ArrayList<Float>();
52         private boolean mCurDown;
53         private int mCurX;
54         private int mCurY;
55         private float mCurPressure;
56         private float mCurSize;
57         private int mCurWidth;
58         private VelocityTracker mVelocity;
59     }
60     
61     public class MyView extends View {
62         private final Paint mTextPaint;
63         private final Paint mTextBackgroundPaint;
64         private final Paint mTextLevelPaint;
65         private final Paint mPaint;
66         private final Paint mTargetPaint;
67         private final Paint mPathPaint;
68         private final FontMetricsInt mTextMetrics = new FontMetricsInt();
69         private int mHeaderBottom;
70         private boolean mCurDown;
71         private int mCurNumPointers;
72         private int mMaxNumPointers;
73         private final ArrayList<PointerState> mPointers
74                  = new ArrayList<PointerState>();
75         
76         public MyView(Context c) {
77             super(c);
78             mTextPaint = new Paint();
79             mTextPaint.setAntiAlias(true);
80             mTextPaint.setTextSize(10
81                     * getResources().getDisplayMetrics().density);
82             mTextPaint.setARGB(255, 0, 0, 0);
83             mTextBackgroundPaint = new Paint();
84             mTextBackgroundPaint.setAntiAlias(false);
85             mTextBackgroundPaint.setARGB(128, 255, 255, 255);
86             mTextLevelPaint = new Paint();
87             mTextLevelPaint.setAntiAlias(false);
88             mTextLevelPaint.setARGB(192, 255, 0, 0);
89             mPaint = new Paint();
90             mPaint.setAntiAlias(true);
91             mPaint.setARGB(255, 255, 255, 255);
92             mPaint.setStyle(Paint.Style.STROKE);
93             mPaint.setStrokeWidth(2);
94             mTargetPaint = new Paint();
95             mTargetPaint.setAntiAlias(false);
96             mTargetPaint.setARGB(255, 0, 0, 192);
97             mPathPaint = new Paint();
98             mPathPaint.setAntiAlias(false);
99             mPathPaint.setARGB(255, 0, 96, 255);
100             mPaint.setStyle(Paint.Style.STROKE);
101             mPaint.setStrokeWidth(1);
102             
103             PointerState ps = new PointerState();
104             ps.mVelocity = VelocityTracker.obtain();
105             mPointers.add(ps);
106         }
107
108         @Override
109         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
110             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
111             mTextPaint.getFontMetricsInt(mTextMetrics);
112             mHeaderBottom = -mTextMetrics.ascent+mTextMetrics.descent+2;
113             Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent
114                     + " descent=" + mTextMetrics.descent
115                     + " leading=" + mTextMetrics.leading
116                     + " top=" + mTextMetrics.top
117                     + " bottom=" + mTextMetrics.bottom);
118         }
119
120         @Override
121         protected void onDraw(Canvas canvas) {
122             final int w = getWidth();
123             final int itemW = w/7;
124             final int base = -mTextMetrics.ascent+1;
125             final int bottom = mHeaderBottom;
126             
127             final int NP = mPointers.size();
128             
129             if (NP > 0) {
130                 final PointerState ps = mPointers.get(0);
131                 canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
132                 canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
133                         1, base, mTextPaint);
134                 
135                 canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
136                 canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
137                 
138                 canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
139                 canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
140                 
141                 canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
142                 int velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getXVelocity() * 1000);
143                 canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
144                 
145                 canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
146                 velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getYVelocity() * 1000);
147                 canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
148                 
149                 canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
150                 canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
151                         bottom, mTextLevelPaint);
152                 canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
153                         base, mTextPaint);
154                 
155                 canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
156                 canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
157                         bottom, mTextLevelPaint);
158                 canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
159                         base, mTextPaint);
160             }
161             
162             for (int p=0; p<NP; p++) {
163                 final PointerState ps = mPointers.get(p);
164                 
165                 if (mCurDown && ps.mCurDown) {
166                     canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
167                     canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
168                     int pressureLevel = (int)(ps.mCurPressure*255);
169                     mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
170                     canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
171                     canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
172                 }
173             }
174             
175             for (int p=0; p<NP; p++) {
176                 final PointerState ps = mPointers.get(p);
177                 
178                 final int N = ps.mXs.size();
179                 float lastX=0, lastY=0;
180                 boolean haveLast = false;
181                 boolean drawn = false;
182                 mPaint.setARGB(255, 128, 255, 255);
183                 for (int i=0; i<N; i++) {
184                     float x = ps.mXs.get(i);
185                     float y = ps.mYs.get(i);
186                     if (Float.isNaN(x)) {
187                         haveLast = false;
188                         continue;
189                     }
190                     if (haveLast) {
191                         canvas.drawLine(lastX, lastY, x, y, mPathPaint);
192                         canvas.drawPoint(lastX, lastY, mPaint);
193                         drawn = true;
194                     }
195                     lastX = x;
196                     lastY = y;
197                     haveLast = true;
198                 }
199                 
200                 if (drawn) {
201                     if (ps.mVelocity != null) {
202                         mPaint.setARGB(255, 255, 64, 128);
203                         float xVel = ps.mVelocity.getXVelocity() * (1000/60);
204                         float yVel = ps.mVelocity.getYVelocity() * (1000/60);
205                         canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
206                     } else {
207                         canvas.drawPoint(lastX, lastY, mPaint);
208                     }
209                 }
210             }
211         }
212
213         @Override
214         public boolean onTouchEvent(MotionEvent event) {
215             int action = event.getAction();
216             
217             //Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
218             //        + " pointers=" + event.getPointerCount());
219             
220             int NP = mPointers.size();
221             
222             //mRect.set(0, 0, getWidth(), mHeaderBottom+1);
223             //invalidate(mRect);
224             //if (mCurDown) {
225             //    mRect.set(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
226             //            mCurX+mCurWidth+3, mCurY+mCurWidth+3);
227             //} else {
228             //    mRect.setEmpty();
229             //}
230             if (action == MotionEvent.ACTION_DOWN) {
231                 for (int p=0; p<NP; p++) {
232                     final PointerState ps = mPointers.get(p);
233                     ps.mXs.clear();
234                     ps.mYs.clear();
235                     ps.mVelocity = VelocityTracker.obtain();
236                     ps.mCurDown = false;
237                 }
238                 mPointers.get(0).mCurDown = true;
239                 mMaxNumPointers = 0;
240             }
241             
242             if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
243                 final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
244                         >> MotionEvent.ACTION_POINTER_ID_SHIFT;
245                 while (NP <= id) {
246                     PointerState ps = new PointerState();
247                     ps.mVelocity = VelocityTracker.obtain();
248                     mPointers.add(ps);
249                     NP++;
250                 }
251                 final PointerState ps = mPointers.get(id);
252                 ps.mVelocity = VelocityTracker.obtain();
253                 ps.mCurDown = true;
254             }
255             
256             final int NI = event.getPointerCount();
257             
258             mCurDown = action != MotionEvent.ACTION_UP
259                     && action != MotionEvent.ACTION_CANCEL;
260             mCurNumPointers = mCurDown ? NI : 0;
261             if (mMaxNumPointers < mCurNumPointers) {
262                 mMaxNumPointers = mCurNumPointers;
263             }
264             
265             for (int i=0; i<NI; i++) {
266                 final PointerState ps = mPointers.get(event.getPointerId(i));
267                 ps.mVelocity.addMovement(event);
268                 ps.mVelocity.computeCurrentVelocity(1);
269                 final int N = event.getHistorySize();
270                 for (int j=0; j<N; j++) {
271                     ps.mXs.add(event.getHistoricalX(i, j));
272                     ps.mYs.add(event.getHistoricalY(i, j));
273                 }
274                 ps.mXs.add(event.getX(i));
275                 ps.mYs.add(event.getY(i));
276                 ps.mCurX = (int)event.getX(i);
277                 ps.mCurY = (int)event.getY(i);
278                 //Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
279                 //        + "," + ps.mCurY + ")");
280                 ps.mCurPressure = event.getPressure(i);
281                 ps.mCurSize = event.getSize(i);
282                 ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
283             }
284             
285             if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
286                 final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
287                         >> MotionEvent.ACTION_POINTER_ID_SHIFT;
288                 final PointerState ps = mPointers.get(id);
289                 ps.mXs.add(Float.NaN);
290                 ps.mYs.add(Float.NaN);
291                 ps.mCurDown = false;
292             }
293             
294             //if (mCurDown) {
295             //    mRect.union(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
296             //            mCurX+mCurWidth+3, mCurY+mCurWidth+3);
297             //}
298             //invalidate(mRect);
299             invalidate();
300             return true;
301         }
302         
303     }
304 }