diff options
author | Joe Onorato <joeo@android.com> | 2009-08-04 16:04:30 -0400 |
---|---|---|
committer | Joe Onorato <joeo@android.com> | 2009-08-06 12:45:43 -0700 |
commit | 00acb123c5100f06b8e89e8ec8978ebafc6f6d26 (patch) | |
tree | 77c09f4bcd3174e687ce4d5f31a0f89a55e52bb8 /src/com/android/launcher2/DragLayer.java | |
parent | 17721426111214db82ea00abd8bfafc66e65fe71 (diff) | |
download | android_packages_apps_Trebuchet-00acb123c5100f06b8e89e8ec8978ebafc6f6d26.tar.gz android_packages_apps_Trebuchet-00acb123c5100f06b8e89e8ec8978ebafc6f6d26.tar.bz2 android_packages_apps_Trebuchet-00acb123c5100f06b8e89e8ec8978ebafc6f6d26.zip |
Move the drag thing into its own window that goes around on top of everything else.
Diffstat (limited to 'src/com/android/launcher2/DragLayer.java')
-rw-r--r-- | src/com/android/launcher2/DragLayer.java | 575 |
1 files changed, 8 insertions, 567 deletions
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java index fee86326c..28397119a 100644 --- a/src/com/android/launcher2/DragLayer.java +++ b/src/com/android/launcher2/DragLayer.java @@ -39,114 +39,9 @@ import android.widget.FrameLayout; /** * A ViewGroup that coordinated dragging across its dscendants */ -public class DragLayer extends FrameLayout implements DragController { - private static final int SCROLL_DELAY = 600; - private static final int SCROLL_ZONE = 20; - private static final int VIBRATE_DURATION = 35; - private static final int ANIMATION_SCALE_UP_DURATION = 110; +public class DragLayer extends FrameLayout { - private static final boolean PROFILE_DRAWING_DURING_DRAG = false; - - // Number of pixels to add to the dragged item for scaling - private static final float DRAG_SCALE = 24.0f; - - private boolean mDragging = false; - private boolean mShouldDrop; - private float mLastMotionX; - private float mLastMotionY; - - /** - * The bitmap that is currently being dragged - */ - private Bitmap mDragBitmap = null; - private View mOriginator; - - private int mBitmapOffsetX; - private int mBitmapOffsetY; - - /** - * X offset from where we touched on the cell to its upper-left corner - */ - private float mTouchOffsetX; - - /** - * Y offset from where we touched on the cell to its upper-left corner - */ - private float mTouchOffsetY; - - /** - * Utility rectangle - */ - private Rect mDragRect = new Rect(); - - /** - * Where the drag originated - */ - private DragSource mDragSource; - - /** - * The data associated with the object being dragged - */ - private Object mDragInfo; - - private final Rect mRect = new Rect(); - private final int[] mDropCoordinates = new int[2]; - - private final Vibrator mVibrator = new Vibrator(); - - private DragListener mListener; - - private DragScroller mDragScroller; - - private static final int SCROLL_OUTSIDE_ZONE = 0; - private static final int SCROLL_WAITING_IN_ZONE = 1; - - private static final int SCROLL_LEFT = 0; - private static final int SCROLL_RIGHT = 1; - - private int mScrollState = SCROLL_OUTSIDE_ZONE; - - private ScrollRunnable mScrollRunnable = new ScrollRunnable(); - private View mIgnoredDropTarget; - - private RectF mDragRegion; - private boolean mEnteredRegion; - private DropTarget mLastDropTarget; - - private final Paint mTrashPaint = new Paint(); - private final Paint mEstimatedPaint = new Paint(); - private Paint mDragPaint; - - /** - * If true, draw a "snag" showing where the object currently being dragged - * would end up if dropped from current location. - */ - private static final boolean DRAW_TARGET_SNAG = false; - - private Rect mEstimatedRect = new Rect(); - private float[] mDragCenter = new float[2]; - private float[] mEstimatedCenter = new float[2]; - private boolean mDrawEstimated = false; - - private int mTriggerWidth = -1; - private int mTriggerHeight = -1; - - private static final int DISTANCE_DRAW_SNAG = 20; - - private static final int ANIMATION_STATE_STARTING = 1; - private static final int ANIMATION_STATE_RUNNING = 2; - private static final int ANIMATION_STATE_DONE = 3; - - private static final int ANIMATION_TYPE_SCALE = 1; - - private float mAnimationFrom; - private float mAnimationTo; - private int mAnimationDuration; - private long mAnimationStartTime; - private int mAnimationType; - private int mAnimationState = ANIMATION_STATE_DONE; - - private InputMethodManager mInputMethodManager; + DragController mDragController; /** * Used to create a new DragLayer from XML. @@ -156,478 +51,24 @@ public class DragLayer extends FrameLayout implements DragController { */ public DragLayer(Context context, AttributeSet attrs) { super(context, attrs); - - final int srcColor = context.getResources().getColor(R.color.delete_color_filter); - mTrashPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP)); - - // Make estimated paint area in gray - int snagColor = context.getResources().getColor(R.color.snag_callout_color); - mEstimatedPaint.setColor(snagColor); - mEstimatedPaint.setStrokeWidth(3); - mEstimatedPaint.setAntiAlias(true); - } - public void startDrag(View v, DragSource source, Object dragInfo, int dragAction) { - if (PROFILE_DRAWING_DURING_DRAG) { - android.os.Debug.startMethodTracing("Launcher"); - } - - // Hide soft keyboard, if visible - if (mInputMethodManager == null) { - mInputMethodManager = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - } - mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); - - if (mListener != null) { - mListener.onDragStart(v, source, dragInfo, dragAction); - } - - Rect r = mDragRect; - r.set(v.getScrollX(), v.getScrollY(), 0, 0); - - offsetDescendantRectToMyCoords(v, r); - mTouchOffsetX = mLastMotionX - r.left; - mTouchOffsetY = mLastMotionY - r.top; - - v.clearFocus(); - v.setPressed(false); - - boolean willNotCache = v.willNotCacheDrawing(); - v.setWillNotCacheDrawing(false); - - // Reset the drawing cache background color to fully transparent - // for the duration of this operation - int color = v.getDrawingCacheBackgroundColor(); - v.setDrawingCacheBackgroundColor(0); - - if (color != 0) { - v.destroyDrawingCache(); - } - v.buildDrawingCache(); - Bitmap viewBitmap = v.getDrawingCache(); - int width = viewBitmap.getWidth(); - int height = viewBitmap.getHeight(); - - mTriggerWidth = width * 2 / 3; - mTriggerHeight = height * 2 / 3; - - Matrix scale = new Matrix(); - float scaleFactor = v.getWidth(); - scaleFactor = (scaleFactor + DRAG_SCALE) /scaleFactor; - scale.setScale(scaleFactor, scaleFactor); - - mAnimationTo = 1.0f; - mAnimationFrom = 1.0f / scaleFactor; - mAnimationDuration = ANIMATION_SCALE_UP_DURATION; - mAnimationState = ANIMATION_STATE_STARTING; - mAnimationType = ANIMATION_TYPE_SCALE; - - mDragBitmap = Bitmap.createBitmap(viewBitmap, 0, 0, width, height, scale, true); - v.destroyDrawingCache(); - v.setWillNotCacheDrawing(willNotCache); - v.setDrawingCacheBackgroundColor(color); - - final Bitmap dragBitmap = mDragBitmap; - mBitmapOffsetX = (dragBitmap.getWidth() - width) / 2; - mBitmapOffsetY = (dragBitmap.getHeight() - height) / 2; - - if (dragAction == DRAG_ACTION_MOVE) { - v.setVisibility(GONE); - } - - mDragPaint = null; - mDragging = true; - mShouldDrop = true; - mOriginator = v; - mDragSource = source; - mDragInfo = dragInfo; - - mVibrator.vibrate(VIBRATE_DURATION); - - mEnteredRegion = false; - - invalidate(); + public void setDragController(DragController controller) { + mDragController = controller; } - + @Override public boolean dispatchKeyEvent(KeyEvent event) { - return mDragging || super.dispatchKeyEvent(event); - } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - - if (mDragging && mDragBitmap != null) { - if (mAnimationState == ANIMATION_STATE_STARTING) { - mAnimationStartTime = SystemClock.uptimeMillis(); - mAnimationState = ANIMATION_STATE_RUNNING; - } - - if (mAnimationState == ANIMATION_STATE_RUNNING) { - float normalized = (float) (SystemClock.uptimeMillis() - mAnimationStartTime) / - mAnimationDuration; - if (normalized >= 1.0f) { - mAnimationState = ANIMATION_STATE_DONE; - } - normalized = Math.min(normalized, 1.0f); - final float value = mAnimationFrom + (mAnimationTo - mAnimationFrom) * normalized; - - switch (mAnimationType) { - case ANIMATION_TYPE_SCALE: - final Bitmap dragBitmap = mDragBitmap; - canvas.save(); - canvas.translate(mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, - mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY); - canvas.translate((dragBitmap.getWidth() * (1.0f - value)) / 2, - (dragBitmap.getHeight() * (1.0f - value)) / 2); - canvas.scale(value, value); - canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint); - canvas.restore(); - break; - } - } else { - // Only draw estimate drop "snag" when requested - if (DRAW_TARGET_SNAG && mDrawEstimated) { - canvas.drawLine(mDragCenter[0], mDragCenter[1], mEstimatedCenter[0], mEstimatedCenter[1], mEstimatedPaint); - canvas.drawCircle(mEstimatedCenter[0], mEstimatedCenter[1], 8, mEstimatedPaint); - } - - // Draw actual icon being dragged - canvas.drawBitmap(mDragBitmap, - mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, - mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY, mDragPaint); - } - } - } - - private void endDrag() { - if (mDragging) { - mDragging = false; - if (mDragBitmap != null) { - mDragBitmap.recycle(); - } - if (mOriginator != null) { - mOriginator.setVisibility(VISIBLE); - } - if (mListener != null) { - mListener.onDragEnd(); - } - } + return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - final int action = ev.getAction(); - - final float x = ev.getX(); - final float y = ev.getY(); - - switch (action) { - case MotionEvent.ACTION_MOVE: - break; - - case MotionEvent.ACTION_DOWN: - // Remember location of down touch - mLastMotionX = x; - mLastMotionY = y; - mLastDropTarget = null; - break; - - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - if (mShouldDrop && drop(x, y)) { - mShouldDrop = false; - } - endDrag(); - break; - } - - return mDragging; + return mDragController.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { - if (!mDragging) { - return false; - } - - final int action = ev.getAction(); - final float x = ev.getX(); - final float y = ev.getY(); - - switch (action) { - case MotionEvent.ACTION_DOWN: - - // Remember where the motion event started - mLastMotionX = x; - mLastMotionY = y; - - if ((x < SCROLL_ZONE) || (x > getWidth() - SCROLL_ZONE)) { - mScrollState = SCROLL_WAITING_IN_ZONE; - postDelayed(mScrollRunnable, SCROLL_DELAY); - } else { - mScrollState = SCROLL_OUTSIDE_ZONE; - } - - break; - case MotionEvent.ACTION_MOVE: - final int scrollX = mScrollX; - final int scrollY = mScrollY; - - final float touchX = mTouchOffsetX; - final float touchY = mTouchOffsetY; - - final int offsetX = mBitmapOffsetX; - final int offsetY = mBitmapOffsetY; - - int left = (int) (scrollX + mLastMotionX - touchX - offsetX); - int top = (int) (scrollY + mLastMotionY - touchY - offsetY); - - final Bitmap dragBitmap = mDragBitmap; - final int width = dragBitmap.getWidth(); - final int height = dragBitmap.getHeight(); - - final Rect rect = mRect; - rect.set(left - 1, top - 1, left + width + 1, top + height + 1); - - mLastMotionX = x; - mLastMotionY = y; - - left = (int) (scrollX + x - touchX - offsetX); - top = (int) (scrollY + y - touchY - offsetY); - - // Invalidate current icon position - rect.union(left - 1, top - 1, left + width + 1, top + height + 1); - - mDragCenter[0] = rect.centerX(); - mDragCenter[1] = rect.centerY(); - - // Invalidate any old estimated location - if (DRAW_TARGET_SNAG && mDrawEstimated) { - rect.union(mEstimatedRect); - } - - final int[] coordinates = mDropCoordinates; - DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); - if (dropTarget != null) { - if (mLastDropTarget == dropTarget) { - dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1], - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); - } else { - if (mLastDropTarget != null) { - mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); - } - dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1], - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); - } - } else { - if (mLastDropTarget != null) { - mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); - } - } - - // Render estimated drop "snag" only outside of width - mDrawEstimated = false; - if (DRAW_TARGET_SNAG && dropTarget != null) { - Rect foundEstimate = dropTarget.estimateDropLocation(mDragSource, - (int) (scrollX + mLastMotionX), (int) (scrollY + mLastMotionY), - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo, mEstimatedRect); - - if (foundEstimate != null) { - mEstimatedCenter[0] = foundEstimate.centerX(); - mEstimatedCenter[1] = foundEstimate.centerY(); - - int deltaX = (int) Math.abs(mEstimatedCenter[0] - mDragCenter[0]); - int deltaY = (int) Math.abs(mEstimatedCenter[1] - mDragCenter[1]); - - if (deltaX > mTriggerWidth || deltaY > mTriggerHeight) { - mDrawEstimated = true; - } - } - } - - // Include new estimated area in invalidated rectangle - if (DRAW_TARGET_SNAG && mDrawEstimated) { - rect.union(mEstimatedRect); - } - invalidate(rect); - - mLastDropTarget = dropTarget; - - boolean inDragRegion = false; - if (mDragRegion != null) { - final RectF region = mDragRegion; - final boolean inRegion = region.contains(ev.getRawX(), ev.getRawY()); - if (!mEnteredRegion && inRegion) { - mDragPaint = mTrashPaint; - mEnteredRegion = true; - inDragRegion = true; - } else if (mEnteredRegion && !inRegion) { - mDragPaint = null; - mEnteredRegion = false; - } - } - - if (!inDragRegion && x < SCROLL_ZONE) { - if (mScrollState == SCROLL_OUTSIDE_ZONE) { - mScrollState = SCROLL_WAITING_IN_ZONE; - mScrollRunnable.setDirection(SCROLL_LEFT); - postDelayed(mScrollRunnable, SCROLL_DELAY); - } - } else if (!inDragRegion && x > getWidth() - SCROLL_ZONE) { - if (mScrollState == SCROLL_OUTSIDE_ZONE) { - mScrollState = SCROLL_WAITING_IN_ZONE; - mScrollRunnable.setDirection(SCROLL_RIGHT); - postDelayed(mScrollRunnable, SCROLL_DELAY); - } - } else { - if (mScrollState == SCROLL_WAITING_IN_ZONE) { - mScrollState = SCROLL_OUTSIDE_ZONE; - mScrollRunnable.setDirection(SCROLL_RIGHT); - removeCallbacks(mScrollRunnable); - } - } - - break; - case MotionEvent.ACTION_UP: - removeCallbacks(mScrollRunnable); - if (mShouldDrop) { - drop(x, y); - mShouldDrop = false; - } - endDrag(); - - break; - case MotionEvent.ACTION_CANCEL: - endDrag(); - } - - return true; - } - - private boolean drop(float x, float y) { - invalidate(); - - final int[] coordinates = mDropCoordinates; - DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); - - if (dropTarget != null) { - dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); - if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1], - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo)) { - dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1], - (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); - mDragSource.onDropCompleted((View) dropTarget, true); - return true; - } else { - mDragSource.onDropCompleted((View) dropTarget, false); - return true; - } - } - return false; - } - - DropTarget findDropTarget(int x, int y, int[] dropCoordinates) { - return findDropTarget(this, x, y, dropCoordinates); - } - - private DropTarget findDropTarget(ViewGroup container, int x, int y, int[] dropCoordinates) { - final Rect r = mDragRect; - final int count = container.getChildCount(); - final int scrolledX = x + container.getScrollX(); - final int scrolledY = y + container.getScrollY(); - final View ignoredDropTarget = mIgnoredDropTarget; - - for (int i = count - 1; i >= 0; i--) { - final View child = container.getChildAt(i); - if (child.getVisibility() == VISIBLE && child != ignoredDropTarget) { - child.getHitRect(r); - if (r.contains(scrolledX, scrolledY)) { - DropTarget target = null; - if (child instanceof ViewGroup) { - x = scrolledX - child.getLeft(); - y = scrolledY - child.getTop(); - target = findDropTarget((ViewGroup) child, x, y, dropCoordinates); - } - if (target == null) { - if (child instanceof DropTarget) { - // Only consider this child if they will accept - DropTarget childTarget = (DropTarget) child; - if (childTarget.acceptDrop(mDragSource, x, y, 0, 0, mDragInfo)) { - dropCoordinates[0] = x; - dropCoordinates[1] = y; - return (DropTarget) child; - } else { - return null; - } - } - } else { - return target; - } - } - } - } - - return null; - } - - public void setDragScoller(DragScroller scroller) { - mDragScroller = scroller; - } - - public void setDragListener(DragListener l) { - mListener = l; - } - - public void removeDragListener(DragListener l) { - mListener = null; - } - - /** - * Specifies the view that must be ignored when looking for a drop target. - * - * @param view The view that will not be taken into account while looking - * for a drop target. - */ - void setIgnoredDropTarget(View view) { - mIgnoredDropTarget = view; - } - - /** - * Specifies the delete region. - * - * @param region The rectangle in screen coordinates of the delete region. - */ - void setDeleteRegion(RectF region) { - mDragRegion = region; - } - - private class ScrollRunnable implements Runnable { - private int mDirection; - - ScrollRunnable() { - } - - public void run() { - if (mDragScroller != null) { - mDrawEstimated = false; - if (mDirection == SCROLL_LEFT) { - mDragScroller.scrollLeft(); - } else { - mDragScroller.scrollRight(); - } - mScrollState = SCROLL_OUTSIDE_ZONE; - } - } - - void setDirection(int direction) { - mDirection = direction; - } + return mDragController.onTouchEvent(ev); } } |