summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher2/DragLayer.java
diff options
context:
space:
mode:
authorJoe Onorato <joeo@android.com>2009-08-04 16:04:30 -0400
committerJoe Onorato <joeo@android.com>2009-08-06 12:45:43 -0700
commit00acb123c5100f06b8e89e8ec8978ebafc6f6d26 (patch)
tree77c09f4bcd3174e687ce4d5f31a0f89a55e52bb8 /src/com/android/launcher2/DragLayer.java
parent17721426111214db82ea00abd8bfafc66e65fe71 (diff)
downloadandroid_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.java575
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);
}
}