blob: c2b710ec79ed197ed8b19859aabc2db5d4fdfb75 [file] [log] [blame]
The Android Open Source Project31dd5032009-03-03 19:32:27 -08001/*
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
Joe Onoratoa5902522009-07-30 13:37:37 -070017package com.android.launcher2;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080018
Adam Cohen67882692011-03-11 15:29:03 -080019import java.util.ArrayList;
Adam Cohend4844c32011-02-18 19:25:06 -080020
The Android Open Source Project31dd5032009-03-03 19:32:27 -080021import android.content.Context;
Adam Cohen120980b2010-12-08 11:05:37 -080022import android.graphics.Bitmap;
Adam Cohen67882692011-03-11 15:29:03 -080023import android.graphics.Rect;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080024import android.util.AttributeSet;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080025import android.view.KeyEvent;
Michael Jurka0e260592010-06-30 17:07:39 -070026import android.view.MotionEvent;
Romain Guyea3763c2010-01-11 18:02:04 -080027import android.view.View;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080028import android.widget.FrameLayout;
Adam Cohen120980b2010-12-08 11:05:37 -080029import android.widget.ImageView;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080030
Adam Cohen67882692011-03-11 15:29:03 -080031import com.android.launcher.R;
32
The Android Open Source Project31dd5032009-03-03 19:32:27 -080033/**
Michael Jurka0e260592010-06-30 17:07:39 -070034 * A ViewGroup that coordinates dragging across its descendants
The Android Open Source Project31dd5032009-03-03 19:32:27 -080035 */
Joe Onorato00acb122009-08-04 16:04:30 -040036public class DragLayer extends FrameLayout {
Adam Cohen120980b2010-12-08 11:05:37 -080037 private DragController mDragController;
38 private int[] mTmpXY = new int[2];
The Android Open Source Project31dd5032009-03-03 19:32:27 -080039
Adam Cohen67882692011-03-11 15:29:03 -080040 // Variables relating to resizing widgets
41 private final ArrayList<AppWidgetResizeFrame> mResizeFrames =
42 new ArrayList<AppWidgetResizeFrame>();
43 private AppWidgetResizeFrame mCurrentResizeFrame;
44 private int mXDown, mYDown;
45
The Android Open Source Project31dd5032009-03-03 19:32:27 -080046 /**
47 * Used to create a new DragLayer from XML.
48 *
49 * @param context The application's context.
Michael Jurka0e260592010-06-30 17:07:39 -070050 * @param attrs The attributes set containing the Workspace's customization values.
The Android Open Source Project31dd5032009-03-03 19:32:27 -080051 */
52 public DragLayer(Context context, AttributeSet attrs) {
53 super(context, attrs);
Winson Chungbe62afa2011-02-03 23:14:57 -080054
55 // Disable multitouch across the workspace/all apps/customize tray
56 setMotionEventSplittingEnabled(false);
The Android Open Source Project31dd5032009-03-03 19:32:27 -080057 }
58
Joe Onorato00acb122009-08-04 16:04:30 -040059 public void setDragController(DragController controller) {
60 mDragController = controller;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080061 }
Joe Onorato00acb122009-08-04 16:04:30 -040062
The Android Open Source Project31dd5032009-03-03 19:32:27 -080063 @Override
64 public boolean dispatchKeyEvent(KeyEvent event) {
Joe Onorato00acb122009-08-04 16:04:30 -040065 return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
The Android Open Source Project31dd5032009-03-03 19:32:27 -080066 }
67
Adam Cohen67882692011-03-11 15:29:03 -080068 private boolean handleTouchDown(MotionEvent ev) {
69 Rect hitRect = new Rect();
70 int x = (int) ev.getX();
71 int y = (int) ev.getY();
Adam Cohen1b607ed2011-03-03 17:26:50 -080072
Adam Cohen67882692011-03-11 15:29:03 -080073 for (AppWidgetResizeFrame child: mResizeFrames) {
74 child.getHitRect(hitRect);
75 if (hitRect.contains(x, y)) {
76 if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
77 mCurrentResizeFrame = child;
78 mXDown = x;
79 mYDown = y;
80 requestDisallowInterceptTouchEvent(true);
81 return true;
82 }
Patrick Dubroyd1837cc2011-03-07 13:38:54 -080083 }
Adam Cohen1b607ed2011-03-03 17:26:50 -080084 }
Adam Cohen67882692011-03-11 15:29:03 -080085 return false;
86 }
87
88 @Override
89 public boolean onInterceptTouchEvent(MotionEvent ev) {
90 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
91 if (handleTouchDown(ev)) {
92 return true;
93 }
94 }
95 clearAllResizeFrames();
Joe Onorato4db52312009-10-06 11:17:43 -070096 return mDragController.onInterceptTouchEvent(ev);
The Android Open Source Project31dd5032009-03-03 19:32:27 -080097 }
98
99 @Override
100 public boolean onTouchEvent(MotionEvent ev) {
Adam Cohen67882692011-03-11 15:29:03 -0800101 boolean handled = false;
102 int action = ev.getAction();
103
104 int x = (int) ev.getX();
105 int y = (int) ev.getY();
106
107 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
108 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
109 if (handleTouchDown(ev)) {
110 return true;
111 }
112 }
113 }
114
115 if (mCurrentResizeFrame != null) {
116 handled = true;
117 switch (action) {
118 case MotionEvent.ACTION_MOVE:
119 mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown);
120 break;
121 case MotionEvent.ACTION_CANCEL:
122 case MotionEvent.ACTION_UP:
123 mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown);
124 mCurrentResizeFrame = null;
125 }
126 }
127 if (handled) return true;
Joe Onorato4db52312009-10-06 11:17:43 -0700128 return mDragController.onTouchEvent(ev);
Romain Guy91a9c962009-06-12 13:52:17 -0700129 }
Romain Guyea3763c2010-01-11 18:02:04 -0800130
131 @Override
132 public boolean dispatchUnhandledMove(View focused, int direction) {
133 return mDragController.dispatchUnhandledMove(focused, direction);
134 }
Adam Cohen120980b2010-12-08 11:05:37 -0800135
136 public View createDragView(Bitmap b, int xPos, int yPos) {
137 ImageView imageView = new ImageView(mContext);
138 imageView.setImageBitmap(b);
139 imageView.setX(xPos);
140 imageView.setY(yPos);
141 addView(imageView, b.getWidth(), b.getHeight());
142
143 return imageView;
144 }
145
146 public View createDragView(View v) {
147 v.getLocationOnScreen(mTmpXY);
148 return createDragView(mDragController.getViewBitmap(v), mTmpXY[0], mTmpXY[1]);
149 }
Adam Cohen67882692011-03-11 15:29:03 -0800150
151 public static class LayoutParams extends FrameLayout.LayoutParams {
152 public int x, y;
153 public boolean customPosition = false;
154
155 /**
156 * {@inheritDoc}
157 */
158 public LayoutParams(int width, int height) {
159 super(width, height);
160 }
161
162 public void setWidth(int width) {
163 this.width = width;
164 }
165
166 public int getWidth() {
167 return width;
168 }
169
170 public void setHeight(int height) {
171 this.height = height;
172 }
173
174 public int getHeight() {
175 return height;
176 }
177
178 public void setX(int x) {
179 this.x = x;
180 }
181
182 public int getX() {
183 return x;
184 }
185
186 public void setY(int y) {
187 this.y = y;
188 }
189
190 public int getY() {
191 return y;
192 }
193 }
194
195 protected void onLayout(boolean changed, int l, int t, int r, int b) {
196 super.onLayout(changed, l, t, r, b);
197 int count = getChildCount();
198 for (int i = 0; i < count; i++) {
199 View child = getChildAt(i);
200 final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
201 if (flp instanceof LayoutParams) {
202 final LayoutParams lp = (LayoutParams) flp;
203 if (lp.customPosition) {
204 child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height);
205 }
206 }
207 }
208 }
209
210 public void clearAllResizeFrames() {
211 if (mResizeFrames.size() > 0) {
212 for (AppWidgetResizeFrame frame: mResizeFrames) {
213 removeView(frame);
214 }
215 mResizeFrames.clear();
216 }
217 }
218
219 public boolean hasResizeFrames() {
220 return mResizeFrames.size() > 0;
221 }
222
223 public boolean isWidgetBeingResized() {
224 return mCurrentResizeFrame != null;
225 }
226
227 public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget,
228 CellLayout cellLayout) {
229 AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(),
230 itemInfo, widget, cellLayout, this);
231
232 LayoutParams lp = new LayoutParams(-1, -1);
233 lp.customPosition = true;
234
235 addView(resizeFrame, lp);
236 mResizeFrames.add(resizeFrame);
237
238 resizeFrame.snapToWidget(false);
239 }
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800240}