Bug 1396076 - Part 1 - Add a HoverDelegate class. r?jwu
This is more or less a straight copy of our TouchDelegateWithReset class adapted to using HoverEvents instead of TouchEvents.
MozReview-Commit-ID: KtQvf1is5xK
copy from mobile/android/base/java/org/mozilla/gecko/widget/TouchDelegateWithReset.java
copy to mobile/android/base/java/org/mozilla/gecko/widget/HoverDelegateWithReset.java
--- a/mobile/android/base/java/org/mozilla/gecko/widget/TouchDelegateWithReset.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/HoverDelegateWithReset.java
@@ -1,42 +1,39 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.widget;
import android.graphics.Rect;
import android.view.MotionEvent;
-import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewConfiguration;
/**
- * This is a copy of TouchDelegate from
- * https://github.com/android/platform_frameworks_base/blob/4b1a8f46d6ec55796bf77fd8921a5a242a219278/core/java/android/view/TouchDelegate.java
- * with a fix to reset mDelegateTargeted on each new gesture - the sole substantive change is a new
- * else leg in the ACTION_DOWN case of onTouchEvent marked by "START|END BUG FIX" comments.
+ * This is an implementation of a delegate class for hover events along the lines of TouchDelegate,
+ * based on our fixed copy in TouchDelegateWithReset.java.
*/
/**
- * Helper class to handle situations where you want a view to have a larger touch area than its
- * actual view bounds. The view whose touch area is changed is called the delegate view. This
- * class should be used by an ancestor of the delegate. To use a TouchDelegate, first create an
+ * Helper class to handle situations where you want a view to have a larger hover area than its
+ * actual view bounds. The view whose hover area is changed is called the delegate view. This
+ * class should be used by an ancestor of the delegate. To use a HoverDelegate, first create an
* instance that specifies the bounds that should be mapped to the delegate and the delegate
* view itself.
* <p>
- * The ancestor should then forward all of its touch events received in its
- * {@link android.view.View#onTouchEvent(MotionEvent)} to {@link #onTouchEvent(MotionEvent)}.
+ * The ancestor should then forward all of its hover events received in its
+ * {@link android.view.View#onHoverEvent(MotionEvent)} to {@link #onHoverEvent(MotionEvent)}.
* </p>
*/
-public class TouchDelegateWithReset extends TouchDelegate {
+public class HoverDelegateWithReset {
/**
- * View that should receive forwarded touch events
+ * View that should receive forwarded hover events
*/
private View mDelegateView;
/**
* Bounds in local coordinates of the containing view that should be mapped to the delegate
* view. This rect is used for initial hit testing.
*/
private Rect mBounds;
@@ -56,57 +53,54 @@ public class TouchDelegateWithReset exte
/**
* Constructor
*
* @param bounds Bounds in local coordinates of the containing view that should be mapped to
* the delegate view
* @param delegateView The view that should receive motion events
*/
- public TouchDelegateWithReset(Rect bounds, View delegateView) {
- super(bounds, delegateView);
-
+ public HoverDelegateWithReset(Rect bounds, View delegateView) {
mBounds = bounds;
mSlop = ViewConfiguration.get(delegateView.getContext()).getScaledTouchSlop();
mSlopBounds = new Rect(bounds);
mSlopBounds.inset(-mSlop, -mSlop);
mDelegateView = delegateView;
}
/**
- * Will forward touch events to the delegate view if the event is within the bounds
+ * Will forward hover events to the delegate view if the event is within the bounds
* specified in the constructor.
*
- * @param event The touch event to forward
+ * @param event The hover event to forward
* @return True if the event was forwarded to the delegate, false otherwise.
*/
- @Override
- public boolean onTouchEvent(MotionEvent event) {
+ public boolean onHoverEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
boolean sendToDelegate = false;
boolean hit = true;
boolean handled = false;
switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_HOVER_ENTER:
Rect bounds = mBounds;
if (bounds.contains(x, y)) {
mDelegateTargeted = true;
sendToDelegate = true;
} /* START BUG FIX */
else {
mDelegateTargeted = false;
}
/* END BUG FIX */
break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_MOVE:
+ case MotionEvent.ACTION_HOVER_EXIT:
+ case MotionEvent.ACTION_HOVER_MOVE:
sendToDelegate = mDelegateTargeted;
if (sendToDelegate) {
Rect slopBounds = mSlopBounds;
if (!slopBounds.contains(x, y)) {
hit = false;
}
}
break;
@@ -122,13 +116,13 @@ public class TouchDelegateWithReset exte
// Offset event coordinates to be inside the target view
event.setLocation(delegateView.getWidth() / 2, delegateView.getHeight() / 2);
} else {
// Offset event coordinates to be outside the target view (in case it does
// something like tracking pressed state)
int slop = mSlop;
event.setLocation(-(slop * 2), -(slop * 2));
}
- handled = delegateView.dispatchTouchEvent(event);
+ handled = delegateView.dispatchGenericMotionEvent(event);
}
return handled;
}
}
\ No newline at end of file
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -989,16 +989,17 @@ gbjar.sources += ['java/org/mozilla/geck
'widget/FadedTextView.java',
'widget/FaviconView.java',
'widget/FilledCardView.java',
'widget/FlowLayout.java',
'widget/GeckoActionProvider.java',
'widget/GeckoPopupMenu.java',
'widget/GridSpacingDecoration.java',
'widget/HistoryDividerItemDecoration.java',
+ 'widget/HoverDelegateWithReset.java',
'widget/IconTabWidget.java',
'widget/LoginDoorHanger.java',
'widget/RecyclerViewClickSupport.java',
'widget/ResizablePathDrawable.java',
'widget/RoundedCornerLayout.java',
'widget/SiteLogins.java',
'widget/SplashScreen.java',
'widget/SquaredImageView.java',