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 18 package com.android.launcher2; 19 20 import android.animation.ValueAnimator; 21 import android.animation.ValueAnimator.AnimatorUpdateListener; 22 import android.content.res.Resources; 23 import android.graphics.Bitmap; 24 import android.graphics.Canvas; 25 import android.graphics.Matrix; 26 import android.graphics.Paint; 27 import android.graphics.Point; 28 import android.graphics.Rect; 29 import android.view.View; 30 import android.view.animation.DecelerateInterpolator; 31 32 import com.android.launcher.R; 33 34 public class DragView extends View { 35 private Bitmap mBitmap; 36 private Paint mPaint; 37 private int mRegistrationX; 38 private int mRegistrationY; 39 40 private Point mDragVisualizeOffset = null; 41 private Rect mDragRegion = null; 42 private DragLayer mDragLayer = null; 43 private boolean mHasDrawn = false; 44 45 ValueAnimator mAnim; 46 private float mOffsetX = 0.0f; 47 private float mOffsetY = 0.0f; 48 49 private DragLayer.LayoutParams mLayoutParams; 50 51 /** 52 * Construct the drag view. 53 * <p> 54 * The registration point is the point inside our view that the touch events should 55 * be centered upon. 56 * 57 * @param launcher The Launcher instance 58 * @param bitmap The view that we're dragging around. We scale it up when we draw it. 59 * @param registrationX The x coordinate of the registration point. 60 * @param registrationY The y coordinate of the registration point. 61 */ DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY, int left, int top, int width, int height)62 public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY, 63 int left, int top, int width, int height) { 64 super(launcher); 65 mDragLayer = launcher.getDragLayer(); 66 67 final Resources res = getResources(); 68 final int dragScale = res.getInteger(R.integer.config_dragViewExtraPixels); 69 70 Matrix scale = new Matrix(); 71 final float scaleFactor = (width + dragScale) / width; 72 if (scaleFactor != 1.0f) { 73 scale.setScale(scaleFactor, scaleFactor); 74 } 75 76 final int offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX); 77 final int offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY); 78 79 // Animate the view into the correct position 80 mAnim = ValueAnimator.ofFloat(0.0f, 1.0f); 81 mAnim.setDuration(110); 82 mAnim.setInterpolator(new DecelerateInterpolator(2.5f)); 83 mAnim.addUpdateListener(new AnimatorUpdateListener() { 84 @Override 85 public void onAnimationUpdate(ValueAnimator animation) { 86 final float value = (Float) animation.getAnimatedValue(); 87 88 final int deltaX = (int) ((value * offsetX) - mOffsetX); 89 final int deltaY = (int) ((value * offsetY) - mOffsetY); 90 91 mOffsetX += deltaX; 92 mOffsetY += deltaY; 93 94 if (getParent() == null) { 95 animation.cancel(); 96 } else { 97 DragLayer.LayoutParams lp = mLayoutParams; 98 lp.x += deltaX; 99 lp.y += deltaY; 100 mDragLayer.requestLayout(); 101 } 102 } 103 }); 104 105 mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true); 106 setDragRegion(new Rect(0, 0, width, height)); 107 108 // The point in our scaled bitmap that the touch events are located 109 mRegistrationX = registrationX; 110 mRegistrationY = registrationY; 111 112 // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass 113 int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 114 measure(ms, ms); 115 } 116 getOffsetY()117 public float getOffsetY() { 118 return mOffsetY; 119 } 120 getDragRegionLeft()121 public int getDragRegionLeft() { 122 return mDragRegion.left; 123 } 124 getDragRegionTop()125 public int getDragRegionTop() { 126 return mDragRegion.top; 127 } 128 getDragRegionWidth()129 public int getDragRegionWidth() { 130 return mDragRegion.width(); 131 } 132 getDragRegionHeight()133 public int getDragRegionHeight() { 134 return mDragRegion.height(); 135 } 136 setDragVisualizeOffset(Point p)137 public void setDragVisualizeOffset(Point p) { 138 mDragVisualizeOffset = p; 139 } 140 getDragVisualizeOffset()141 public Point getDragVisualizeOffset() { 142 return mDragVisualizeOffset; 143 } 144 setDragRegion(Rect r)145 public void setDragRegion(Rect r) { 146 mDragRegion = r; 147 } 148 getDragRegion()149 public Rect getDragRegion() { 150 return mDragRegion; 151 } 152 153 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)154 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 155 setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight()); 156 } 157 158 @Override onDraw(Canvas canvas)159 protected void onDraw(Canvas canvas) { 160 if (false) { 161 // for debugging 162 Paint p = new Paint(); 163 p.setStyle(Paint.Style.FILL); 164 p.setColor(0xaaffffff); 165 canvas.drawRect(0, 0, getWidth(), getHeight(), p); 166 } 167 168 mHasDrawn = true; 169 canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint); 170 } 171 setPaint(Paint paint)172 public void setPaint(Paint paint) { 173 mPaint = paint; 174 invalidate(); 175 } 176 hasDrawn()177 public boolean hasDrawn() { 178 return mHasDrawn; 179 } 180 181 @Override setAlpha(float alpha)182 public void setAlpha(float alpha) { 183 super.setAlpha(alpha); 184 if (mPaint == null) { 185 mPaint = new Paint(); 186 } 187 mPaint.setAlpha((int) (255 * alpha)); 188 invalidate(); 189 } 190 191 /** 192 * Create a window containing this view and show it. 193 * 194 * @param windowToken obtained from v.getWindowToken() from one of your views 195 * @param touchX the x coordinate the user touched in DragLayer coordinates 196 * @param touchY the y coordinate the user touched in DragLayer coordinates 197 */ show(int touchX, int touchY)198 public void show(int touchX, int touchY) { 199 mDragLayer.addView(this); 200 DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0); 201 lp.width = mBitmap.getWidth(); 202 lp.height = mBitmap.getHeight(); 203 lp.x = touchX - mRegistrationX; 204 lp.y = touchY - mRegistrationY; 205 lp.customPosition = true; 206 setLayoutParams(lp); 207 mLayoutParams = lp; 208 mAnim.start(); 209 } 210 211 /** 212 * Move the window containing this view. 213 * 214 * @param touchX the x coordinate the user touched in DragLayer coordinates 215 * @param touchY the y coordinate the user touched in DragLayer coordinates 216 */ move(int touchX, int touchY)217 void move(int touchX, int touchY) { 218 DragLayer.LayoutParams lp = mLayoutParams; 219 lp.x = touchX - mRegistrationX + (int) mOffsetX; 220 lp.y = touchY - mRegistrationY + (int) mOffsetY; 221 mDragLayer.requestLayout(); 222 } 223 remove()224 void remove() { 225 post(new Runnable() { 226 public void run() { 227 mDragLayer.removeView(DragView.this); 228 } 229 }); 230 } 231 getPosition(int[] result)232 int[] getPosition(int[] result) { 233 DragLayer.LayoutParams lp = mLayoutParams; 234 if (result == null) result = new int[2]; 235 result[0] = lp.x; 236 result[1] = lp.y; 237 return result; 238 } 239 } 240 241