DragView.java revision a63c452f5bd491ba9b28c332ccedc6c6c7e2f3cc
1/* 2 * Copyright (C) 2008 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 18package com.android.launcher2; 19 20import android.content.Context; 21import android.graphics.Bitmap; 22import android.graphics.Canvas; 23import android.graphics.Matrix; 24import android.graphics.Paint; 25import android.graphics.PixelFormat; 26import android.os.IBinder; 27import android.view.Gravity; 28import android.view.View; 29import android.view.ViewGroup; 30import android.view.WindowManager; 31import android.view.WindowManagerImpl; 32 33public class DragView extends View implements TweenCallback { 34 // Number of pixels to add to the dragged item for scaling. Should be even for pixel alignment. 35 private static final int DRAG_SCALE = 40; 36 37 private Bitmap mBitmap; 38 private Paint mPaint; 39 private int mRegistrationX; 40 private int mRegistrationY; 41 42 private int mDragRegionLeft = 0; 43 private int mDragRegionTop = 0; 44 private int mDragRegionWidth; 45 private int mDragRegionHeight; 46 47 SymmetricalLinearTween mTween; 48 private float mScale; 49 private float mAnimationScale = 1.0f; 50 51 private WindowManager.LayoutParams mLayoutParams; 52 private WindowManager mWindowManager; 53 54 /** 55 * Construct the drag view. 56 * <p> 57 * The registration point is the point inside our view that the touch events should 58 * be centered upon. 59 * 60 * @param context A context 61 * @param bitmap The view that we're dragging around. We scale it up when we draw it. 62 * @param registrationX The x coordinate of the registration point. 63 * @param registrationY The y coordinate of the registration point. 64 */ 65 public DragView(Context context, Bitmap bitmap, int registrationX, int registrationY, 66 int left, int top, int width, int height) { 67 super(context); 68 69 mWindowManager = WindowManagerImpl.getDefault(); 70 71 mTween = new SymmetricalLinearTween(false, 110 /*ms duration*/, this); 72 73 Matrix scale = new Matrix(); 74 float scaleFactor = width; 75 scaleFactor = mScale = (scaleFactor + DRAG_SCALE) / scaleFactor; 76 scale.setScale(scaleFactor, scaleFactor); 77 78 mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true); 79 mDragRegionWidth = width; 80 mDragRegionHeight = height; 81 82 // The point in our scaled bitmap that the touch events are located 83 mRegistrationX = registrationX + (DRAG_SCALE / 2); 84 mRegistrationY = registrationY + (DRAG_SCALE / 2); 85 } 86 87 public void setDragRegion(int left, int top, int width, int height) { 88 mDragRegionLeft = left; 89 mDragRegionTop = top; 90 mDragRegionWidth = width; 91 mDragRegionHeight = height; 92 } 93 94 public int getDragRegionLeft() { 95 return mDragRegionLeft; 96 } 97 98 public int getDragRegionTop() { 99 return mDragRegionTop; 100 } 101 102 public int getDragRegionWidth() { 103 return mDragRegionWidth; 104 } 105 106 public int getDragRegionHeight() { 107 return mDragRegionHeight; 108 } 109 110 @Override 111 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 112 setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight()); 113 } 114 115 @Override 116 protected void onDraw(Canvas canvas) { 117 if (false) { 118 // for debugging 119 Paint p = new Paint(); 120 p.setStyle(Paint.Style.FILL); 121 p.setColor(0xaaffffff); 122 canvas.drawRect(0, 0, getWidth(), getHeight(), p); 123 } 124 float scale = mAnimationScale; 125 if (scale < 0.999f) { // allow for some float error 126 float width = mBitmap.getWidth(); 127 float offset = (width-(width*scale))/2; 128 canvas.translate(offset, offset); 129 canvas.scale(scale, scale); 130 } 131 canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); 132 } 133 134 @Override 135 protected void onDetachedFromWindow() { 136 super.onDetachedFromWindow(); 137 mBitmap.recycle(); 138 } 139 140 public void onTweenValueChanged(float value, float oldValue) { 141 mAnimationScale = (1.0f+((mScale-1.0f)*value))/mScale; 142 invalidate(); 143 } 144 145 public void onTweenStarted() { 146 } 147 148 public void onTweenFinished() { 149 } 150 151 public void setPaint(Paint paint) { 152 mPaint = paint; 153 invalidate(); 154 } 155 156 /** 157 * Create a window containing this view and show it. 158 * 159 * @param windowToken obtained from v.getWindowToken() from one of your views 160 * @param touchX the x coordinate the user touched in screen coordinates 161 * @param touchY the y coordinate the user touched in screen coordinates 162 */ 163 public void show(IBinder windowToken, int touchX, int touchY) { 164 WindowManager.LayoutParams lp; 165 int pixelFormat; 166 167 pixelFormat = PixelFormat.TRANSLUCENT; 168 169 lp = new WindowManager.LayoutParams( 170 ViewGroup.LayoutParams.WRAP_CONTENT, 171 ViewGroup.LayoutParams.WRAP_CONTENT, 172 touchX-mRegistrationX, touchY-mRegistrationY, 173 WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, 174 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 175 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 176 /*| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM*/, 177 pixelFormat); 178// lp.token = mStatusBarView.getWindowToken(); 179 lp.gravity = Gravity.LEFT | Gravity.TOP; 180 lp.token = windowToken; 181 lp.setTitle("DragView"); 182 mLayoutParams = lp; 183 184 mWindowManager.addView(this, lp); 185 186 mAnimationScale = 1.0f/mScale; 187 mTween.start(true); 188 } 189 190 /** 191 * Move the window containing this view. 192 * 193 * @param touchX the x coordinate the user touched in screen coordinates 194 * @param touchY the y coordinate the user touched in screen coordinates 195 */ 196 void move(int touchX, int touchY) { 197 WindowManager.LayoutParams lp = mLayoutParams; 198 lp.x = touchX - mRegistrationX; 199 lp.y = touchY - mRegistrationY; 200 mWindowManager.updateViewLayout(this, lp); 201 } 202 203 void remove() { 204 mWindowManager.removeView(this); 205 } 206} 207 208