mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Dragging an icon out of a folder was showing a gray background. This was due to the icon's drawing cache background color. This fix simply temporarily resets that color when capturing the view into a Bitmap.
630 lines
22 KiB
Java
630 lines
22 KiB
Java
/*
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.launcher;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Matrix;
|
|
import android.graphics.Rect;
|
|
import android.graphics.RectF;
|
|
import android.graphics.Paint;
|
|
import android.graphics.PorterDuffColorFilter;
|
|
import android.graphics.PorterDuff;
|
|
import android.os.Vibrator;
|
|
import android.os.SystemClock;
|
|
import android.util.AttributeSet;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.view.KeyEvent;
|
|
import android.view.inputmethod.InputMethodManager;
|
|
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;
|
|
|
|
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;
|
|
|
|
/**
|
|
* Used to create a new DragLayer from XML.
|
|
*
|
|
* @param context The application's context.
|
|
* @param attrs The attribtues set containing the Workspace's customization values.
|
|
*/
|
|
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);
|
|
|
|
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();
|
|
}
|
|
|
|
@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();
|
|
}
|
|
}
|
|
}
|
|
|
|
@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;
|
|
}
|
|
|
|
@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;
|
|
}
|
|
}
|
|
}
|