diff options
Diffstat (limited to 'apps/SdkController/src/com/android/tools/sdkcontroller/views/MultiTouchView.java')
-rwxr-xr-x | apps/SdkController/src/com/android/tools/sdkcontroller/views/MultiTouchView.java | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/apps/SdkController/src/com/android/tools/sdkcontroller/views/MultiTouchView.java b/apps/SdkController/src/com/android/tools/sdkcontroller/views/MultiTouchView.java new file mode 100755 index 000000000..0f185b173 --- /dev/null +++ b/apps/SdkController/src/com/android/tools/sdkcontroller/views/MultiTouchView.java @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.tools.sdkcontroller.views; + +import java.io.InputStream; +import java.nio.ByteBuffer; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; + +/** + * Implements a main view for the application providing multi-touch emulation. + */ +public class MultiTouchView extends View { + /** Tag for logging messages. */ + private static final String TAG = MultiTouchView.class.getSimpleName(); + /** + * Back-end bitmap. Initialized in onSizeChanged(), updated in + * onTouchEvent() and drawn in onDraw(). + */ + private Bitmap mBitmap; + /** Default Paint instance for drawing the bitmap. */ + private final Paint mPaint = new Paint(); + /** Canvas instance for this view. */ + private Canvas mCanvas; + /** Emulator screen width to this view width ratio. */ + private float mDx = 1; + /** Emulator screen height to this view height ratio. */ + private float mDy = 1; + /** + * Flags whether or not image received from the emulator should be rotated. + * Rotation is required when display orientation state of the emulator and + * the device doesn't match. + */ + private boolean mRotateDisplay; + /** Base matrix that keep emulator->device display scaling */ + private Matrix mBaseMatrix = new Matrix(); + /** Matrix that is used to draw emulator's screen on the device. */ + private Matrix mDrawMatrix = new Matrix(); + + /** + * Simple constructor to use when creating a view from code. + * + * @see View#View(Context) + */ + public MultiTouchView(Context context) { + this(context, null); + } + + /** + * Constructor that is called when inflating a view from XML. + * + * @see View#View(Context, AttributeSet) + */ + public MultiTouchView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + /** + * Perform inflation from XML and apply a class-specific base style. + * + * @see View#View(Context, AttributeSet, int) + */ + public MultiTouchView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + // TODO Add constructor-time code here. + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + mCanvas = new Canvas(mBitmap); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + // Just draw the back-end bitmap without zooming or scaling. + if (mBitmap != null) { + canvas.drawBitmap(mBitmap, 0, 0, null); + } + } + + /** + * Sets emulator screen width and height to this view width and height + * ratio. + * + * @param dx Emulator screen width to this view width ratio. + * @param dy Emulator screen height to this view height ratio. + * @param rotateDisplay Flags whether image received from the emulator + * should be rotated when drawn on the device. + */ + public void setDxDy(float dx, float dy, boolean rotateDisplay) { + mDx = dx; + mDy = dy; + mRotateDisplay = rotateDisplay; + + mBaseMatrix.setScale(dx, dy); + if (mRotateDisplay) { + mBaseMatrix.postRotate(90); + mBaseMatrix.postTranslate(getWidth(), 0); + } + } + + /** + * Computes draw matrix for the emulator screen update. + * + * @param x Left screen coordinate of the bitmap on emulator screen. + * @param y Top screen coordinate of the bitmap on emulator screen. + */ + private void computeDrawMatrix(int x, int y) { + mDrawMatrix.set(mBaseMatrix); + if (mRotateDisplay) { + mDrawMatrix.postTranslate(-y * mDy, x * mDx); + } else { + mDrawMatrix.postTranslate(x * mDx, y * mDy); + } + } + + /** + * Draws a bitmap on the screen. + * + * @param x Left screen coordinate of the bitmap on emulator screen. + * @param y Top screen coordinate of the bitmap on emulator screen. + * @param w Width of the bitmap on the emulator screen. + * @param h Height of the bitmap on the emulator screen. + * @param colors Bitmap to draw. + */ + public void drawBitmap(int x, int y, int w, int h, int[] colors) { + if (mCanvas != null) { + final Bitmap bmp = Bitmap.createBitmap(colors, 0, w, w, h, Bitmap.Config.ARGB_8888); + + computeDrawMatrix(x, y); + + /* Draw the bitmap and invalidate the updated region. */ + mCanvas.drawBitmap(bmp, mDrawMatrix, mPaint); + invalidate(); + } + } + + /** + * Draws a JPEG bitmap on the screen. + * + * @param x Left screen coordinate of the bitmap on emulator screen. + * @param y Top screen coordinate of the bitmap on emulator screen. + * @param w Width of the bitmap on the emulator screen. + * @param h Height of the bitmap on the emulator screen. + * @param jpeg JPEG bitmap to draw. + */ + public void drawJpeg(int x, int y, int w, int h, InputStream jpeg) { + if (mCanvas != null) { + final Bitmap bmp = BitmapFactory.decodeStream(jpeg); + + computeDrawMatrix(x, y); + + /* Draw the bitmap and invalidate the updated region. */ + mCanvas.drawBitmap(bmp, mDrawMatrix, mPaint); + invalidate(); + } + } + + /** + * Constructs touch event message to be send to emulator. + * + * @param bb ByteBuffer where to construct the message. + * @param event Event for which to construct the message. + * @param ptr_index Index of the motion pointer for which to construct the + * message. + */ + public void constructEventMessage(ByteBuffer bb, MotionEvent event, int ptr_index) { + bb.putInt(event.getPointerId(ptr_index)); + if (mRotateDisplay == false) { + bb.putInt((int) (event.getX(ptr_index) / mDx)); + bb.putInt((int) (event.getY(ptr_index) / mDy)); + } else { + bb.putInt((int) (event.getY(ptr_index) / mDy)); + bb.putInt((int) (getWidth() - event.getX(ptr_index) / mDx)); + } + // At the system level the input reader takes integers in the range + // 0 - 100 for the pressure. + int pressure = (int) (event.getPressure(ptr_index) * 100); + // Make sure it doesn't exceed 100... + if (pressure > 100) { + pressure = 100; + } + bb.putInt(pressure); + } + + /*************************************************************************** + * Logging wrappers + **************************************************************************/ + + @SuppressWarnings("unused") + private void Loge(String log) { + Log.e(TAG, log); + } + + @SuppressWarnings("unused") + private void Logw(String log) { + Log.w(TAG, log); + } + + @SuppressWarnings("unused") + private void Logv(String log) { + Log.v(TAG, log); + } +} |