DragLayer.java revision 31dd503c6aa69018e694d91724d46db49ea09327
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpackage com.android.launcher; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas; 2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Matrix; 2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Rect; 2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.RectF; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Paint; 2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.PorterDuffColorFilter; 2731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.PorterDuff; 2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Vibrator; 2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.SystemClock; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.MotionEvent; 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View; 3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.ViewGroup; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.KeyEvent; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.inputmethod.InputMethodManager; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.FrameLayout; 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * A ViewGroup that coordinated dragging across its dscendants 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpublic class DragLayer extends FrameLayout implements DragController { 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int SCROLL_DELAY = 600; 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int SCROLL_ZONE = 20; 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int VIBRATE_DURATION = 35; 4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int ANIMATION_SCALE_UP_DURATION = 110; 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final boolean PROFILE_DRAWING_DURING_DRAG = false; 4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Number of pixels to add to the dragged item for scaling 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final float DRAG_SCALE = 24.0f; 5131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mDragging = false; 5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mShouldDrop; 5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private float mLastMotionX; 5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private float mLastMotionY; 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 5831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The bitmap that is currently being dragged 5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Bitmap mDragBitmap = null; 6131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private View mOriginator; 6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mBitmapOffsetX; 6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mBitmapOffsetY; 6531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * X offset from where we touched on the cell to its upper-left corner 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private float mTouchOffsetX; 7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Y offset from where we touched on the cell to its upper-left corner 7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private float mTouchOffsetY; 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Utility rectangle 7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Rect mDragRect = new Rect(); 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Where the drag originated 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private DragSource mDragSource; 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The data associated with the object being dragged 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Object mDragInfo; 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final Rect mRect = new Rect(); 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final int[] mDropCoordinates = new int[2]; 9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final Vibrator mVibrator = new Vibrator(); 9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private DragListener mListener; 9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private DragScroller mDragScroller; 9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int SCROLL_OUTSIDE_ZONE = 0; 10131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int SCROLL_WAITING_IN_ZONE = 1; 10231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int SCROLL_LEFT = 0; 10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int SCROLL_RIGHT = 1; 10531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mScrollState = SCROLL_OUTSIDE_ZONE; 10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private ScrollRunnable mScrollRunnable = new ScrollRunnable(); 10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private View mIgnoredDropTarget; 11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private RectF mDragRegion; 11231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mEnteredRegion; 11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private DropTarget mLastDropTarget; 11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final Paint mTrashPaint = new Paint(); 11631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Paint mDragPaint; 11731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int ANIMATION_STATE_STARTING = 1; 11931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int ANIMATION_STATE_RUNNING = 2; 12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int ANIMATION_STATE_DONE = 3; 12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int ANIMATION_TYPE_SCALE = 1; 12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private float mAnimationFrom; 12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private float mAnimationTo; 12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mAnimationDuration; 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private long mAnimationStartTime; 12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mAnimationType; 12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mAnimationState = ANIMATION_STATE_DONE; 13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private InputMethodManager mInputMethodManager; 13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to create a new DragLayer from XML. 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param attrs The attribtues set containing the Workspace's customization values. 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public DragLayer(Context context, AttributeSet attrs) { 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int srcColor = context.getResources().getColor(R.color.delete_color_filter); 14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mTrashPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP)); 14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void startDrag(View v, DragSource source, Object dragInfo, int dragAction) { 14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (PROFILE_DRAWING_DURING_DRAG) { 14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project android.os.Debug.startMethodTracing("Launcher"); 14931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Hide soft keyboard, if visible 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mInputMethodManager == null) { 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mInputMethodManager = (InputMethodManager) 15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mListener != null) { 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mListener.onDragStart(v, source, dragInfo, dragAction); 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Rect r = mDragRect; 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project r.set(v.getScrollX(), v.getScrollY(), 0, 0); 16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project offsetDescendantRectToMyCoords(v, r); 16631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mTouchOffsetX = mLastMotionX - r.left; 16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mTouchOffsetY = mLastMotionY - r.top; 16831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project v.clearFocus(); 17031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project v.setPressed(false); 17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean willNotCache = v.willNotCacheDrawing(); 17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project v.setWillNotCacheDrawing(false); 17431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project v.buildDrawingCache(); 17531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Bitmap viewBitmap = v.getDrawingCache(); 17731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int width = viewBitmap.getWidth(); 17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int height = viewBitmap.getHeight(); 17931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Matrix scale = new Matrix(); 18131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project float scaleFactor = v.getWidth(); 18231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project scaleFactor = (scaleFactor + DRAG_SCALE) /scaleFactor; 18331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project scale.setScale(scaleFactor, scaleFactor); 18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationTo = 1.0f; 18631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationFrom = 1.0f / scaleFactor; 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationDuration = ANIMATION_SCALE_UP_DURATION; 18831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationState = ANIMATION_STATE_STARTING; 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationType = ANIMATION_TYPE_SCALE; 19031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragBitmap = Bitmap.createBitmap(viewBitmap, 0, 0, width, height, scale, true); 19231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project v.destroyDrawingCache(); 19331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project v.setWillNotCacheDrawing(willNotCache); 19431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap dragBitmap = mDragBitmap; 19631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mBitmapOffsetX = (dragBitmap.getWidth() - width) / 2; 19731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mBitmapOffsetY = (dragBitmap.getHeight() - height) / 2; 19831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (dragAction == DRAG_ACTION_MOVE) { 20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project v.setVisibility(GONE); 20131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 20231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 20331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragPaint = null; 20431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragging = true; 20531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mShouldDrop = true; 20631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mOriginator = v; 20731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragSource = source; 20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = dragInfo; 20931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mVibrator.vibrate(VIBRATE_DURATION); 21131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mEnteredRegion = false; 21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project invalidate(); 21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 21631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 21831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mDragging || super.dispatchKeyEvent(event); 22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected void dispatchDraw(Canvas canvas) { 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.dispatchDraw(canvas); 22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDragging && mDragBitmap != null) { 22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mAnimationState == ANIMATION_STATE_STARTING) { 22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationStartTime = SystemClock.uptimeMillis(); 22931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationState = ANIMATION_STATE_RUNNING; 23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mAnimationState == ANIMATION_STATE_RUNNING) { 23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project float normalized = (float) (SystemClock.uptimeMillis() - mAnimationStartTime) / 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationDuration; 23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (normalized >= 1.0f) { 23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAnimationState = ANIMATION_STATE_DONE; 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project normalized = Math.min(normalized, 1.0f); 23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float value = mAnimationFrom + (mAnimationTo - mAnimationFrom) * normalized; 24031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 24131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project switch (mAnimationType) { 24231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case ANIMATION_TYPE_SCALE: 24331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap dragBitmap = mDragBitmap; 24431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.save(); 24531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.translate(mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, 24631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY); 24731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.translate((dragBitmap.getWidth() * (1.0f - value)) / 2, 24831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (dragBitmap.getHeight() * (1.0f - value)) / 2); 24931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.scale(value, value); 25031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint); 25131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.restore(); 25231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.drawBitmap(mDragBitmap, 25631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, 25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY, mDragPaint); 25831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void endDrag() { 26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDragging) { 26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragging = false; 26531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDragBitmap != null) { 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragBitmap.recycle(); 26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mOriginator != null) { 26931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mOriginator.setVisibility(VISIBLE); 27031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mListener != null) { 27231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mListener.onDragEnd(); 27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent ev) { 27931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int action = ev.getAction(); 28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float x = ev.getX(); 28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float y = ev.getY(); 28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project switch (action) { 28531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_MOVE: 28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_DOWN: 28931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Remember location of down touch 29031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastMotionX = x; 29131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastMotionY = y; 29231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastDropTarget = null; 29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_CANCEL: 29631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_UP: 29731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mShouldDrop && drop(x, y)) { 29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mShouldDrop = false; 29931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project endDrag(); 30131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 30231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mDragging; 30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 30831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 30931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!mDragging) { 31031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 31131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 31231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 31331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int action = ev.getAction(); 31431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float x = ev.getX(); 31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float y = ev.getY(); 31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 31731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project switch (action) { 31831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_DOWN: 31931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 32031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Remember where the motion event started 32131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastMotionX = x; 32231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastMotionY = y; 32331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if ((x < SCROLL_ZONE) || (x > getWidth() - SCROLL_ZONE)) { 32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollState = SCROLL_WAITING_IN_ZONE; 32631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project postDelayed(mScrollRunnable, SCROLL_DELAY); 32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 32831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollState = SCROLL_OUTSIDE_ZONE; 32931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 33131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 33231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_MOVE: 33331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int scrollX = mScrollX; 33431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int scrollY = mScrollY; 33531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 33631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float touchX = mTouchOffsetX; 33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final float touchY = mTouchOffsetY; 33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 33931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int offsetX = mBitmapOffsetX; 34031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int offsetY = mBitmapOffsetY; 34131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 34231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int left = (int) (scrollX + mLastMotionX - touchX - offsetX); 34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int top = (int) (scrollY + mLastMotionY - touchY - offsetY); 34431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 34531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Bitmap dragBitmap = mDragBitmap; 34631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int width = dragBitmap.getWidth(); 34731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int height = dragBitmap.getHeight(); 34831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 34931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Rect rect = mRect; 35031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project rect.set(left - 1, top - 1, left + width + 1, top + height + 1); 35131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 35231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastMotionX = x; 35331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastMotionY = y; 35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 35531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project left = (int) (scrollX + x - touchX - offsetX); 35631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project top = (int) (scrollY + y - touchY - offsetY); 35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 35831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project rect.union(left - 1, top - 1, left + width + 1, top + height + 1); 35931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project invalidate(rect); 36031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 36131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int[] coordinates = mDropCoordinates; 36231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); 36331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (dropTarget != null) { 36431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mLastDropTarget == dropTarget) { 36531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1], 36631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); 36731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 36831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mLastDropTarget != null) { 36931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], 37031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); 37131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 37231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1], 37331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); 37431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 37531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 37631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mLastDropTarget != null) { 37731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], 37831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); 37931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 38031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 38131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLastDropTarget = dropTarget; 38231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 38331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean inDragRegion = false; 38431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDragRegion != null) { 38531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final RectF region = mDragRegion; 38631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final boolean inRegion = region.contains(ev.getRawX(), ev.getRawY()); 38731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!mEnteredRegion && inRegion) { 38831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragPaint = mTrashPaint; 38931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mEnteredRegion = true; 39031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project inDragRegion = true; 39131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (mEnteredRegion && !inRegion) { 39231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragPaint = null; 39331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mEnteredRegion = false; 39431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 39531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 39631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 39731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!inDragRegion && x < SCROLL_ZONE) { 39831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mScrollState == SCROLL_OUTSIDE_ZONE) { 39931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollState = SCROLL_WAITING_IN_ZONE; 40031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollRunnable.setDirection(SCROLL_LEFT); 40131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project postDelayed(mScrollRunnable, SCROLL_DELAY); 40231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 40331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (!inDragRegion && x > getWidth() - SCROLL_ZONE) { 40431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mScrollState == SCROLL_OUTSIDE_ZONE) { 40531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollState = SCROLL_WAITING_IN_ZONE; 40631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollRunnable.setDirection(SCROLL_RIGHT); 40731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project postDelayed(mScrollRunnable, SCROLL_DELAY); 40831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 40931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 41031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mScrollState == SCROLL_WAITING_IN_ZONE) { 41131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollState = SCROLL_OUTSIDE_ZONE; 41231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollRunnable.setDirection(SCROLL_RIGHT); 41331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project removeCallbacks(mScrollRunnable); 41431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 41531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 41631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 41731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 41831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_UP: 41931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project removeCallbacks(mScrollRunnable); 42031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mShouldDrop) { 42131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project drop(x, y); 42231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mShouldDrop = false; 42331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 42431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project endDrag(); 42531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 42631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 42731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MotionEvent.ACTION_CANCEL: 42831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project endDrag(); 42931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 43131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 43231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 43431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean drop(float x, float y) { 43531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project invalidate(); 43631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 43731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int[] coordinates = mDropCoordinates; 43831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); 43931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 44031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (dropTarget != null) { 44131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], 44231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); 44331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1], 44431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo)) { 44531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1], 44631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); 44731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragSource.onDropCompleted((View) dropTarget, true); 44831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 44931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 45031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragSource.onDropCompleted((View) dropTarget, false); 45131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 45231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 45331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 45431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 45531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 45631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 45731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project DropTarget findDropTarget(int x, int y, int[] dropCoordinates) { 45831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return findDropTarget(this, x, y, dropCoordinates); 45931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 46031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 46131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private DropTarget findDropTarget(ViewGroup container, int x, int y, int[] dropCoordinates) { 46231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Rect r = mDragRect; 46331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int count = container.getChildCount(); 46431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int scrolledX = x + container.getScrollX(); 46531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int scrolledY = y + container.getScrollY(); 46631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final View ignoredDropTarget = mIgnoredDropTarget; 46731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 46831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = count - 1; i >= 0; i--) { 46931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final View child = container.getChildAt(i); 47031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (child.getVisibility() == VISIBLE && child != ignoredDropTarget) { 47131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project child.getHitRect(r); 47231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (r.contains(scrolledX, scrolledY)) { 47331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project DropTarget target = null; 47431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (child instanceof ViewGroup) { 47531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project x = scrolledX - child.getLeft(); 47631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project y = scrolledY - child.getTop(); 47731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project target = findDropTarget((ViewGroup) child, x, y, dropCoordinates); 47831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 47931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (target == null) { 48031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (child instanceof DropTarget) { 48131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project dropCoordinates[0] = x; 48231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project dropCoordinates[1] = y; 48331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return (DropTarget) child; 48431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 48531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 48631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return target; 48731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 48831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 48931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 49031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 49131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 49231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 49331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 49431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 49531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void setDragScoller(DragScroller scroller) { 49631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragScroller = scroller; 49731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 49831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 49931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void setDragListener(DragListener l) { 50031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mListener = l; 50131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 50231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 50331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void removeDragListener(DragListener l) { 50431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mListener = null; 50531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 50631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 50731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 50831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Specifies the view that must be ignored when looking for a drop target. 50931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 51031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param view The view that will not be taken into account while looking 51131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * for a drop target. 51231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 51331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void setIgnoredDropTarget(View view) { 51431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mIgnoredDropTarget = view; 51531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 51631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 51731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 51831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Specifies the delete region. 51931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 52031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param region The rectangle in screen coordinates of the delete region. 52131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 52231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void setDeleteRegion(RectF region) { 52331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragRegion = region; 52431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 52531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 52631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private class ScrollRunnable implements Runnable { 52731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mDirection; 52831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 52931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ScrollRunnable() { 53031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 53131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 53231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void run() { 53331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDragScroller != null) { 53431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDirection == SCROLL_LEFT) { 53531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragScroller.scrollLeft(); 53631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 53731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragScroller.scrollRight(); 53831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 53931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollState = SCROLL_OUTSIDE_ZONE; 54031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 54331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void setDirection(int direction) { 54431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDirection = direction; 54531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 548