DragView.java revision 00acb123c5100f06b8e89e8ec8978ebafc6f6d26
100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato/* 200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Copyright (C) 2008 The Android Open Source Project 300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * you may not use this file except in compliance with the License. 600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * You may obtain a copy of the License at 700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 1000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Unless required by applicable law or agreed to in writing, software 1100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 1200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * See the License for the specific language governing permissions and 1400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * limitations under the License. 1500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 1600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 1700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 1800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopackage com.android.launcher2; 1900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 2000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.content.Context; 2100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.content.res.TypedArray; 2200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap; 2300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Canvas; 2400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Matrix; 2500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Paint; 2600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.PixelFormat; 2700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Point; 2800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.IBinder; 2900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.util.AttributeSet; 3000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.util.Log; 3100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.Gravity; 3200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.View; 3300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.ViewGroup; 3400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.KeyEvent; 3500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.WindowManager; 3600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.WindowManagerImpl; 3700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 3800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopublic class DragView extends View implements TweenCallback { 3900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // Number of pixels to add to the dragged item for scaling. Should be even for pixel alignment. 4000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private static final int DRAG_SCALE = 24; 4100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 4200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private Bitmap mBitmap; 4300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private Paint mPaint; 4400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private int mRegistrationX; 4500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private int mRegistrationY; 4600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 4700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato SymmetricalLinearTween mTween; 4800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private float mScale; 4900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private float mAnimationScale = 1.0f; 5000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 5100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private WindowManager.LayoutParams mLayoutParams; 5200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private WindowManager mWindowManager; 5300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 5400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 5500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Construct the drag view. 5600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * <p> 5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * The registration point is the point inside our view that the touch events should 5800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * be centered upon. 5900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 6000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param context A context 6100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param bitmap The view that we're dragging around. We scale it up when we draw it. 6200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationX The x coordinate of the registration point. 6300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param registrationY The y coordinate of the registration point. 6400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 6500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public DragView(Context context, Bitmap bitmap, int registrationX, int registrationY) { 6600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato super(context); 6700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 6800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mWindowManager = WindowManagerImpl.getDefault(); 6900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 7000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mTween = new SymmetricalLinearTween(false, 110 /*ms duration*/, this); 7100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 7200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int width = bitmap.getWidth(); 7300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int height = bitmap.getHeight(); 7400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 7500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato Matrix scale = new Matrix(); 7600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato float scaleFactor = width; 7700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato scaleFactor = mScale = (scaleFactor + DRAG_SCALE) / scaleFactor; 7800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato scale.setScale(scaleFactor, scaleFactor); 7900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 8000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, scale, true); 8100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 8200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // The point in our scaled bitmap that the touch events are located 8300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mRegistrationX = registrationX + (DRAG_SCALE / 2); 8400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mRegistrationY = registrationY + (DRAG_SCALE / 2); 8500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 8600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 8700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato @Override 8800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 8900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int widthSize = resolveSize(mBitmap.getWidth(), widthMeasureSpec); 9000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int heightSize = resolveSize(mBitmap.getHeight(), heightMeasureSpec); 9100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato setMeasuredDimension(widthSize, heightSize); 9200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 9300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 9400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato @Override 9500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onDraw(Canvas canvas) { 9600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (false) { 9700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // for debugging 9800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato Paint p = new Paint(); 9900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato p.setStyle(Paint.Style.FILL); 10000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato p.setColor(0xaaffffff); 10100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato canvas.drawRect(0, 0, getWidth(), getHeight(), p); 10200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 10300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato float scale = mAnimationScale; 10400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (scale < 0.999f) { // allow for some float error 10500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato float width = mBitmap.getWidth(); 10600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato float offset = (width-(width*scale))/2; 10700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato canvas.translate(offset, offset); 10800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato canvas.scale(scale, scale); 10900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 11000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); 11100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 11200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 11300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato @Override 11400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onDetachedFromWindow() { 11500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato super.onDetachedFromWindow(); 11600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mBitmap.recycle(); 11700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 11800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 11900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void onTweenValueChanged(float value, float oldValue) { 12000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mAnimationScale = (1.0f+((mScale-1.0f)*value))/mScale; 12100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato invalidate(); 12200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 12300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 12400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void onTweenStarted() { 12500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 12600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 12700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void onTweenFinished() { 12800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 12900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 13000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setPaint(Paint paint) { 13100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mPaint = paint; 13200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato invalidate(); 13300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 13400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 13500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 13600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Create a window containing this view and show it. 13700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 13800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param windowToken obtained from v.getWindowToken() from one of your views 13900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param touchX the x coordinate the user touched in screen coordinates 14000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param touchY the y coordinate the user touched in screen coordinates 14100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 14200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void show(IBinder windowToken, int touchX, int touchY) { 14300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato WindowManager.LayoutParams lp; 14400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int pixelFormat; 14500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 14600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato pixelFormat = PixelFormat.TRANSLUCENT; 14700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 14800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato lp = new WindowManager.LayoutParams( 14900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato ViewGroup.LayoutParams.WRAP_CONTENT, 15000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato ViewGroup.LayoutParams.WRAP_CONTENT, 15100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato touchX-mRegistrationX, touchY-mRegistrationY, 15200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, 15300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 15400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 15500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /*| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM*/, 15600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato pixelFormat); 15700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato// lp.token = mStatusBarView.getWindowToken(); 15800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato lp.gravity = Gravity.LEFT | Gravity.TOP; 15900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato lp.token = windowToken; 16000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato lp.setTitle("DragView"); 16100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mLayoutParams = lp; 16200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 16300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mWindowManager.addView(this, lp); 16400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 16500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mAnimationScale = 1.0f/mScale; 16600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mTween.start(true); 16700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 16800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 16900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 17000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Move the window containing this view. 17100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 17200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param touchX the x coordinate the user touched in screen coordinates 17300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @param touchY the y coordinate the user touched in screen coordinates 17400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 17500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato void move(int touchX, int touchY) { 17600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato WindowManager.LayoutParams lp = mLayoutParams; 17700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato lp.x = touchX - mRegistrationX; 17800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato lp.y = touchY - mRegistrationY; 17900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mWindowManager.updateViewLayout(this, lp); 18000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 18100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 18200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato void remove() { 18300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mWindowManager.removeView(this); 18400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 18500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato} 18600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 187