package pl.verdigo.libraries.drawer;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.Window;
/**
* Bezel Swipe helper class.
*
* @author Lukasz Milewski <lukasz.milewski@gmail.com>
*/
public class BezelSwipe
{
public enum DispatchState
{
CALL_SUPER, FAKE_CANCEL, RETURN_FALSE, RETURN_TRUE;
}
private int mIgnoredTopHeight;
private Drawer mDrawer;
private boolean mIsBeingDragged = false;
private Drawer mSecondDrawer;
private boolean mSecondDrawerHandled = false;
private int mStartX;
private int mStartY;
private int mLeftDragAreaWidth;
private int mWindowWidth;
/**
* Creates BezelSwipe object.
*
* @param drawer Drawer
* @param window Window
* @param ignoredTopHeight Ignored height
* @param leftDragAreaWidth Left drag area
*/
public BezelSwipe(Drawer drawer, Window window, int ignoredTopHeight, int leftDragAreaWidth)
{
this(drawer, null, window, ignoredTopHeight, leftDragAreaWidth);
}
/**
* Creates BezelSwipe object for two Drawer objects.
*
* @param drawer Drawer
* @param secondDrawer Second drawer
* @param window Window
* @param ignoredTopHeight Ignored height
* @param leftDragAreaWidth Left drag area
*/
public BezelSwipe(Drawer drawer, Drawer secondDrawer, Window window, int ignoredTopHeight, int leftDragAreaWidth)
{
mDrawer = drawer;
mSecondDrawer = secondDrawer;
mIgnoredTopHeight = ignoredTopHeight;
mLeftDragAreaWidth = leftDragAreaWidth;
mWindowWidth = window.getDecorView().getWidth();
if (mSecondDrawer != null && mDrawer.isRightDrawer() == mSecondDrawer.isRightDrawer())
{
throw new UnsupportedOperationException("Drawers needs to be on opposite sides");
}
updateNotificationBarHeight(window);
}
private void updateNotificationBarHeight(Window window)
{
Rect rect = new Rect();
window.getDecorView().getWindowVisibleDisplayFrame(rect);
int notificationHeight = rect.top;
mIgnoredTopHeight += notificationHeight;
}
private void cancelSwipe()
{
mStartX = -1;
mStartY = -1;
mSecondDrawerHandled = false;
}
/**
* Wrapper for dispatching touch events.
*
* @param ev Motion event
* @return Return state to original method
*/
public DispatchState dispatchTouchEvent(MotionEvent ev)
{
int x = Math.round(ev.getX());
int y = Math.round(ev.getY());
if (!mIsBeingDragged && y < mIgnoredTopHeight)
{
return DispatchState.CALL_SUPER;
}
if (ev.getAction() == MotionEvent.ACTION_DOWN)
{
mIsBeingDragged = false;
if ((x < mLeftDragAreaWidth && !mDrawer.isRightDrawer()) || (x > mWindowWidth - mLeftDragAreaWidth && mDrawer.isRightDrawer()))
{
mStartX = x;
mStartY = y;
mSecondDrawerHandled = false;
}
else if (mSecondDrawer != null && ((x < mLeftDragAreaWidth && !mSecondDrawer.isRightDrawer())
|| (x > mWindowWidth - mLeftDragAreaWidth && mSecondDrawer.isRightDrawer())))
{
mStartX = x;
mStartY = y;
mSecondDrawerHandled = true;
}
else
{
cancelSwipe();
}
if ((mDrawer.isVisible()) && mSecondDrawerHandled || (mSecondDrawer != null && mSecondDrawer.isVisible() && !mSecondDrawerHandled))
{
cancelSwipe();
}
return DispatchState.CALL_SUPER;
}
if (ev.getAction() == MotionEvent.ACTION_MOVE && mStartX >= 0 && !mIsBeingDragged)
{
if (Math.abs(y - mStartY) > mLeftDragAreaWidth)
{
cancelSwipe();
return DispatchState.CALL_SUPER;
}
if (x - mStartX >= mLeftDragAreaWidth && !getDrawer().isRightDrawer())
{
mIsBeingDragged = true;
}
if (mStartX - x >= mLeftDragAreaWidth && getDrawer().isRightDrawer())
{
mIsBeingDragged = true;
}
return DispatchState.CALL_SUPER;
}
if (ev.getAction() == MotionEvent.ACTION_MOVE && mIsBeingDragged)
{
getDrawer().isMovable();
getDrawer().setAllowCloseOnTouch(false);
getDrawer().showWithTouch(x);
getDrawer().onTouch(null, ev);
return DispatchState.FAKE_CANCEL;
}
if (ev.getAction() == MotionEvent.ACTION_UP && mIsBeingDragged)
{
getDrawer().finishShowing();
}
if ((ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) && mIsBeingDragged)
{
getDrawer().onTouch(null, ev);
getDrawer().setAllowCloseOnTouch(true);
cancelSwipe();
mIsBeingDragged = false;
return DispatchState.FAKE_CANCEL;
}
return DispatchState.CALL_SUPER;
}
private Drawer getDrawer()
{
if (mSecondDrawerHandled)
{
return mSecondDrawer;
}
return mDrawer;
}
}