DragLayer.java revision 2801cafe62653131fdc9da402e5c44e5ffd0bf47
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 17package com.android.launcher2; 18 19import java.util.ArrayList; 20 21import android.content.Context; 22import android.graphics.Bitmap; 23import android.graphics.Rect; 24import android.util.AttributeSet; 25import android.view.KeyEvent; 26import android.view.MotionEvent; 27import android.view.View; 28import android.widget.FrameLayout; 29import android.widget.ImageView; 30 31import com.android.launcher.R; 32 33/** 34 * A ViewGroup that coordinates dragging across its descendants 35 */ 36public class DragLayer extends FrameLayout { 37 private DragController mDragController; 38 private int[] mTmpXY = new int[2]; 39 40 // 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 private Folder mCurrentFolder = null; 46 private Launcher mLauncher; 47 48 /** 49 * Used to create a new DragLayer from XML. 50 * 51 * @param context The application's context. 52 * @param attrs The attributes set containing the Workspace's customization values. 53 */ 54 public DragLayer(Context context, AttributeSet attrs) { 55 super(context, attrs); 56 57 // Disable multitouch across the workspace/all apps/customize tray 58 setMotionEventSplittingEnabled(false); 59 } 60 61 public void setDragController(DragController controller) { 62 mDragController = controller; 63 } 64 65 @Override 66 public boolean dispatchKeyEvent(KeyEvent event) { 67 return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); 68 } 69 70 private boolean handleTouchDown(MotionEvent ev) { 71 Rect hitRect = new Rect(); 72 int x = (int) ev.getX(); 73 int y = (int) ev.getY(); 74 75 for (AppWidgetResizeFrame child: mResizeFrames) { 76 child.getHitRect(hitRect); 77 if (hitRect.contains(x, y)) { 78 if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) { 79 mCurrentResizeFrame = child; 80 mXDown = x; 81 mYDown = y; 82 requestDisallowInterceptTouchEvent(true); 83 return true; 84 } 85 } 86 } 87 if (mCurrentFolder != null) { 88 mCurrentFolder.getHitRect(hitRect); 89 int[] screenPos = new int[2]; 90 View parent = (View) mCurrentFolder.getParent(); 91 if (parent != null) { 92 parent.getLocationOnScreen(screenPos); 93 hitRect.offset(screenPos[0], screenPos[1]); 94 if (!hitRect.contains(x, y)) { 95 mLauncher.closeFolder(); 96 } 97 } 98 } 99 return false; 100 } 101 102 @Override 103 public boolean onInterceptTouchEvent(MotionEvent ev) { 104 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 105 if (handleTouchDown(ev)) { 106 return true; 107 } 108 } 109 clearAllResizeFrames(); 110 return mDragController.onInterceptTouchEvent(ev); 111 } 112 113 @Override 114 public boolean onTouchEvent(MotionEvent ev) { 115 boolean handled = false; 116 int action = ev.getAction(); 117 118 int x = (int) ev.getX(); 119 int y = (int) ev.getY(); 120 121 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 122 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 123 if (handleTouchDown(ev)) { 124 return true; 125 } 126 } 127 } 128 129 if (mCurrentResizeFrame != null) { 130 handled = true; 131 switch (action) { 132 case MotionEvent.ACTION_MOVE: 133 mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); 134 break; 135 case MotionEvent.ACTION_CANCEL: 136 case MotionEvent.ACTION_UP: 137 mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown); 138 mCurrentResizeFrame = null; 139 } 140 } 141 if (handled) return true; 142 return mDragController.onTouchEvent(ev); 143 } 144 145 @Override 146 public boolean dispatchUnhandledMove(View focused, int direction) { 147 return mDragController.dispatchUnhandledMove(focused, direction); 148 } 149 150 public View createDragView(Bitmap b, int xPos, int yPos) { 151 ImageView imageView = new ImageView(mContext); 152 imageView.setImageBitmap(b); 153 imageView.setX(xPos); 154 imageView.setY(yPos); 155 addView(imageView, b.getWidth(), b.getHeight()); 156 157 return imageView; 158 } 159 160 public View createDragView(View v) { 161 v.getLocationOnScreen(mTmpXY); 162 return createDragView(mDragController.getViewBitmap(v), mTmpXY[0], mTmpXY[1]); 163 } 164 165 public static class LayoutParams extends FrameLayout.LayoutParams { 166 public int x, y; 167 public boolean customPosition = false; 168 169 /** 170 * {@inheritDoc} 171 */ 172 public LayoutParams(int width, int height) { 173 super(width, height); 174 } 175 176 public void setWidth(int width) { 177 this.width = width; 178 } 179 180 public int getWidth() { 181 return width; 182 } 183 184 public void setHeight(int height) { 185 this.height = height; 186 } 187 188 public int getHeight() { 189 return height; 190 } 191 192 public void setX(int x) { 193 this.x = x; 194 } 195 196 public int getX() { 197 return x; 198 } 199 200 public void setY(int y) { 201 this.y = y; 202 } 203 204 public int getY() { 205 return y; 206 } 207 } 208 209 protected void onLayout(boolean changed, int l, int t, int r, int b) { 210 super.onLayout(changed, l, t, r, b); 211 int count = getChildCount(); 212 for (int i = 0; i < count; i++) { 213 View child = getChildAt(i); 214 final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams(); 215 if (flp instanceof LayoutParams) { 216 final LayoutParams lp = (LayoutParams) flp; 217 if (lp.customPosition) { 218 child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height); 219 } 220 } 221 } 222 } 223 224 public void clearAllResizeFrames() { 225 if (mResizeFrames.size() > 0) { 226 for (AppWidgetResizeFrame frame: mResizeFrames) { 227 removeView(frame); 228 } 229 mResizeFrames.clear(); 230 } 231 } 232 233 public boolean hasResizeFrames() { 234 return mResizeFrames.size() > 0; 235 } 236 237 public boolean isWidgetBeingResized() { 238 return mCurrentResizeFrame != null; 239 } 240 241 public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget, 242 CellLayout cellLayout) { 243 AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(), 244 itemInfo, widget, cellLayout, this); 245 246 LayoutParams lp = new LayoutParams(-1, -1); 247 lp.customPosition = true; 248 249 addView(resizeFrame, lp); 250 mResizeFrames.add(resizeFrame); 251 252 resizeFrame.snapToWidget(false); 253 } 254 255 public void setLauncher(Launcher l) { 256 mLauncher = l; 257 } 258 259 public void setCurrentFolder(Folder f) { 260 mCurrentFolder = f; 261 } 262} 263