package com.smartisanos.sidebar.view;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.view.View;
import android.widget.ImageView;
import com.smartisanos.sidebar.R;
import com.smartisanos.sidebar.action.UninstallAction;
import com.smartisanos.sidebar.util.Constants;
import com.smartisanos.sidebar.util.LOG;
import com.smartisanos.sidebar.util.anim.Anim;
import com.smartisanos.sidebar.util.anim.AnimInterpolator;
import com.smartisanos.sidebar.util.anim.AnimListener;
import com.smartisanos.sidebar.util.anim.AnimTimeLine;
import com.smartisanos.sidebar.util.anim.Vector3f;
import com.smartisanos.sidebar.view.SidebarRootView.DragView;
public class Trash {
private static final LOG log = LOG.getInstance(Trash.class);
private Context mContext;
public ImageView mTrashView;
public ImageView mTrashForegroundView;
public int mTrashWidth;
public int mTrashHeight;
public int mWindowWidth;
public int mWindowHeight;
public int mTrashDisplayHeight;
public int mTrashFloatUpHeight;
public int [] trash_react_area = new int[4];
public int [] trash_uninstall_react_area = new int[4];
public static final int TRASH_HIDE = 1;
public static final int TRASH_SHOW = 2;
public static final int TRASH_FLOAT = 3;
private int mTrashStatus = TRASH_HIDE;
private UninstallAction mUninstallAction;
public Trash(Context context, ImageView trashView, ImageView trashForegroundView) {
mContext = context;
mTrashView = trashView;
mTrashForegroundView = trashForegroundView;
Resources resources = mContext.getResources();
mTrashWidth = resources.getInteger(R.integer.trash_width);;
mTrashHeight = resources.getInteger(R.integer.trash_height);
mTrashDisplayHeight = resources.getInteger(R.integer.trash_display_height);
mTrashFloatUpHeight = resources.getInteger(R.integer.trash_float_up_height);
mWindowWidth = Constants.WindowWidth;
mWindowHeight = Constants.WindowHeight;
}
public boolean inTrashReactArea(float x, float y) {
if (trash_react_area[0] == 0) {
return false;
}
if (trash_react_area[0] < x && x < trash_react_area[2]) {
if (y > trash_react_area[1]) {
return true;
}
}
return false;
}
public boolean inTrashUninstallReactArea(float x, float y) {
if (trash_uninstall_react_area[0] == 0) {
return false;
}
if (trash_uninstall_react_area[0] < x && x < trash_uninstall_react_area[2]) {
if (y > trash_uninstall_react_area[1]) {
return true;
}
}
return false;
}
public void dragObjectMoveTo(float x, float y) {
if (inTrashReactArea(x, y)) {
//in trash area
trashFloatUpWithAnim(null);
} else {
//out trash area
trashFallDownWithAnim();
}
}
public void dismissDialog() {
if (mUninstallAction != null) {
mUninstallAction.dismissDialog();
}
}
public boolean dragObjectUpOnUp(float x, float y, DragView dragView) {
if (!inTrashUninstallReactArea(x, y)) {
return false;
}
//move icon to trash
moveIconToTrash(dragView);
mUninstallAction = new UninstallAction(mContext, dragView);
mUninstallAction.showUninstallDialog();
return true;
}
public void initTrashView() {
mTrashStatus = TRASH_HIDE;
mTrashView.setVisibility(View.GONE);
int trashViewWidth = mTrashView.getWidth();
if (trashViewWidth == 0) {
trashViewWidth = mTrashWidth;
}
int locX = mWindowWidth / 2 - trashViewWidth / 2;
int locY = mWindowHeight;
mTrashView.setTranslationX(locX);
mTrashView.setTranslationY(locY);
mTrashView.setVisibility(View.VISIBLE);
trash_react_area = new int[4];
//left-top, right-bottom
int left = mWindowWidth / 2 - mTrashWidth / 2;
int top = mWindowHeight - mTrashHeight / 2;
int right = mWindowWidth / 2 + mTrashWidth / 2;
int bottom = mWindowHeight;
trash_react_area[0] = left;
trash_react_area[1] = top;
trash_react_area[2] = right;
trash_react_area[3] = bottom;
trash_uninstall_react_area[0] = left;
trash_uninstall_react_area[1] = mWindowHeight - mTrashHeight;
trash_uninstall_react_area[2] = right;
trash_uninstall_react_area[3] = bottom;
}
public void hideTrashView() {
if (mTrashView == null) {
return;
}
mTrashView.setVisibility(View.GONE);
}
private boolean trashAnimRunning = false;
public void trashAppearWithAnim() {
if (mTrashStatus != TRASH_HIDE) {
return;
}
if (trashAnimRunning) {
log.error("trashAppearWithAnim return by trashAppearAnimRunning true");
return;
}
mTrashView.setTranslationX(mWindowWidth / 2 - mTrashView.getWidth() / 2);
int fromY = mWindowHeight;
int toY = mWindowHeight - mTrashDisplayHeight;
Vector3f from = new Vector3f(0, fromY);
Vector3f to = new Vector3f(0, toY);
Anim anim = new Anim(mTrashView, Anim.TRANSLATE, 200, Anim.CUBIC_OUT, from, to);
anim.setListener(new AnimListener() {
@Override
public void onStart() {
trashAnimRunning = true;
int width = mTrashView.getWidth();
mTrashView.setTranslationX(mWindowWidth / 2 - width / 2);
}
@Override
public void onComplete(int type) {
trashAnimRunning = false;
mTrashStatus = TRASH_SHOW;
log.error("trashAppearWithAnim onComplete");
}
});
anim.start();
}
public void trashDisappearWithAnim(final Runnable callback) {
if (mTrashStatus == TRASH_HIDE) {
return;
}
if (trashAnimRunning) {
log.error("trashDisappearWithAnim return by trashDisappearAnimRunning true");
return;
}
Vector3f from = new Vector3f(0, mTrashView.getTranslationY());
Vector3f to = new Vector3f(0, mWindowHeight);
int time = 200;
AnimTimeLine timeLine = new AnimTimeLine();
if (mTrashForegroundView.getVisibility() == View.VISIBLE) {
Anim anim = new Anim(mTrashForegroundView, Anim.TRANSLATE, time, Anim.CUBIC_OUT, from, to);
anim.setListener(new AnimListener() {
@Override
public void onStart() {
}
@Override
public void onComplete(int type) {
mTrashForegroundView.setVisibility(View.GONE);
}
});
timeLine.addAnim(anim);
}
Anim anim = new Anim(mTrashView, Anim.TRANSLATE, time, Anim.CUBIC_OUT, from, to);
timeLine.setAnimListener(new AnimListener() {
@Override
public void onStart() {
trashAnimRunning = true;
}
@Override
public void onComplete(int type) {
trashAnimRunning = false;
mTrashStatus = TRASH_HIDE;
if (callback != null) {
callback.run();
}
}
});
timeLine.addAnim(anim);
if (!timeLine.start()) {
trashAnimRunning = false;
mTrashStatus = TRASH_HIDE;
if (callback != null) {
callback.run();
}
}
}
private boolean mTrashUpAnimRunning = false;
private boolean mTrashDownAnimRunning = false;
public void trashFloatUpWithAnim(final Runnable runnable) {
if (mTrashStatus == TRASH_FLOAT) {
return;
}
if (mTrashUpAnimRunning) {
log.error("trashFloatUpWithAnim return by mTrashUpAnimRunning true");
return;
}
mTrashUpAnimRunning = true;
int fromY = (int) mTrashView.getY();
int toY = mWindowHeight - mTrashDisplayHeight - mTrashFloatUpHeight;
Vector3f from = new Vector3f(0, fromY);
Vector3f to = new Vector3f(0, toY);
Anim anim = new Anim(mTrashView, Anim.TRANSLATE, 100, Anim.CUBIC_OUT, from, to);
anim.setListener(new AnimListener() {
@Override
public void onStart() {
}
@Override
public void onComplete(int type) {
mTrashStatus = TRASH_FLOAT;
mTrashUpAnimRunning = false;
if (runnable != null) {
runnable.run();
}
}
});
anim.start();
}
public void trashFallDownWithAnim() {
if (mTrashStatus != TRASH_FLOAT) {
return;
}
if (mTrashDownAnimRunning) {
log.error("trashFallDownWithAnim return by mTrashDownAnimRunning true");
return;
}
mTrashDownAnimRunning = true;
Vector3f from = new Vector3f(0, mTrashView.getY());
Vector3f to = new Vector3f(0, mWindowHeight - mTrashDisplayHeight);
Anim anim = new Anim(mTrashView, Anim.TRANSLATE, 100, Anim.CUBIC_OUT, from, to);
anim.setListener(new AnimListener() {
@Override
public void onStart() {
}
@Override
public void onComplete(int type) {
mTrashDownAnimRunning = false;
mTrashStatus = TRASH_SHOW;
}
});
anim.start();
}
public void moveIconToTrash(final SidebarRootView.DragView dragView) {
View view = dragView.mView;
if (view == null) {
return;
}
dragView.setBubbleVisibleStatus(View.INVISIBLE);
int viewWidth = view.getWidth();
int viewHeight = view.getHeight();
float fromX = view.getX();
float fromY = view.getY();
float toX = mWindowWidth / 2 - viewWidth / 2;
float toY = mWindowHeight - mTrashDisplayHeight - mTrashFloatUpHeight - viewHeight;
Vector3f from = new Vector3f(fromX, fromY);
Vector3f to = new Vector3f(toX, toY);
Anim anim = new Anim(view, Anim.TRANSLATE, 200, Anim.CUBIC_OUT, from, to);
anim.setListener(new AnimListener() {
@Override
public void onStart() {
}
@Override
public void onComplete(int type) {
if (mTrashStatus != TRASH_FLOAT) {
Runnable runnable = new Runnable() {
@Override
public void run() {
rockOnTrash(dragView.mView);
}
};
trashFloatUpWithAnim(runnable);
} else {
rockOnTrash(dragView.mView);
}
}
});
anim.start();
}
private boolean rockRepeat = false;
private AnimatorSet mRockAnimSet;
public void rockOnTrash(View view) {
if (mRockAnimSet != null) {
mRockAnimSet = null;
}
float rockAngle = 2.0f;
float offset = 2.0f;
float locX = view.getX();
float locY = view.getY();
//init view loc and rotate
rockRepeat = true;
view.setTranslationX(locX - offset);
view.setTranslationY(locY + offset);
view.setRotation(-rockAngle);
Vector3f loc = new Vector3f(locX, locY);
mRockAnimSet = generateRockAnimSet(view, loc);
RockAnimListener listener = new RockAnimListener(view, loc);
mRockAnimSet.addListener(listener);
mRockAnimSet.start();
}
public void stopRock() {
rockRepeat = false;
if (mRockAnimSet != null) {
if (mRockAnimSet.isStarted()) {
if (mRockAnimSet.isRunning()) {
mRockAnimSet.end();
} else {
mRockAnimSet.cancel();
}
}
}
//
}
private class RockAnimListener implements Animator.AnimatorListener {
private View mView;
private Vector3f mLoc;
public RockAnimListener(View view, Vector3f loc) {
mView = view;
mLoc = loc;
}
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
if (rockRepeat) {
mRockAnimSet = generateRockAnimSet(mView, mLoc);
RockAnimListener listener = new RockAnimListener(mView, mLoc);
mRockAnimSet.addListener(listener);
mRockAnimSet.start();
}
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
}
private AnimatorSet generateRockAnimSet(View view, Vector3f loc) {
float rockAngle = 2.0f;
float offset = 2.0f;
long interval_time = 70;
AnimInterpolator.Interpolator interpolator = new AnimInterpolator.Interpolator(Anim.CIRC_IN_OUT);
AnimatorSet animSet = new AnimatorSet();
//step 1
ObjectAnimator anim1_translateX = ObjectAnimator.ofFloat(view, Anim.X, loc.x - offset, loc.x + offset);
anim1_translateX.setDuration(interval_time);
anim1_translateX.setInterpolator(interpolator);
ObjectAnimator anim1_translateY = ObjectAnimator.ofFloat(view, Anim.Y, loc.y + offset, loc.y - offset);
anim1_translateY.setDuration(interval_time);
anim1_translateY.setInterpolator(interpolator);
animSet.play(anim1_translateX).with(anim1_translateY);
//step 2
ObjectAnimator anim2_rotate = ObjectAnimator.ofFloat(view, Anim.ROTATION, -rockAngle, rockAngle);
anim2_rotate.setDuration(interval_time);
anim2_rotate.setInterpolator(interpolator);
ObjectAnimator anim2_translateX = ObjectAnimator.ofFloat(view, Anim.X, loc.x + offset, loc.x + offset);
anim2_translateX.setDuration(interval_time);
anim2_translateX.setInterpolator(interpolator);
ObjectAnimator anim2_translateY = ObjectAnimator.ofFloat(view, Anim.Y, loc.y - offset, loc.y + offset);
anim2_translateY.setDuration(interval_time);
anim2_translateY.setInterpolator(interpolator);
animSet.play(anim2_rotate).with(anim2_translateX).with(anim2_translateY).after(anim1_translateX);
//step 3
ObjectAnimator anim3_translateX = ObjectAnimator.ofFloat(view, Anim.X, loc.x + offset, loc.x - offset);
anim3_translateX.setDuration(interval_time);
anim3_translateX.setInterpolator(interpolator);
ObjectAnimator anim3_translateY = ObjectAnimator.ofFloat(view, Anim.Y, loc.y + offset, loc.y - offset);
anim3_translateY.setDuration(interval_time);
anim3_translateY.setInterpolator(interpolator);
animSet.play(anim3_translateX).with(anim3_translateY).after(anim2_rotate);
//step 4
ObjectAnimator anim4_rotate = ObjectAnimator.ofFloat(view, Anim.ROTATION, rockAngle, -rockAngle);
anim4_rotate.setDuration(interval_time);
anim4_rotate.setInterpolator(interpolator);
ObjectAnimator anim4_translateX = ObjectAnimator.ofFloat(view, Anim.X, loc.x - offset, loc.x - offset);
anim4_translateX.setDuration(interval_time);
anim4_translateX.setInterpolator(interpolator);
ObjectAnimator anim4_translateY = ObjectAnimator.ofFloat(view, Anim.Y, loc.y - offset, loc.y + offset);
anim4_translateY.setDuration(interval_time);
anim4_translateY.setInterpolator(interpolator);
animSet.play(anim4_rotate).with(anim4_translateX).with(anim4_translateY).after(anim3_translateX);
return animSet;
}
}