blob: b02e22b16bff033c0386c4444db971cda5df3a20 [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;
Adam Cohene3e27a82011-04-15 12:07:39 -070029import android.graphics.Rect;
Joe Onorato00acb122009-08-04 16:04:30 -040030import android.os.IBinder;
Joe Onorato00acb122009-08-04 16:04:30 -040031import android.view.Gravity;
32import android.view.View;
33import android.view.ViewGroup;
Joe Onorato00acb122009-08-04 16:04:30 -040034import android.view.WindowManager;
35import android.view.WindowManagerImpl;
Patrick Dubroya669d792010-11-23 14:40:33 -080036import android.view.animation.DecelerateInterpolator;
Joe Onorato00acb122009-08-04 16:04:30 -040037
Adam Cohen120980b2010-12-08 11:05:37 -080038import com.android.launcher.R;
39
Patrick Dubroya669d792010-11-23 14:40:33 -080040public class DragView extends View {
Joe Onorato00acb122009-08-04 16:04:30 -040041 private Bitmap mBitmap;
42 private Paint mPaint;
43 private int mRegistrationX;
44 private int mRegistrationY;
45
Adam Cohene3e27a82011-04-15 12:07:39 -070046 private Rect mDragRegion = null;
Michael Jurkaa63c4522010-08-19 13:52:27 -070047
Patrick Dubroya669d792010-11-23 14:40:33 -080048 ValueAnimator mAnim;
Patrick Dubroya669d792010-11-23 14:40:33 -080049 private float mOffsetX = 0.0f;
50 private float mOffsetY = 0.0f;
Joe Onorato00acb122009-08-04 16:04:30 -040051
52 private WindowManager.LayoutParams mLayoutParams;
53 private WindowManager mWindowManager;
54
55 /**
Patrick Dubroya669d792010-11-23 14:40:33 -080056 * A callback to be called the first time this view is drawn.
57 * This allows the originator of the drag to dim or hide the original view as soon
58 * as the DragView is drawn.
59 */
60 private Runnable mOnDrawRunnable = null;
61
62 /**
Joe Onorato00acb122009-08-04 16:04:30 -040063 * Construct the drag view.
64 * <p>
65 * The registration point is the point inside our view that the touch events should
66 * be centered upon.
67 *
68 * @param context A context
69 * @param bitmap The view that we're dragging around. We scale it up when we draw it.
70 * @param registrationX The x coordinate of the registration point.
71 * @param registrationY The y coordinate of the registration point.
72 */
Joe Onorato5162ea92009-09-03 09:39:42 -070073 public DragView(Context context, Bitmap bitmap, int registrationX, int registrationY,
74 int left, int top, int width, int height) {
Joe Onorato00acb122009-08-04 16:04:30 -040075 super(context);
76
Patrick Dubroyde7658b2010-09-27 11:15:43 -070077 final Resources res = getResources();
78 final int dragScale = res.getInteger(R.integer.config_dragViewExtraPixels);
79
Joe Onorato00acb122009-08-04 16:04:30 -040080 mWindowManager = WindowManagerImpl.getDefault();
Joe Onorato00acb122009-08-04 16:04:30 -040081
Joe Onorato00acb122009-08-04 16:04:30 -040082 Matrix scale = new Matrix();
Patrick Dubroya669d792010-11-23 14:40:33 -080083 final float scaleFactor = (width + dragScale) / width;
84 if (scaleFactor != 1.0f) {
85 scale.setScale(scaleFactor, scaleFactor);
86 }
87
Adam Cohen8878a322011-03-28 13:18:42 -070088 final int offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX);
89 final int offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY);
Patrick Dubroya669d792010-11-23 14:40:33 -080090
91 // Animate the view into the correct position
92 mAnim = ValueAnimator.ofFloat(0.0f, 1.0f);
93 mAnim.setDuration(110);
94 mAnim.setInterpolator(new DecelerateInterpolator(2.5f));
95 mAnim.addUpdateListener(new AnimatorUpdateListener() {
96 @Override
97 public void onAnimationUpdate(ValueAnimator animation) {
98 final float value = (Float) animation.getAnimatedValue();
99
100 final int deltaX = (int) ((value * offsetX) - mOffsetX);
101 final int deltaY = (int) ((value * offsetY) - mOffsetY);
102
103 mOffsetX += deltaX;
104 mOffsetY += deltaY;
105
106 if (getParent() == null) {
107 animation.cancel();
108 } else {
109 WindowManager.LayoutParams lp = mLayoutParams;
110 lp.x += deltaX;
111 lp.y += deltaY;
112 mWindowManager.updateViewLayout(DragView.this, lp);
113 }
114 }
115 });
Joe Onorato00acb122009-08-04 16:04:30 -0400116
Joe Onorato5162ea92009-09-03 09:39:42 -0700117 mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true);
Adam Cohene3e27a82011-04-15 12:07:39 -0700118 setDragRegion(new Rect(0, 0, width, height));
Joe Onorato00acb122009-08-04 16:04:30 -0400119
120 // The point in our scaled bitmap that the touch events are located
Patrick Dubroya669d792010-11-23 14:40:33 -0800121 mRegistrationX = registrationX;
122 mRegistrationY = registrationY;
Patrick Dubroy62bbb3c2011-01-17 15:29:27 -0800123
124 // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass
125 int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
126 measure(ms, ms);
127 }
128
129 public float getOffsetY() {
130 return mOffsetY;
Joe Onorato00acb122009-08-04 16:04:30 -0400131 }
132
Patrick Dubroya669d792010-11-23 14:40:33 -0800133 public void setOnDrawRunnable(Runnable r) {
134 mOnDrawRunnable = r;
135 }
136
Michael Jurkaa63c4522010-08-19 13:52:27 -0700137 public int getDragRegionLeft() {
Adam Cohene3e27a82011-04-15 12:07:39 -0700138 return mDragRegion.left;
Michael Jurkaa63c4522010-08-19 13:52:27 -0700139 }
140
141 public int getDragRegionTop() {
Adam Cohene3e27a82011-04-15 12:07:39 -0700142 return mDragRegion.top;
Michael Jurkaa63c4522010-08-19 13:52:27 -0700143 }
144
145 public int getDragRegionWidth() {
Adam Cohene3e27a82011-04-15 12:07:39 -0700146 return mDragRegion.width();
Michael Jurkaa63c4522010-08-19 13:52:27 -0700147 }
148
149 public int getDragRegionHeight() {
Adam Cohene3e27a82011-04-15 12:07:39 -0700150 return mDragRegion.height();
151 }
152
153 public void setDragRegion(Rect r) {
154 mDragRegion = r;
155 }
156
157 public Rect getDragRegion() {
158 return mDragRegion;
Michael Jurkaa63c4522010-08-19 13:52:27 -0700159 }
160
Joe Onorato00acb122009-08-04 16:04:30 -0400161 @Override
162 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Joe Onoratoeebd9242009-11-04 13:48:32 -0500163 setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
Joe Onorato00acb122009-08-04 16:04:30 -0400164 }
165
166 @Override
167 protected void onDraw(Canvas canvas) {
168 if (false) {
169 // for debugging
170 Paint p = new Paint();
171 p.setStyle(Paint.Style.FILL);
172 p.setColor(0xaaffffff);
173 canvas.drawRect(0, 0, getWidth(), getHeight(), p);
174 }
Patrick Dubroya669d792010-11-23 14:40:33 -0800175
176 // Call the callback if we haven't already been detached
177 if (getParent() != null) {
178 if (mOnDrawRunnable != null) {
179 mOnDrawRunnable.run();
180 mOnDrawRunnable = null;
181 }
Joe Onorato00acb122009-08-04 16:04:30 -0400182 }
Patrick Dubroya669d792010-11-23 14:40:33 -0800183
Joe Onorato00acb122009-08-04 16:04:30 -0400184 canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
185 }
186
187 @Override
188 protected void onDetachedFromWindow() {
189 super.onDetachedFromWindow();
190 mBitmap.recycle();
191 }
192
Joe Onorato00acb122009-08-04 16:04:30 -0400193 public void setPaint(Paint paint) {
194 mPaint = paint;
195 invalidate();
196 }
197
198 /**
199 * Create a window containing this view and show it.
200 *
201 * @param windowToken obtained from v.getWindowToken() from one of your views
202 * @param touchX the x coordinate the user touched in screen coordinates
203 * @param touchY the y coordinate the user touched in screen coordinates
204 */
205 public void show(IBinder windowToken, int touchX, int touchY) {
206 WindowManager.LayoutParams lp;
207 int pixelFormat;
208
209 pixelFormat = PixelFormat.TRANSLUCENT;
210
211 lp = new WindowManager.LayoutParams(
212 ViewGroup.LayoutParams.WRAP_CONTENT,
213 ViewGroup.LayoutParams.WRAP_CONTENT,
Patrick Dubroya669d792010-11-23 14:40:33 -0800214 touchX - mRegistrationX, touchY - mRegistrationY,
Joe Onorato00acb122009-08-04 16:04:30 -0400215 WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
216 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
217 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
218 /*| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM*/,
219 pixelFormat);
220// lp.token = mStatusBarView.getWindowToken();
221 lp.gravity = Gravity.LEFT | Gravity.TOP;
222 lp.token = windowToken;
223 lp.setTitle("DragView");
224 mLayoutParams = lp;
225
226 mWindowManager.addView(this, lp);
227
Patrick Dubroya669d792010-11-23 14:40:33 -0800228 mAnim.start();
Joe Onorato00acb122009-08-04 16:04:30 -0400229 }
230
231 /**
232 * Move the window containing this view.
233 *
234 * @param touchX the x coordinate the user touched in screen coordinates
235 * @param touchY the y coordinate the user touched in screen coordinates
236 */
237 void move(int touchX, int touchY) {
238 WindowManager.LayoutParams lp = mLayoutParams;
Patrick Dubroya669d792010-11-23 14:40:33 -0800239 lp.x = touchX - mRegistrationX + (int) mOffsetX;
240 lp.y = touchY - mRegistrationY + (int) mOffsetY;
Joe Onorato00acb122009-08-04 16:04:30 -0400241 mWindowManager.updateViewLayout(this, lp);
242 }
243
244 void remove() {
245 mWindowManager.removeView(this);
246 }
Patrick Dubroy6f133422011-02-24 12:16:12 -0800247
248 int[] getPosition(int[] result) {
249 WindowManager.LayoutParams lp = mLayoutParams;
250 if (result == null) result = new int[2];
251 result[0] = lp.x;
252 result[1] = lp.y;
253 return result;
254 }
Joe Onorato00acb122009-08-04 16:04:30 -0400255}
256