summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/ButtonDropTarget.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/ButtonDropTarget.java')
-rw-r--r--src/com/android/launcher3/ButtonDropTarget.java225
1 files changed, 190 insertions, 35 deletions
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 019f86c21..b7f89d02a 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -16,26 +16,41 @@
package com.android.launcher3;
+import android.animation.AnimatorSet;
+import android.animation.FloatArrayEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.TargetApi;
import android.content.Context;
-import android.content.res.Resources;
+import android.content.res.ColorStateList;
+import android.content.res.Configuration;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
import android.widget.TextView;
+import com.android.launcher3.util.Thunk;
/**
* Implements a DropTarget.
*/
-public class ButtonDropTarget extends TextView implements DropTarget, DragController.DragListener {
+public abstract class ButtonDropTarget extends TextView
+ implements DropTarget, DragController.DragListener, OnClickListener {
- protected final int mTransitionDuration;
+ private static int DRAG_VIEW_DROP_DURATION = 285;
protected Launcher mLauncher;
private int mBottomDragPadding;
- protected TextView mText;
protected SearchDropTargetBar mSearchDropTargetBar;
/** Whether this drop target is active for the current drag */
@@ -44,72 +59,197 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
/** The paint applied to the drag view on hover */
protected int mHoverColor = 0;
+ protected ColorStateList mOriginalTextColor;
+ protected Drawable mDrawable;
+
+ private AnimatorSet mCurrentColorAnim;
+ @Thunk ColorMatrix mSrcFilter, mDstFilter, mCurrentFilter;
+
+
public ButtonDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ButtonDropTarget(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ mBottomDragPadding = getResources().getDimensionPixelSize(R.dimen.drop_target_drag_padding);
+ }
- Resources r = getResources();
- mTransitionDuration = r.getInteger(R.integer.config_dropTargetBgTransitionDuration);
- mBottomDragPadding = r.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mOriginalTextColor = getTextColors();
+
+ // Remove the text in the Phone UI in landscape
+ DeviceProfile grid = ((Launcher) getContext()).getDeviceProfile();
+ if (grid.isVerticalBarLayout()) {
+ setText("");
+ }
}
- void setLauncher(Launcher launcher) {
- mLauncher = launcher;
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+ protected void setDrawable(int resId) {
+ // We do not set the drawable in the xml as that inflates two drawables corresponding to
+ // drawableLeft and drawableStart.
+ mDrawable = getResources().getDrawable(resId);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
+ } else {
+ setCompoundDrawablesWithIntrinsicBounds(mDrawable, null, null, null);
+ }
}
- public boolean acceptDrop(DragObject d) {
- return false;
+ public void setLauncher(Launcher launcher) {
+ mLauncher = launcher;
}
public void setSearchDropTargetBar(SearchDropTargetBar searchDropTargetBar) {
mSearchDropTargetBar = searchDropTargetBar;
}
- protected Drawable getCurrentDrawable() {
- Drawable[] drawables = getCompoundDrawablesRelative();
- for (int i = 0; i < drawables.length; ++i) {
- if (drawables[i] != null) {
- return drawables[i];
+ @Override
+ public void onFlingToDelete(DragObject d, PointF vec) { }
+
+ @Override
+ public final void onDragEnter(DragObject d) {
+ d.dragView.setColor(mHoverColor);
+ if (Utilities.isLmpOrAbove()) {
+ animateTextColor(mHoverColor);
+ } else {
+ if (mCurrentFilter == null) {
+ mCurrentFilter = new ColorMatrix();
}
+ DragView.setColorScale(mHoverColor, mCurrentFilter);
+ mDrawable.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
+ setTextColor(mHoverColor);
}
- return null;
}
- public void onDrop(DragObject d) {
+ @Override
+ public void onDragOver(DragObject d) {
+ // Do nothing
}
- public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
- // Do nothing
+ protected void resetHoverColor() {
+ if (Utilities.isLmpOrAbove()) {
+ animateTextColor(mOriginalTextColor.getDefaultColor());
+ } else {
+ mDrawable.setColorFilter(null);
+ setTextColor(mOriginalTextColor);
+ }
}
- public void onDragEnter(DragObject d) {
- d.dragView.setColor(mHoverColor);
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private void animateTextColor(int targetColor) {
+ if (mCurrentColorAnim != null) {
+ mCurrentColorAnim.cancel();
+ }
+
+ mCurrentColorAnim = new AnimatorSet();
+ mCurrentColorAnim.setDuration(DragView.COLOR_CHANGE_DURATION);
+
+ if (mSrcFilter == null) {
+ mSrcFilter = new ColorMatrix();
+ mDstFilter = new ColorMatrix();
+ mCurrentFilter = new ColorMatrix();
+ }
+
+ DragView.setColorScale(getTextColor(), mSrcFilter);
+ DragView.setColorScale(targetColor, mDstFilter);
+ ValueAnimator anim1 = ValueAnimator.ofObject(
+ new FloatArrayEvaluator(mCurrentFilter.getArray()),
+ mSrcFilter.getArray(), mDstFilter.getArray());
+ anim1.addUpdateListener(new AnimatorUpdateListener() {
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mDrawable.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
+ invalidate();
+ }
+ });
+
+ mCurrentColorAnim.play(anim1);
+ mCurrentColorAnim.play(ObjectAnimator.ofArgb(this, "textColor", targetColor));
+ mCurrentColorAnim.start();
}
- public void onDragOver(DragObject d) {
- // Do nothing
+ @Override
+ public final void onDragExit(DragObject d) {
+ if (!d.dragComplete) {
+ d.dragView.setColor(0);
+ resetHoverColor();
+ } else {
+ // Restore the hover color
+ d.dragView.setColor(mHoverColor);
+ }
}
- public void onDragExit(DragObject d) {
- d.dragView.setColor(0);
+ @Override
+ public final void onDragStart(DragSource source, Object info, int dragAction) {
+ mActive = supportsDrop(source, info);
+ mDrawable.setColorFilter(null);
+ if (mCurrentColorAnim != null) {
+ mCurrentColorAnim.cancel();
+ mCurrentColorAnim = null;
+ }
+ setTextColor(mOriginalTextColor);
+ ((ViewGroup) getParent()).setVisibility(mActive ? View.VISIBLE : View.GONE);
}
- public void onDragStart(DragSource source, Object info, int dragAction) {
- // Do nothing
+ @Override
+ public final boolean acceptDrop(DragObject dragObject) {
+ return supportsDrop(dragObject.dragSource, dragObject.dragInfo);
}
+ protected abstract boolean supportsDrop(DragSource source, Object info);
+
+ @Override
public boolean isDropEnabled() {
return mActive;
}
+ @Override
public void onDragEnd() {
- // Do nothing
+ mActive = false;
+ }
+
+ /**
+ * On drop animate the dropView to the icon.
+ */
+ @Override
+ public void onDrop(final DragObject d) {
+ final DragLayer dragLayer = mLauncher.getDragLayer();
+ final Rect from = new Rect();
+ dragLayer.getViewRectRelativeToSelf(d.dragView, from);
+
+ int width = mDrawable.getIntrinsicWidth();
+ int height = mDrawable.getIntrinsicHeight();
+ final Rect to = getIconRect(d.dragView.getMeasuredWidth(), d.dragView.getMeasuredHeight(),
+ width, height);
+ final float scale = (float) to.width() / from.width();
+ mSearchDropTargetBar.deferOnDragEnd();
+
+ Runnable onAnimationEndRunnable = new Runnable() {
+ @Override
+ public void run() {
+ completeDrop(d);
+ mSearchDropTargetBar.onDragEnd();
+ mLauncher.exitSpringLoadedDragModeDelayed(true, 0, null);
+ }
+ };
+ dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
+ DRAG_VIEW_DROP_DURATION, new DecelerateInterpolator(2),
+ new LinearInterpolator(), onAnimationEndRunnable,
+ DragLayer.ANIMATION_END_DISAPPEAR, null);
}
@Override
+ public void prepareAccessibilityDrop() { }
+
+ @Thunk abstract void completeDrop(DragObject d);
+
+ @Override
public void getHitRectRelativeToDragLayer(android.graphics.Rect outRect) {
super.getHitRect(outRect);
outRect.bottom += mBottomDragPadding;
@@ -119,11 +259,7 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
outRect.offsetTo(coords[0], coords[1]);
}
- private boolean isRtl() {
- return (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
- }
-
- Rect getIconRect(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight) {
+ protected Rect getIconRect(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight) {
DragLayer dragLayer = mLauncher.getDragLayer();
// Find the rect to animate to (the view is center aligned)
@@ -136,7 +272,7 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
final int left;
final int right;
- if (isRtl()) {
+ if (Utilities.isRtl(getResources())) {
right = to.right - getPaddingRight();
left = right - width;
} else {
@@ -157,7 +293,26 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
return to;
}
+ @Override
public void getLocationInDragLayer(int[] loc) {
mLauncher.getDragLayer().getLocationInDragLayer(this, loc);
}
+
+ public void enableAccessibleDrag(boolean enable) {
+ setOnClickListener(enable ? this : null);
+ }
+
+ protected String getAccessibilityDropConfirmation() {
+ return null;
+ }
+
+ @Override
+ public void onClick(View v) {
+ LauncherAppState.getInstance().getAccessibilityDelegate()
+ .handleAccessibleDrop(this, null, getAccessibilityDropConfirmation());
+ }
+
+ public int getTextColor() {
+ return getTextColors().getDefaultColor();
+ }
}