blob: a8dad7a4882b5f877f46d36b4c9621b62a2bfa13 [file] [log] [blame]
Joe Onorato00acb122009-08-04 16:04:30 -04001/*
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
Patrick Dubroya669d792010-11-23 14:40:33 -080020import android.animation.ValueAnimator;
21import android.animation.ValueAnimator.AnimatorUpdateListener;
Joe Onorato00acb122009-08-04 16:04:30 -040022import android.content.Context;
Patrick Dubroyde7658b2010-09-27 11:15:43 -070023import android.content.res.Resources;
Joe Onorato00acb122009-08-04 16:04:30 -040024import android.graphics.Bitmap;
25import android.graphics.Canvas;
26import android.graphics.Matrix;
27import android.graphics.Paint;
28import android.graphics.PixelFormat;
Joe Onorato00acb122009-08-04 16:04:30 -040029import android.os.IBinder;
Joe Onorato00acb122009-08-04 16:04:30 -040030import android.view.Gravity;
31import android.view.View;
32import android.view.ViewGroup;
Joe Onorato00acb122009-08-04 16:04:30 -040033import android.view.WindowManager;
34import android.view.WindowManagerImpl;
Patrick Dubroya669d792010-11-23 14:40:33 -080035import android.view.animation.DecelerateInterpolator;
Joe Onorato00acb122009-08-04 16:04:30 -040036
Adam Cohen120980b2010-12-08 11:05:37 -080037import com.android.launcher.R;
38
Patrick Dubroya669d792010-11-23 14:40:33 -080039public class DragView extends View {
Joe Onorato00acb122009-08-04 16:04:30 -040040 private Bitmap mBitmap;
41 private Paint mPaint;
42 private int mRegistrationX;
43 private int mRegistrationY;
44
Michael Jurkaa63c4522010-08-19 13:52:27 -070045 private int mDragRegionLeft = 0;
46 private int mDragRegionTop = 0;
47 private int mDragRegionWidth;
48 private int mDragRegionHeight;
49
Patrick Dubroya669d792010-11-23 14:40:33 -080050 ValueAnimator mAnim;
51 private float mScale = 1.0f;
52 private float mOffsetX = 0.0f;
53 private float mOffsetY = 0.0f;
Joe Onorato00acb122009-08-04 16:04:30 -040054
55 private WindowManager.LayoutParams mLayoutParams;
56 private WindowManager mWindowManager;
57
58 /**
Patrick Dubroya669d792010-11-23 14:40:33 -080059 * A callback to be called the first time this view is drawn.
60 * This allows the originator of the drag to dim or hide the original view as soon
61 * as the DragView is drawn.
62 */
63 private Runnable mOnDrawRunnable = null;
64
65 /**
Joe Onorato00acb122009-08-04 16:04:30 -040066 * Construct the drag view.
67 * <p>
68 * The registration point is the point inside our view that the touch events should
69 * be centered upon.
70 *
71 * @param context A context
72 * @param bitmap The view that we're dragging around. We scale it up when we draw it.
73 * @param registrationX The x coordinate of the registration point.
74 * @param registrationY The y coordinate of the registration point.
75 */
Joe Onorato5162ea92009-09-03 09:39:42 -070076 public DragView(Context context, Bitmap bitmap, int registrationX, int registrationY,
77 int left, int top, int width, int height) {
Joe Onorato00acb122009-08-04 16:04:30 -040078 super(context);
79
Patrick Dubroyde7658b2010-09-27 11:15:43 -070080 final Resources res = getResources();
81 final int dragScale = res.getInteger(R.integer.config_dragViewExtraPixels);
82
Joe Onorato00acb122009-08-04 16:04:30 -040083 mWindowManager = WindowManagerImpl.getDefault();
Joe Onorato00acb122009-08-04 16:04:30 -040084
Joe Onorato00acb122009-08-04 16:04:30 -040085 Matrix scale = new Matrix();
Patrick Dubroya669d792010-11-23 14:40:33 -080086 final float scaleFactor = (width + dragScale) / width;
87 if (scaleFactor != 1.0f) {
88 scale.setScale(scaleFactor, scaleFactor);
89 }
90
91 final int offsetX = res.getInteger(R.integer.config_dragViewOffsetX);
92 final int offsetY = res.getInteger(R.integer.config_dragViewOffsetY);
93
94 // Animate the view into the correct position
95 mAnim = ValueAnimator.ofFloat(0.0f, 1.0f);
96 mAnim.setDuration(110);
97 mAnim.setInterpolator(new DecelerateInterpolator(2.5f));
98 mAnim.addUpdateListener(new AnimatorUpdateListener() {
99 @Override
100 public void onAnimationUpdate(ValueAnimator animation) {
101 final float value = (Float) animation.getAnimatedValue();
102
103 final int deltaX = (int) ((value * offsetX) - mOffsetX);
104 final int deltaY = (int) ((value * offsetY) - mOffsetY);
105
106 mOffsetX += deltaX;
107 mOffsetY += deltaY;
108
109 if (getParent() == null) {
110 animation.cancel();
111 } else {
112 WindowManager.LayoutParams lp = mLayoutParams;
113 lp.x += deltaX;
114 lp.y += deltaY;
115 mWindowManager.updateViewLayout(DragView.this, lp);
116 }
117 }
118 });
Joe Onorato00acb122009-08-04 16:04:30 -0400119
Joe Onorato5162ea92009-09-03 09:39:42 -0700120 mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true);
Michael Jurka0280c3b2010-09-17 15:00:07 -0700121 setDragRegion(0, 0, width, height);
Joe Onorato00acb122009-08-04 16:04:30 -0400122
123 // The point in our scaled bitmap that the touch events are located
Patrick Dubroya669d792010-11-23 14:40:33 -0800124 mRegistrationX = registrationX;
125 mRegistrationY = registrationY;
Joe Onorato00acb122009-08-04 16:04:30 -0400126 }
127
Michael Jurkaa63c4522010-08-19 13:52:27 -0700128 public void setDragRegion(int left, int top, int width, int height) {
129 mDragRegionLeft = left;
130 mDragRegionTop = top;
131 mDragRegionWidth = width;
132 mDragRegionHeight = height;
133 }
134
Patrick Dubroya669d792010-11-23 14:40:33 -0800135 public void setOnDrawRunnable(Runnable r) {
136 mOnDrawRunnable = r;
137 }
138
Michael Jurka0280c3b2010-09-17 15:00:07 -0700139 public int getScaledDragRegionXOffset() {
140 return -(int)((mScale - 1.0f) * mDragRegionWidth / 2);
141 }
142
143 public int getScaledDragRegionWidth() {
144 return (int)(mScale * mDragRegionWidth);
145 }
146
147 public int getScaledDragRegionYOffset() {
148 return -(int)((mScale - 1.0f) * mDragRegionHeight / 2);
149 }
150
151 public int getScaledDragRegionHeight() {
152 return (int)(mScale * mDragRegionWidth);
153 }
154
Michael Jurkaa63c4522010-08-19 13:52:27 -0700155 public int getDragRegionLeft() {
156 return mDragRegionLeft;
157 }
158
159 public int getDragRegionTop() {
160 return mDragRegionTop;
161 }
162
163 public int getDragRegionWidth() {
164 return mDragRegionWidth;
165 }
166
167 public int getDragRegionHeight() {
168 return mDragRegionHeight;
169 }
170
Joe Onorato00acb122009-08-04 16:04:30 -0400171 @Override
172 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Joe Onoratoeebd9242009-11-04 13:48:32 -0500173 setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
Joe Onorato00acb122009-08-04 16:04:30 -0400174 }
175
176 @Override
177 protected void onDraw(Canvas canvas) {
178 if (false) {
179 // for debugging
180 Paint p = new Paint();
181 p.setStyle(Paint.Style.FILL);
182 p.setColor(0xaaffffff);
183 canvas.drawRect(0, 0, getWidth(), getHeight(), p);
184 }
Patrick Dubroya669d792010-11-23 14:40:33 -0800185
186 // Call the callback if we haven't already been detached
187 if (getParent() != null) {
188 if (mOnDrawRunnable != null) {
189 mOnDrawRunnable.run();
190 mOnDrawRunnable = null;
191 }
Joe Onorato00acb122009-08-04 16:04:30 -0400192 }
Patrick Dubroya669d792010-11-23 14:40:33 -0800193
Joe Onorato00acb122009-08-04 16:04:30 -0400194 canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
195 }
196
197 @Override
198 protected void onDetachedFromWindow() {
199 super.onDetachedFromWindow();
200 mBitmap.recycle();
201 }
202
Joe Onorato00acb122009-08-04 16:04:30 -0400203 public void setPaint(Paint paint) {
204 mPaint = paint;
205 invalidate();
206 }
207
208 /**
209 * Create a window containing this view and show it.
210 *
211 * @param windowToken obtained from v.getWindowToken() from one of your views
212 * @param touchX the x coordinate the user touched in screen coordinates
213 * @param touchY the y coordinate the user touched in screen coordinates
214 */
215 public void show(IBinder windowToken, int touchX, int touchY) {
216 WindowManager.LayoutParams lp;
217 int pixelFormat;
218
219 pixelFormat = PixelFormat.TRANSLUCENT;
220
221 lp = new WindowManager.LayoutParams(
222 ViewGroup.LayoutParams.WRAP_CONTENT,
223 ViewGroup.LayoutParams.WRAP_CONTENT,
Patrick Dubroya669d792010-11-23 14:40:33 -0800224 touchX - mRegistrationX, touchY - mRegistrationY,
Joe Onorato00acb122009-08-04 16:04:30 -0400225 WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
226 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
227 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
228 /*| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM*/,
229 pixelFormat);
230// lp.token = mStatusBarView.getWindowToken();
231 lp.gravity = Gravity.LEFT | Gravity.TOP;
232 lp.token = windowToken;
233 lp.setTitle("DragView");
234 mLayoutParams = lp;
235
236 mWindowManager.addView(this, lp);
237
Patrick Dubroya669d792010-11-23 14:40:33 -0800238 mAnim.start();
Joe Onorato00acb122009-08-04 16:04:30 -0400239 }
240
241 /**
242 * Move the window containing this view.
243 *
244 * @param touchX the x coordinate the user touched in screen coordinates
245 * @param touchY the y coordinate the user touched in screen coordinates
246 */
247 void move(int touchX, int touchY) {
248 WindowManager.LayoutParams lp = mLayoutParams;
Patrick Dubroya669d792010-11-23 14:40:33 -0800249 lp.x = touchX - mRegistrationX + (int) mOffsetX;
250 lp.y = touchY - mRegistrationY + (int) mOffsetY;
Joe Onorato00acb122009-08-04 16:04:30 -0400251 mWindowManager.updateViewLayout(this, lp);
252 }
253
254 void remove() {
255 mWindowManager.removeView(this);
256 }
257}
258