diff --git a/hover/src/main/java/io/mattcarroll/hover/BaseTouchController.java b/hover/src/main/java/io/mattcarroll/hover/BaseTouchController.java
new file mode 100644
index 0000000..e69bde4
--- /dev/null
+++ b/hover/src/main/java/io/mattcarroll/hover/BaseTouchController.java
@@ -0,0 +1,85 @@
+package io.mattcarroll.hover;
+
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.support.annotation.NonNull;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+public abstract class BaseTouchController {
+ private static final String TAG = "BaseTouchController";
+
+ protected View mTouchView;
+ protected TouchListener mTouchListener;
+ protected boolean mIsActivated;
+ private boolean mIsDebugMode;
+
+ private View.OnTouchListener mDragTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ switch (motionEvent.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ Log.d(TAG, "ACTION_DOWN");
+ mTouchListener.onPress();
+ return true;
+ case MotionEvent.ACTION_UP:
+ Log.d(TAG, "ACTION_UP");
+ mTouchListener.onTap();
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+
+ public abstract View createTouchView(@NonNull Rect rect);
+
+ public abstract void destroyTouchView(@NonNull View touchView);
+
+ public abstract void moveTouchViewTo(@NonNull View touchView, @NonNull PointF position);
+
+ public void activate(@NonNull TouchListener touchListener, @NonNull Rect rect) {
+ if (!mIsActivated) {
+ Log.d(TAG, "Activating.");
+ mIsActivated = true;
+ mTouchListener = touchListener;
+ mTouchView = createTouchView(rect);
+ moveTouchViewTo(mTouchView, new PointF(rect.left, rect.top));
+ mTouchView.setOnTouchListener(mDragTouchListener);
+
+ updateTouchControlViewAppearance();
+ }
+ }
+
+ public void deactivate() {
+ if (mIsActivated) {
+ Log.d(TAG, "Deactivating.");
+ mTouchView.setOnTouchListener(null);
+ destroyTouchView(mTouchView);
+ mIsActivated = false;
+ mTouchView = null;
+ }
+ }
+
+ public void enableDebugMode(boolean isDebugMode) {
+ mIsDebugMode = isDebugMode;
+ updateTouchControlViewAppearance();
+ }
+
+ private void updateTouchControlViewAppearance() {
+ if (null != mTouchView) {
+ if (mIsDebugMode) {
+ mTouchView.setBackgroundColor(0x44FF0000);
+ } else {
+ mTouchView.setBackgroundColor(0x00000000);
+ }
+ }
+ }
+
+ public interface TouchListener {
+ void onPress();
+
+ void onTap();
+ }
+}
diff --git a/hover/src/main/java/io/mattcarroll/hover/Dragger.java b/hover/src/main/java/io/mattcarroll/hover/Dragger.java
index 0e2572d..e163cb2 100644
--- a/hover/src/main/java/io/mattcarroll/hover/Dragger.java
+++ b/hover/src/main/java/io/mattcarroll/hover/Dragger.java
@@ -15,44 +15,115 @@
*/
package io.mattcarroll.hover;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.support.annotation.NonNull;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
/**
* Reports user drag behavior on the screen to a {@link DragListener}.
*/
-public interface Dragger {
+public abstract class Dragger extends BaseTouchController {
+ private static final String TAG = "Dragger";
- /**
- * Starts reporting user drag behavior given a drag area represented by {@code controlBounds}.
- * @param dragListener listener that receives information about drag behavior
- * @param rect Rect area to be draggable
- */
- void activate(@NonNull DragListener dragListener, @NonNull Rect rect);
+ private final int mTapTouchSlop;
+ private DragListener mDragListener;
+ private boolean mIsDragging;
- /**
- * Stops monitoring and reporting user drag behavior.
- */
- void deactivate();
+ private PointF mOriginalViewPosition = new PointF();
+ private PointF mCurrentViewPosition = new PointF();
+ private PointF mOriginalTouchPosition = new PointF();
- /**
- * Enable/Disable debug mode. In debug mode this Dragger will paint its touch area with a
- * translucent color.
- * @param debugMode true for debug mode, false otherwise
- */
- void enableDebugMode(boolean debugMode);
+ protected final View.OnTouchListener mDragTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ switch (motionEvent.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ Log.d(TAG, "ACTION_DOWN");
+ mIsDragging = false;
- interface DragListener {
+ mOriginalViewPosition = convertCornerToCenter(getTouchViewPosition(mTouchView));
+ mCurrentViewPosition = new PointF(mOriginalViewPosition.x, mOriginalViewPosition.y);
+ mOriginalTouchPosition.set(motionEvent.getRawX(), motionEvent.getRawY());
+ mTouchListener.onPress();
+ return true;
+ case MotionEvent.ACTION_MOVE:
+ Log.d(TAG, "ACTION_MOVE. motionX: " + motionEvent.getRawX() + ", motionY: " + motionEvent.getRawY());
+ float dragDeltaX = motionEvent.getRawX() - mOriginalTouchPosition.x;
+ float dragDeltaY = motionEvent.getRawY() - mOriginalTouchPosition.y;
+ mCurrentViewPosition = new PointF(
+ mOriginalViewPosition.x + dragDeltaX,
+ mOriginalViewPosition.y + dragDeltaY
+ );
- /**
- * The user has pressed within the draggable area at the given position.
- * @param x x-coordinate of the user's press (in the parent View's coordinate space)
- * @param y y-coordiante of the user's press (in the parent View's coordinate space)
- */
- void onPress(float x, float y);
+ if (mIsDragging || !isTouchWithinSlopOfOriginalTouch(dragDeltaX, dragDeltaY)) {
+ if (!mIsDragging) {
+ // Dragging just started
+ Log.d(TAG, "MOVE Start Drag.");
+ mIsDragging = true;
+ mDragListener.onDragStart(mCurrentViewPosition.x, mCurrentViewPosition.y);
+ } else {
+ PointF cornerPosition = convertCenterToCorner(mCurrentViewPosition);
+ moveTouchViewTo(mTouchView, cornerPosition);
+ mDragListener.onDragTo(mCurrentViewPosition.x, mCurrentViewPosition.y);
+ }
+ }
+
+ return true;
+ case MotionEvent.ACTION_UP:
+ Log.d(TAG, "ACTION_UP");
+ if (!mIsDragging) {
+ Log.d(TAG, "Reporting as a tap.");
+ mTouchListener.onTap();
+ } else {
+ Log.d(TAG, "Reporting as a drag release at: " + mCurrentViewPosition);
+ mDragListener.onReleasedAt(mCurrentViewPosition.x, mCurrentViewPosition.y);
+ }
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+
+ public Dragger(int mTapTouchSlop) {
+ this.mTapTouchSlop = mTapTouchSlop;
+ }
+
+ public abstract PointF getTouchViewPosition(@NonNull View touchView);
+
+ public void activate(@NonNull DragListener dragListener, @NonNull Rect rect) {
+ super.activate(dragListener, rect);
+ mDragListener = dragListener;
+ mTouchView.setOnTouchListener(mDragTouchListener);
+ }
+
+ private boolean isTouchWithinSlopOfOriginalTouch(float dx, float dy) {
+ double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
+ Log.d(TAG, "Drag distance " + distance + " vs slop allowance " + mTapTouchSlop);
+ return distance < mTapTouchSlop;
+ }
+
+ private PointF convertCornerToCenter(@NonNull PointF cornerPosition) {
+ return new PointF(
+ cornerPosition.x + (mTouchView.getWidth() / 2f),
+ cornerPosition.y + (mTouchView.getHeight() / 2f)
+ );
+ }
+
+ private PointF convertCenterToCorner(@NonNull PointF centerPosition) {
+ return new PointF(
+ centerPosition.x - (mTouchView.getWidth() / 2f),
+ centerPosition.y - (mTouchView.getHeight() / 2f)
+ );
+ }
+ public interface DragListener extends TouchListener {
/**
* The user has begun dragging.
+ *
* @param x x-coordinate of the user's drag start (in the parent View's coordinate space)
* @param y y-coordiante of the user's drag start (in the parent View's coordinate space)
*/
@@ -60,6 +131,7 @@ interface DragListener {
/**
* The user has dragged to the given coordinates.
+ *
* @param x x-coordinate of the user's drag (in the parent View's coordinate space)
* @param y y-coordiante of the user's drag (in the parent View's coordinate space)
*/
@@ -67,15 +139,10 @@ interface DragListener {
/**
* The user has stopped touching the drag area.
+ *
* @param x x-coordinate of the user's release (in the parent View's coordinate space)
* @param y y-coordiante of the user's release (in the parent View's coordinate space)
*/
void onReleasedAt(float x, float y);
-
- /**
- * The user tapped the drag area (instead of dragging it).
- */
- void onTap();
-
}
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverView.java b/hover/src/main/java/io/mattcarroll/hover/HoverView.java
index 923122d..972abc3 100644
--- a/hover/src/main/java/io/mattcarroll/hover/HoverView.java
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverView.java
@@ -232,11 +232,9 @@ void restoreVisualState() {
persistentState.restore(this, mMenu);
}
- // TODO: when to call this?
public void release() {
Log.d(TAG, "Released.");
mDragger.deactivate();
- // TODO: should we also release the screen?
}
public void enableDebugMode(boolean debugMode) {
@@ -354,21 +352,21 @@ public void removeOnInteractionListener(@NonNull OnInteractionListener onInterac
mOnInteractionListeners.remove(onInteractionListener);
}
- void notifyOnTap() {
+ void notifyOnTap(HoverViewState state) {
for (OnInteractionListener onInteractionListener : mOnInteractionListeners) {
- onInteractionListener.onTap();
+ onInteractionListener.onTap(state.getStateType());
}
}
- void notifyOnDragStart() {
+ void notifyOnDragStart(HoverViewState state) {
for (OnInteractionListener onInteractionListener : mOnInteractionListeners) {
- onInteractionListener.onDragStart();
+ onInteractionListener.onDragStart(state.getStateType());
}
}
- void notifyOnDocked() {
+ void notifyOnDocked(HoverViewState state) {
for (OnInteractionListener onInteractionListener : mOnInteractionListeners) {
- onInteractionListener.onDocked();
+ onInteractionListener.onDocked(state.getStateType());
}
}
@@ -397,6 +395,7 @@ public void removeFromWindow() {
if (mIsAddedToWindow) {
mWindowViewController.removeView(this);
mIsAddedToWindow = false;
+ release();
}
}
@@ -609,10 +608,10 @@ public void onAnchored() {
}
public interface OnInteractionListener {
- void onTap();
+ void onTap(HoverViewStateType stateType);
- void onDragStart();
+ void onDragStart(HoverViewStateType stateType);
- void onDocked();
+ void onDocked(HoverViewStateType stateType);
}
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverViewState.java b/hover/src/main/java/io/mattcarroll/hover/HoverViewState.java
index c080668..6a175af 100644
--- a/hover/src/main/java/io/mattcarroll/hover/HoverViewState.java
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverViewState.java
@@ -49,4 +49,6 @@ interface HoverViewState {
* {@link #respondsToBackButton()} returns true.
*/
void onBackPressed();
+
+ HoverViewStateType getStateType();
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateAnchored.java b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateAnchored.java
index 992ed73..7a2c5ec 100644
--- a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateAnchored.java
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateAnchored.java
@@ -1,17 +1,26 @@
package io.mattcarroll.hover;
import android.graphics.Point;
+import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.util.Log;
-public class HoverViewStateAnchored extends BaseHoverViewState {
+class HoverViewStateAnchored extends BaseHoverViewState {
private static final String TAG = "HoverViewStateAnchored";
- private static final int ANCHOR_TAB_X_OFFSET_IN_PX = 100;
- private static final int ANCHOR_TAB_Y_OFFSET_IN_PX = 100;
private FloatingTab mSelectedTab;
- private Point mDock;
+ private HoverMenu.Section mSelectedSection;
+ private final BaseTouchController.TouchListener mTouchListener = new BaseTouchController.TouchListener() {
+ @Override
+ public void onPress() {
+ }
+
+ @Override
+ public void onTap() {
+ mHoverView.notifyOnTap(HoverViewStateAnchored.this);
+ }
+ };
@Override
public void takeControl(@NonNull HoverView hoverView, final Runnable onStateChanged) {
@@ -19,20 +28,28 @@ public void takeControl(@NonNull HoverView hoverView, final Runnable onStateChan
Log.d(TAG, "Taking control.");
mHoverView.makeUntouchableInWindow();
mHoverView.clearFocus();
- mDock = new Point(
- mHoverView.mScreen.getWidth() - ANCHOR_TAB_X_OFFSET_IN_PX,
- ANCHOR_TAB_Y_OFFSET_IN_PX
+ final int pointMargin = hoverView.getContext().getResources().getDimensionPixelSize(R.dimen.hover_tab_anchor_margin);
+ final Point anchorPoint = new Point(
+ mHoverView.mScreen.getWidth() - pointMargin,
+ mHoverView.mScreen.getHeight() - pointMargin
);
- HoverMenu.Section section = mHoverView.mMenu.getSection(0);
- mSelectedTab = mHoverView.mScreen.createChainedTab(section);
- mSelectedTab.setDock(new PositionDock(mDock));
+ mSelectedSection = mHoverView.mMenu.getSection(mHoverView.mSelectedSectionId);
+ if (mSelectedSection == null) {
+ mSelectedSection = mHoverView.mMenu.getSection(0);
+ }
+ mSelectedTab = mHoverView.mScreen.getChainedTab(mSelectedSection.getId());
+ if (mSelectedTab == null) {
+ mSelectedTab = mHoverView.mScreen.createChainedTab(mSelectedSection);
+ }
+ mSelectedTab.setDock(new PositionDock(anchorPoint));
mSelectedTab.dock(new Runnable() {
@Override
public void run() {
if (!hasControl()) {
return;
}
+ activateTouchController();
onStateChanged.run();
}
});
@@ -41,9 +58,20 @@ public void run() {
@Override
public void giveUpControl(@NonNull HoverViewState nextState) {
Log.d(TAG, "Giving up control.");
+ deactivateTouchController();
super.giveUpControl(nextState);
}
+ private void activateTouchController() {
+ final Rect visibleRect = new Rect();
+ mSelectedTab.getGlobalVisibleRect(visibleRect);
+ mHoverView.mDragger.activate(mTouchListener, visibleRect);
+ }
+
+ private void deactivateTouchController() {
+ mHoverView.mDragger.deactivate();
+ }
+
@Override
public boolean respondsToBackButton() {
return false;
@@ -52,4 +80,9 @@ public boolean respondsToBackButton() {
@Override
public void onBackPressed() {
}
+
+ @Override
+ public HoverViewStateType getStateType() {
+ return HoverViewStateType.ANCHORED;
+ }
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateClosed.java b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateClosed.java
index acddf2a..40f3da2 100644
--- a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateClosed.java
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateClosed.java
@@ -69,4 +69,9 @@ public void giveUpControl(@NonNull HoverViewState nextState) {
Log.d(TAG, "Giving up control.");
super.giveUpControl(nextState);
}
+
+ @Override
+ public HoverViewStateType getStateType() {
+ return HoverViewStateType.CLOSED;
+ }
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateCollapsed.java b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateCollapsed.java
index dd1b887..cb2ab16 100644
--- a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateCollapsed.java
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateCollapsed.java
@@ -207,7 +207,7 @@ private void onPickedUpByUser() {
mIsDocked = false;
mHoverView.mScreen.getExitView().setVisibility(VISIBLE);
restoreHoverViewAlphaValue();
- mHoverView.notifyOnDragStart();
+ mHoverView.notifyOnDragStart(this);
}
private void onDroppedByUser() {
@@ -245,7 +245,7 @@ private void onDroppedByUser() {
private void onTap() {
Log.d(TAG, "Floating tab was tapped.");
- mHoverView.notifyOnTap();
+ mHoverView.notifyOnTap(this);
}
private void sendToDock() {
@@ -296,7 +296,7 @@ private void onDocked() {
if (didJustCollapse) {
mOnStateChanged.run();
}
- mHoverView.notifyOnDocked();
+ mHoverView.notifyOnDocked(this);
}
protected void moveTabTo(@NonNull Point position) {
@@ -322,6 +322,11 @@ protected void restoreHoverViewAlphaValue() {
mHoverView.setAlpha(1f);
}
+ @Override
+ public HoverViewStateType getStateType() {
+ return HoverViewStateType.COLLAPSED;
+ }
+
protected static final class FloatingTabDragListener implements Dragger.DragListener {
private final HoverViewStateCollapsed mOwner;
@@ -330,9 +335,6 @@ protected FloatingTabDragListener(@NonNull HoverViewStateCollapsed owner) {
mOwner = owner;
}
- @Override
- public void onPress(float x, float y) { }
-
@Override
public void onDragStart(float x, float y) {
mOwner.onPickedUpByUser();
@@ -348,6 +350,10 @@ public void onReleasedAt(float x, float y) {
mOwner.onDroppedByUser();
}
+ @Override
+ public void onPress() {
+ }
+
@Override
public void onTap() {
mOwner.onTap();
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateExpanded.java b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateExpanded.java
index 7d0b123..483639a 100644
--- a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateExpanded.java
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateExpanded.java
@@ -459,4 +459,9 @@ private void selectSection(@NonNull HoverMenu.Section section) {
contentDisplay.selectedTabIs(mSelectedTab);
contentDisplay.displayContent(section.getContent());
}
+
+ @Override
+ public HoverViewStateType getStateType() {
+ return HoverViewStateType.EXPANDED;
+ }
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverViewStatePreviewed.java b/hover/src/main/java/io/mattcarroll/hover/HoverViewStatePreviewed.java
index 652ce7c..3ce8bcd 100644
--- a/hover/src/main/java/io/mattcarroll/hover/HoverViewStatePreviewed.java
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverViewStatePreviewed.java
@@ -74,4 +74,9 @@ protected void activateDragger() {
mHoverView.mDragger.activate(mDragListener, tabRect);
}
+
+ @Override
+ public HoverViewStateType getStateType() {
+ return HoverViewStateType.PREVIEWED;
+ }
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/HoverViewStateType.java b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateType.java
new file mode 100644
index 0000000..7435290
--- /dev/null
+++ b/hover/src/main/java/io/mattcarroll/hover/HoverViewStateType.java
@@ -0,0 +1,9 @@
+package io.mattcarroll.hover;
+
+public enum HoverViewStateType {
+ CLOSED,
+ COLLAPSED,
+ PREVIEWED,
+ EXPANDED,
+ ANCHORED,
+}
diff --git a/hover/src/main/java/io/mattcarroll/hover/view/InViewDragger.java b/hover/src/main/java/io/mattcarroll/hover/view/InViewDragger.java
index 1811bc2..ce0e528 100644
--- a/hover/src/main/java/io/mattcarroll/hover/view/InViewDragger.java
+++ b/hover/src/main/java/io/mattcarroll/hover/view/InViewDragger.java
@@ -18,8 +18,6 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.support.annotation.NonNull;
-import android.util.Log;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -29,165 +27,43 @@
/**
* {@link Dragger} implementation that works within a {@link ViewGroup}.
*/
-public class InViewDragger implements Dragger {
-
+public class InViewDragger extends Dragger {
private static final String TAG = "InViewDragger";
private final ViewGroup mContainer;
- private final int mTapTouchSlop;
- private boolean mIsActivated;
- private boolean mIsDragging;
- private boolean mIsDebugMode = false;
- private View mDragView;
- private DragListener mDragListener;
- private PointF mOriginalViewPosition = new PointF();
- private PointF mCurrentViewPosition = new PointF();
- private PointF mOriginalTouchPosition = new PointF();
-
- private final View.OnTouchListener mDragTouchListener = new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- switch (motionEvent.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Log.d(TAG, "ACTION_DOWN");
- mIsDragging = false;
-
- mOriginalViewPosition = getDragViewCenterPosition();
- mCurrentViewPosition = new PointF(mOriginalViewPosition.x, mOriginalViewPosition.y);
- mOriginalTouchPosition.set(motionEvent.getRawX(), motionEvent.getRawY());
-
- mDragListener.onPress(mCurrentViewPosition.x, mCurrentViewPosition.y);
-
- return true;
- case MotionEvent.ACTION_MOVE:
- Log.v(TAG, "ACTION_MOVE. motionX: " + motionEvent.getRawX() + ", motionY: " + motionEvent.getRawY());
- float dragDeltaX = motionEvent.getRawX() - mOriginalTouchPosition.x;
- float dragDeltaY = motionEvent.getRawY() - mOriginalTouchPosition.y;
- mCurrentViewPosition = new PointF(
- mOriginalViewPosition.x + dragDeltaX,
- mOriginalViewPosition.y + dragDeltaY
- );
-
- if (mIsDragging || !isTouchWithinSlopOfOriginalTouch(dragDeltaX, dragDeltaY)) {
- if (!mIsDragging) {
- // Dragging just started
- Log.d(TAG, "MOVE Start Drag.");
- mIsDragging = true;
- mDragListener.onDragStart(mCurrentViewPosition.x, mCurrentViewPosition.y);
- } else {
- moveDragViewTo(mCurrentViewPosition);
- mDragListener.onDragTo(mCurrentViewPosition.x, mCurrentViewPosition.y);
- }
- }
-
- return true;
- case MotionEvent.ACTION_UP:
- if (!mIsDragging) {
- Log.d(TAG, "ACTION_UP: Tap.");
- mDragListener.onTap();
- } else {
- Log.d(TAG, "ACTION_UP: Released from dragging.");
- mDragListener.onReleasedAt(mCurrentViewPosition.x, mCurrentViewPosition.y);
- }
-
- return true;
- default:
- return false;
- }
- }
- };
public InViewDragger(@NonNull ViewGroup container, int touchSlop) {
+ super(touchSlop);
mContainer = container;
- mTapTouchSlop = touchSlop;
}
@Override
- public void enableDebugMode(boolean isDebugMode) {
- mIsDebugMode = isDebugMode;
- updateTouchControlViewAppearance();
- }
-
- @Override
- public void activate(@NonNull DragListener dragListener, @NonNull Rect rect) {
- if (!mIsActivated) {
- Log.d(TAG, "Activating.");
- mIsActivated = true;
- mDragListener = dragListener;
- createTouchControlView(rect);
- }
- }
-
- @Override
- public void deactivate() {
- if (mIsActivated) {
- Log.d(TAG, "Deactivating.");
- mIsActivated = false;
- destroyTouchControlView();
- }
- }
-
- private void createTouchControlView(@NonNull Rect rect) {
- mDragView = new View(mContainer.getContext());
- mDragView.setId(R.id.hover_drag_view);
+ public View createTouchView(@NonNull Rect rect) {
+ View dragView = new View(mContainer.getContext());
+ dragView.setId(R.id.hover_drag_view);
final int width = rect.right - rect.left;
final int height = rect.bottom - rect.top;
- mDragView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
- mDragView.setOnTouchListener(mDragTouchListener);
- mContainer.addView(mDragView);
-
- moveDragViewTo(new PointF((rect.right + rect.left) / 2, (rect.bottom + rect.top) / 2));
- updateTouchControlViewAppearance();
- }
-
- private void destroyTouchControlView() {
- mContainer.removeView(mDragView);
-
- mDragView.setOnTouchListener(null);
- mDragView = null;
- }
-
- private void updateTouchControlViewAppearance() {
- if (null != mDragView) {
- if (mIsDebugMode) {
- Log.d(TAG, "Making mDragView red: " + mDragView.hashCode());
- mDragView.setBackgroundColor(0x44FF0000);
- } else {
- mDragView.setBackgroundColor(0x00000000);
- }
- }
- }
-
- private boolean isTouchWithinSlopOfOriginalTouch(float dx, float dy) {
- double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
- return distance < mTapTouchSlop;
+ dragView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
+ mContainer.addView(dragView);
+ return dragView;
}
- private PointF getDragViewCenterPosition() {
- return convertCornerToCenter(new PointF(
- mDragView.getX(),
- mDragView.getY()
- ));
- }
-
- private void moveDragViewTo(PointF centerPosition) {
- Log.d(TAG, "Moving drag view (" + mDragView.hashCode() + ") to: " + centerPosition);
- PointF cornerPosition = convertCenterToCorner(centerPosition);
- mDragView.setX(cornerPosition.x);
- mDragView.setY(cornerPosition.y);
+ @Override
+ public void destroyTouchView(@NonNull View touchView) {
+ mContainer.removeView(touchView);
}
- private PointF convertCornerToCenter(@NonNull PointF cornerPosition) {
+ @Override
+ public PointF getTouchViewPosition(@NonNull View touchView) {
return new PointF(
- cornerPosition.x + (mDragView.getWidth() / 2),
- cornerPosition.y + (mDragView.getHeight() / 2)
+ touchView.getX(),
+ touchView.getY()
);
}
- private PointF convertCenterToCorner(@NonNull PointF centerPosition) {
- return new PointF(
- centerPosition.x - (mDragView.getWidth() / 2),
- centerPosition.y - (mDragView.getHeight() / 2)
- );
+ @Override
+ public void moveTouchViewTo(@NonNull View touchView, @NonNull PointF position) {
+ touchView.setX(position.x);
+ touchView.setY(position.y);
}
}
diff --git a/hover/src/main/java/io/mattcarroll/hover/window/InWindowDragger.java b/hover/src/main/java/io/mattcarroll/hover/window/InWindowDragger.java
index aac914a..d65759f 100755
--- a/hover/src/main/java/io/mattcarroll/hover/window/InWindowDragger.java
+++ b/hover/src/main/java/io/mattcarroll/hover/window/InWindowDragger.java
@@ -16,12 +16,9 @@
package io.mattcarroll.hover.window;
import android.content.Context;
-import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.support.annotation.NonNull;
-import android.util.Log;
-import android.view.MotionEvent;
import android.view.View;
import io.mattcarroll.hover.Dragger;
@@ -29,176 +26,41 @@
/**
* {@link Dragger} implementation that works within a {@code Window}.
*/
-public class InWindowDragger implements Dragger {
-
+public class InWindowDragger extends Dragger {
private static final String TAG = "InWindowDragger";
private final Context mContext;
private final WindowViewController mWindowViewController;
- private final float mTapTouchSlop;
- private View mDragView;
- private Dragger.DragListener mDragListener;
- private boolean mIsActivated;
- private boolean mIsDragging;
- private boolean mIsDebugMode;
-
- private PointF mOriginalViewPosition = new PointF();
- private PointF mCurrentViewPosition = new PointF();
- private PointF mOriginalTouchPosition = new PointF();
-
- private View.OnTouchListener mDragTouchListener = new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- switch (motionEvent.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Log.d(TAG, "ACTION_DOWN");
- mIsDragging = false;
-
- mOriginalViewPosition = getDragViewCenterPosition();
- mCurrentViewPosition = new PointF(mOriginalViewPosition.x, mOriginalViewPosition.y);
- mOriginalTouchPosition.set(motionEvent.getRawX(), motionEvent.getRawY());
-
- mDragListener.onPress(mCurrentViewPosition.x, mCurrentViewPosition.y);
-
- return true;
- case MotionEvent.ACTION_MOVE:
- Log.d(TAG, "ACTION_MOVE. motionX: " + motionEvent.getRawX() + ", motionY: " + motionEvent.getRawY());
- float dragDeltaX = motionEvent.getRawX() - mOriginalTouchPosition.x;
- float dragDeltaY = motionEvent.getRawY() - mOriginalTouchPosition.y;
- mCurrentViewPosition = new PointF(
- mOriginalViewPosition.x + dragDeltaX,
- mOriginalViewPosition.y + dragDeltaY
- );
-
- if (mIsDragging || !isTouchWithinSlopOfOriginalTouch(dragDeltaX, dragDeltaY)) {
- if (!mIsDragging) {
- // Dragging just started
- Log.d(TAG, "MOVE Start Drag.");
- mIsDragging = true;
- mDragListener.onDragStart(mCurrentViewPosition.x, mCurrentViewPosition.y);
- } else {
- moveDragViewTo(mCurrentViewPosition);
- mDragListener.onDragTo(mCurrentViewPosition.x, mCurrentViewPosition.y);
- }
- }
-
- return true;
- case MotionEvent.ACTION_UP:
- Log.d(TAG, "ACTION_UP");
- if (!mIsDragging) {
- Log.d(TAG, "Reporting as a tap.");
- mDragListener.onTap();
- } else {
- Log.d(TAG, "Reporting as a drag release at: " + mCurrentViewPosition);
- mDragListener.onReleasedAt(mCurrentViewPosition.x, mCurrentViewPosition.y);
- }
- return true;
- default:
- return false;
- }
- }
- };
-
- /**
- * Note: {@code view} must already be added to the {@code Window}.
- * @param context context
- * @param windowViewController windowViewController
- * @param tapTouchSlop tapTouchSlop
- */
public InWindowDragger(@NonNull Context context,
@NonNull WindowViewController windowViewController,
- float tapTouchSlop) {
+ int tapTouchSlop) {
+ super(tapTouchSlop);
mContext = context;
mWindowViewController = windowViewController;
- mTapTouchSlop = tapTouchSlop;
- }
-
- @Override
- public void activate(@NonNull DragListener dragListener, @NonNull Rect rect) {
- if (!mIsActivated) {
- Log.d(TAG, "Activating.");
- createTouchControlView(rect);
- mDragListener = dragListener;
- mDragView.setOnTouchListener(mDragTouchListener);
- mIsActivated = true;
- }
- }
-
- @Override
- public void deactivate() {
- if (mIsActivated) {
- Log.d(TAG, "Deactivating.");
- mDragView.setOnTouchListener(null);
- destroyTouchControlView();
- mIsActivated = false;
- }
}
@Override
- public void enableDebugMode(boolean isDebugMode) {
- mIsDebugMode = isDebugMode;
- updateTouchControlViewAppearance();
- }
-
- private void createTouchControlView(@NonNull Rect rect) {
- mDragView = new View(mContext);
+ public View createTouchView(@NonNull Rect rect) {
+ View dragView = new View(mContext);
final int width = rect.right - rect.left;
final int height = rect.bottom - rect.top;
- mWindowViewController.addView(width, height, true, mDragView);
- mWindowViewController.moveViewTo(mDragView, rect.left, rect.top);
- mDragView.setOnTouchListener(mDragTouchListener);
-
- updateTouchControlViewAppearance();
- }
-
- private void destroyTouchControlView() {
- mWindowViewController.removeView(mDragView);
- mDragView = null;
- }
-
- private void updateTouchControlViewAppearance() {
- if (null != mDragView) {
- if (mIsDebugMode) {
- mDragView.setBackgroundColor(0x44FF0000);
- } else {
- mDragView.setBackgroundColor(0x00000000);
- }
- }
+ mWindowViewController.addView(width, height, true, dragView);
+ return dragView;
}
- private boolean isTouchWithinSlopOfOriginalTouch(float dx, float dy) {
- double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
- Log.d(TAG, "Drag distance " + distance + " vs slop allowance " + mTapTouchSlop);
- return distance < mTapTouchSlop;
- }
-
- private PointF getDragViewCenterPosition() {
- Point cornerPosition = mWindowViewController.getViewPosition(mDragView);
- return convertCornerToCenter(new PointF(
- cornerPosition.x,
- cornerPosition.y
- ));
- }
-
- private void moveDragViewTo(PointF centerPosition) {
- Log.d(TAG, "Center position: " + centerPosition);
- PointF cornerPosition = convertCenterToCorner(centerPosition);
- Log.d(TAG, "Corner position: " + cornerPosition);
- mWindowViewController.moveViewTo(mDragView, (int) cornerPosition.x, (int) cornerPosition.y);
+ @Override
+ public void destroyTouchView(@NonNull View touchView) {
+ mWindowViewController.removeView(touchView);
}
- private PointF convertCornerToCenter(@NonNull PointF cornerPosition) {
- return new PointF(
- cornerPosition.x + (mDragView.getWidth() / 2),
- cornerPosition.y + (mDragView.getHeight() / 2)
- );
+ @Override
+ public PointF getTouchViewPosition(@NonNull View touchView) {
+ return new PointF(mWindowViewController.getViewPosition(touchView));
}
- private PointF convertCenterToCorner(@NonNull PointF centerPosition) {
- return new PointF(
- centerPosition.x - (mDragView.getWidth() / 2),
- centerPosition.y - (mDragView.getHeight() / 2)
- );
+ @Override
+ public void moveTouchViewTo(@NonNull View touchView, @NonNull PointF position) {
+ mWindowViewController.moveViewTo(touchView, (int) position.x, (int) position.y);
}
}
diff --git a/hover/src/main/res/values/dimens.xml b/hover/src/main/res/values/dimens.xml
index 0023349..51aeba3 100755
--- a/hover/src/main/res/values/dimens.xml
+++ b/hover/src/main/res/values/dimens.xml
@@ -6,4 +6,5 @@
75dp
32dp
24dp
+ 32dp