blob: 433dab8c68105e89345ea44139568a78bbad5e80 [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;
Patrick Dubroy62bbb3c2011-01-17 15:29:27 -0800126
127 // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass
128 int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
129 measure(ms, ms);
130 }
131
132 public float getOffsetY() {
133 return mOffsetY;
Joe Onorato00acb122009-08-04 16:04:30 -0400134 }
135
Michael Jurkaa63c4522010-08-19 13:52:27 -0700136 public void setDragRegion(int left, int top, int width, int height) {
137 mDragRegionLeft = left;
138 mDragRegionTop = top;
139 mDragRegionWidth = width;
140 mDragRegionHeight = height;
141 }
142
Patrick Dubroya669d792010-11-23 14:40:33 -0800143 public void setOnDrawRunnable(Runnable r) {
144 mOnDrawRunnable = r;
145 }
146
Michael Jurka0280c3b2010-09-17 15:00:07 -0700147 public int getScaledDragRegionXOffset() {
148 return -(int)((mScale - 1.0f) * mDragRegionWidth / 2);
149 }
150
151 public int getScaledDragRegionWidth() {
152 return (int)(mScale * mDragRegionWidth);
153 }
154
155 public int getScaledDragRegionYOffset() {
156 return -(int)((mScale - 1.0f) * mDragRegionHeight / 2);
157 }
158
159 public int getScaledDragRegionHeight() {
160 return (int)(mScale * mDragRegionWidth);
161 }
162
Michael Jurkaa63c4522010-08-19 13:52:27 -0700163 public int getDragRegionLeft() {
164 return mDragRegionLeft;
165 }
166
167 public int getDragRegionTop() {
168 return mDragRegionTop;
169 }
170
171 public int getDragRegionWidth() {
172 return mDragRegionWidth;
173 }
174
175 public int getDragRegionHeight() {
176 return mDragRegionHeight;
177 }
178
Joe Onorato00acb122009-08-04 16:04:30 -0400179 @Override
180 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Joe Onoratoeebd9242009-11-04 13:48:32 -0500181 setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
Joe Onorato00acb122009-08-04 16:04:30 -0400182 }
183
184 @Override
185 protected void onDraw(Canvas canvas) {
186 if (false) {
187 // for debugging
188 Paint p = new Paint();
189 p.setStyle(Paint.Style.FILL);
190 p.setColor(0xaaffffff);
191 canvas.drawRect(0, 0, getWidth(), getHeight(), p);
192 }
Patrick Dubroya669d792010-11-23 14:40:33 -0800193
194 // Call the callback if we haven't already been detached
195 if (getParent() != null) {
196 if (mOnDrawRunnable != null) {
197 mOnDrawRunnable.run();
198 mOnDrawRunnable = null;
199 }
Joe Onorato00acb122009-08-04 16:04:30 -0400200 }
Patrick Dubroya669d792010-11-23 14:40:33 -0800201
Joe Onorato00acb122009-08-04 16:04:30 -0400202 canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
203 }
204
205 @Override
206 protected void onDetachedFromWindow() {
207 super.onDetachedFromWindow();
208 mBitmap.recycle();
209 }
210
Joe Onorato00acb122009-08-04 16:04:30 -0400211 public void setPaint(Paint paint) {
212 mPaint = paint;
213 invalidate();
214 }
215
216 /**
217 * Create a window containing this view and show it.
218 *
219 * @param windowToken obtained from v.getWindowToken() from one of your views
220 * @param touchX the x coordinate the user touched in screen coordinates
221 * @param touchY the y coordinate the user touched in screen coordinates
222 */
223 public void show(IBinder windowToken, int touchX, int touchY) {
224 WindowManager.LayoutParams lp;
225 int pixelFormat;
226
227 pixelFormat = PixelFormat.TRANSLUCENT;
228
229 lp = new WindowManager.LayoutParams(
230 ViewGroup.LayoutParams.WRAP_CONTENT,
231 ViewGroup.LayoutParams.WRAP_CONTENT,
Patrick Dubroya669d792010-11-23 14:40:33 -0800232 touchX - mRegistrationX, touchY - mRegistrationY,
Joe Onorato00acb122009-08-04 16:04:30 -0400233 WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
234 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
235 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
236 /*| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM*/,
237 pixelFormat);
238// lp.token = mStatusBarView.getWindowToken();
239 lp.gravity = Gravity.LEFT | Gravity.TOP;
240 lp.token = windowToken;
241 lp.setTitle("DragView");
242 mLayoutParams = lp;
243
244 mWindowManager.addView(this, lp);
245
Patrick Dubroya669d792010-11-23 14:40:33 -0800246 mAnim.start();
Joe Onorato00acb122009-08-04 16:04:30 -0400247 }
248
249 /**
250 * Move the window containing this view.
251 *
252 * @param touchX the x coordinate the user touched in screen coordinates
253 * @param touchY the y coordinate the user touched in screen coordinates
254 */
255 void move(int touchX, int touchY) {
256 WindowManager.LayoutParams lp = mLayoutParams;
Patrick Dubroya669d792010-11-23 14:40:33 -0800257 lp.x = touchX - mRegistrationX + (int) mOffsetX;
258 lp.y = touchY - mRegistrationY + (int) mOffsetY;
Joe Onorato00acb122009-08-04 16:04:30 -0400259 mWindowManager.updateViewLayout(this, lp);
260 }
261
262 void remove() {
263 mWindowManager.removeView(this);
264 }
265}
266