mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-23 20:01:01 +08:00
Separate Node bounds and hit bounds within node region where needed.
Summary: Node region bounds are assumed to equal the underlying node bounds. In the case of hit slop, these need to be abstracted. Reviewed By: ahmedre Differential Revision: D3713430
This commit is contained in:
committed by
Ahmed El-Helw
parent
a602891946
commit
4a12efad02
@@ -187,9 +187,7 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
||||
if (mountsToView()) {
|
||||
return mViewRight - mViewLeft;
|
||||
} else {
|
||||
// this is not technically correct since hitSlop affects the NodeRegion, but it's a temporary
|
||||
// work around for now, since mView{Right,Left} are only set for views
|
||||
return Math.round(mNodeRegion.mRight - mNodeRegion.mLeft);
|
||||
return Math.round(mNodeRegion.getRight() - mNodeRegion.getLeft());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,9 +196,7 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
||||
if (mountsToView()) {
|
||||
return mViewBottom - mViewTop;
|
||||
} else {
|
||||
// this is not technically correct since hitSlop affects the NodeRegion, but it's a temporary
|
||||
// work around for now, since mView{Bottom,Top} are only set for views
|
||||
return Math.round(mNodeRegion.mBottom - mNodeRegion.mTop);
|
||||
return Math.round(mNodeRegion.getBottom() - mNodeRegion.getTop());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,8 +328,8 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
||||
|
||||
/* package */ final void updateOverflowsContainer() {
|
||||
boolean overflowsContainer = false;
|
||||
int width = (int) (mNodeRegion.mRight - mNodeRegion.mLeft);
|
||||
int height = (int) (mNodeRegion.mBottom - mNodeRegion.mTop);
|
||||
int width = (int) (mNodeRegion.getRight() - mNodeRegion.getLeft());
|
||||
int height = (int) (mNodeRegion.getBottom() - mNodeRegion.getTop());
|
||||
|
||||
float leftBound = 0;
|
||||
float rightBound = width;
|
||||
@@ -349,23 +345,23 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
||||
// to clip certain subviews.
|
||||
if (!mClipToBounds && height > 0 && width > 0) {
|
||||
for (NodeRegion region : mNodeRegions) {
|
||||
if (region.mLeft < leftBound) {
|
||||
leftBound = region.mLeft;
|
||||
if (region.getLeft() < leftBound) {
|
||||
leftBound = region.getLeft();
|
||||
overflowsContainer = true;
|
||||
}
|
||||
|
||||
if (region.mRight > rightBound) {
|
||||
rightBound = region.mRight;
|
||||
if (region.getRight() > rightBound) {
|
||||
rightBound = region.getRight();
|
||||
overflowsContainer = true;
|
||||
}
|
||||
|
||||
if (region.mTop < topBound) {
|
||||
topBound = region.mTop;
|
||||
if (region.getTop() < topBound) {
|
||||
topBound = region.getTop();
|
||||
overflowsContainer = true;
|
||||
}
|
||||
|
||||
if (region.mBottom > bottomBound) {
|
||||
bottomBound = region.mBottom;
|
||||
if (region.getBottom() > bottomBound) {
|
||||
bottomBound = region.getBottom();
|
||||
overflowsContainer = true;
|
||||
}
|
||||
}
|
||||
@@ -424,8 +420,7 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
|
||||
float right,
|
||||
float bottom,
|
||||
boolean isVirtual) {
|
||||
if (mNodeRegion.mLeft != left || mNodeRegion.mTop != top || mNodeRegion.mRight != right ||
|
||||
mNodeRegion.mBottom != bottom || mNodeRegion.mIsVirtual != isVirtual) {
|
||||
if (!mNodeRegion.matches(left, top, right, bottom, isVirtual)) {
|
||||
setNodeRegion(new NodeRegion(left, top, right, bottom, getReactTag(), isVirtual));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,12 +356,12 @@ import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
}
|
||||
|
||||
int resultTag = region == NodeRegion.EMPTY ? touchTargetReactTag : region.mTag;
|
||||
float x = PixelUtil.toDIPFromPixel(region.mLeft + MEASURE_BUFFER[0] - containerX);
|
||||
float y = PixelUtil.toDIPFromPixel(region.mTop + MEASURE_BUFFER[1] - containerY);
|
||||
float x = PixelUtil.toDIPFromPixel(region.getLeft() + MEASURE_BUFFER[0] - containerX);
|
||||
float y = PixelUtil.toDIPFromPixel(region.getTop() + MEASURE_BUFFER[1] - containerY);
|
||||
float width = PixelUtil.toDIPFromPixel(isNativeView ?
|
||||
MEASURE_BUFFER[2] : region.mRight - region.mLeft);
|
||||
MEASURE_BUFFER[2] : region.getRight() - region.getLeft());
|
||||
float height = PixelUtil.toDIPFromPixel(isNativeView ?
|
||||
MEASURE_BUFFER[3] : region.mBottom - region.mTop);
|
||||
MEASURE_BUFFER[3] : region.getBottom() - region.getTop());
|
||||
mCallback.invoke(resultTag, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.flat;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* NodeRegion that has a hit slop.
|
||||
*/
|
||||
/* package */ final class HitSlopNodeRegion extends NodeRegion {
|
||||
|
||||
private final Rect mHitSlop;
|
||||
|
||||
HitSlopNodeRegion(
|
||||
Rect hitSlop,
|
||||
float left,
|
||||
float top,
|
||||
float right,
|
||||
float bottom,
|
||||
int tag,
|
||||
boolean isVirtual) {
|
||||
super(left, top, right, bottom, tag, isVirtual);
|
||||
mHitSlop = hitSlop;
|
||||
}
|
||||
|
||||
@Override
|
||||
/* package */ float getTouchableLeft() {
|
||||
return getLeft() - mHitSlop.left;
|
||||
}
|
||||
|
||||
@Override
|
||||
/* package */ float getTouchableTop() {
|
||||
return getTop() - mHitSlop.top;
|
||||
}
|
||||
|
||||
@Override
|
||||
/* package */ float getTouchableRight() {
|
||||
return getRight() + mHitSlop.right;
|
||||
}
|
||||
|
||||
@Override
|
||||
/* package */ float getTouchableBottom() {
|
||||
return getBottom() + mHitSlop.bottom;
|
||||
}
|
||||
|
||||
@Override
|
||||
/* package */ boolean withinBounds(float touchX, float touchY) {
|
||||
return getTouchableLeft() <= touchX && touchX < getTouchableRight() &&
|
||||
getTouchableTop() <= touchY && touchY < getTouchableBottom();
|
||||
}
|
||||
}
|
||||
@@ -70,11 +70,11 @@ import android.util.SparseIntArray;
|
||||
public static void fillMaxMinArrays(NodeRegion[] regions, float[] maxRight, float[] minLeft) {
|
||||
float last = 0;
|
||||
for (int i = 0; i < regions.length; i++) {
|
||||
last = Math.max(last, regions[i].mRight);
|
||||
last = Math.max(last, regions[i].getTouchableRight());
|
||||
maxRight[i] = last;
|
||||
}
|
||||
for (int i = regions.length - 1; i >= 0; i--) {
|
||||
last = Math.min(last, regions[i].mLeft);
|
||||
last = Math.min(last, regions[i].getTouchableLeft());
|
||||
minLeft[i] = last;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ package com.facebook.react.flat;
|
||||
/* package */ static final NodeRegion[] EMPTY_ARRAY = new NodeRegion[0];
|
||||
/* package */ static final NodeRegion EMPTY = new NodeRegion(0, 0, 0, 0, -1, false);
|
||||
|
||||
/* package */ final float mLeft;
|
||||
/* package */ final float mTop;
|
||||
/* package */ final float mRight;
|
||||
/* package */ final float mBottom;
|
||||
private final float mLeft;
|
||||
private final float mTop;
|
||||
private final float mRight;
|
||||
private final float mBottom;
|
||||
/* package */ final int mTag;
|
||||
/* package */ final boolean mIsVirtual;
|
||||
|
||||
@@ -41,12 +41,88 @@ package com.facebook.react.flat;
|
||||
float right,
|
||||
float bottom,
|
||||
boolean isVirtual) {
|
||||
return left == mLeft && top == mTop && bottom == mBottom && right == mRight &&
|
||||
return left == mLeft && top == mTop && right == mRight && bottom == mBottom &&
|
||||
isVirtual == mIsVirtual;
|
||||
}
|
||||
|
||||
/* package */ final boolean withinBounds(float touchX, float touchY) {
|
||||
return mLeft <= touchX && touchX < mRight && mTop <= touchY && touchY < mBottom;
|
||||
/**
|
||||
* The left bound of the underlying node.
|
||||
*
|
||||
* @return The node bound.
|
||||
*/
|
||||
/* package */ final float getLeft() {
|
||||
return mLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* The top bound of the underlying node.
|
||||
*
|
||||
* @return The node bound.
|
||||
*/
|
||||
/* package */ final float getTop() {
|
||||
return mTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* The right bound of the underlying node.
|
||||
*
|
||||
* @return The node bound.
|
||||
*/
|
||||
/* package */ final float getRight() {
|
||||
return mRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom bound of the underlying node.
|
||||
*
|
||||
* @return The node bound.
|
||||
*/
|
||||
/* package */ final float getBottom() {
|
||||
return mBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* The left bound of the region for the purpose of touch. This is usually the bound of the
|
||||
* underlying node, except in the case of hit slop.
|
||||
*
|
||||
* @return The touch bound.
|
||||
*/
|
||||
/* package */ float getTouchableLeft() {
|
||||
return getLeft();
|
||||
}
|
||||
|
||||
/**
|
||||
* The top bound of the region for the purpose of touch. This is usually the bound of the
|
||||
* underlying node, except in the case of hit slop.
|
||||
*
|
||||
* @return The touch bound.
|
||||
*/
|
||||
/* package */ float getTouchableTop() {
|
||||
return getTop();
|
||||
}
|
||||
|
||||
/**
|
||||
* The right bound of the region for the purpose of touch. This is usually the bound of the
|
||||
* underlying node, except in the case of hit slop.
|
||||
*
|
||||
* @return The touch bound.
|
||||
*/
|
||||
/* package */ float getTouchableRight() {
|
||||
return getRight();
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom bound of the region for the purpose of touch. This is usually the bound of the
|
||||
* underlying node, except in the case of hit slop.
|
||||
*
|
||||
* @return The touch bound.
|
||||
*/
|
||||
/* package */ float getTouchableBottom() {
|
||||
return getBottom();
|
||||
}
|
||||
|
||||
/* package */ boolean withinBounds(float touchX, float touchY) {
|
||||
return mLeft <= touchX && touchX < mRight && mTop <= touchY && touchY < mBottom;
|
||||
}
|
||||
|
||||
/* package */ int getReactTag(float touchX, float touchY) {
|
||||
|
||||
@@ -225,8 +225,7 @@ import com.facebook.textcachewarmer.DefaultTextLayoutCacheWarmer;
|
||||
|
||||
NodeRegion nodeRegion = getNodeRegion();
|
||||
if (mDrawCommand == null) {
|
||||
if (nodeRegion.mLeft != left || nodeRegion.mTop != top || nodeRegion.mRight != right ||
|
||||
nodeRegion.mBottom != bottom || nodeRegion.mIsVirtual != isVirtual) {
|
||||
if (!nodeRegion.matches(left, top, right, bottom, isVirtual)) {
|
||||
setNodeRegion(new TextNodeRegion(left, top, right, bottom, getReactTag(), isVirtual, null));
|
||||
}
|
||||
return;
|
||||
@@ -239,9 +238,7 @@ import com.facebook.textcachewarmer.DefaultTextLayoutCacheWarmer;
|
||||
}
|
||||
|
||||
Layout newLayout = mDrawCommand.getLayout();
|
||||
if (nodeRegion.mLeft != left || nodeRegion.mTop != top ||
|
||||
nodeRegion.mRight != right || nodeRegion.mBottom != bottom ||
|
||||
nodeRegion.mIsVirtual != isVirtual || layout != newLayout) {
|
||||
if (!nodeRegion.matches(left, top, right, bottom, isVirtual) || layout != newLayout) {
|
||||
setNodeRegion(
|
||||
new TextNodeRegion(left, top, right, bottom, getReactTag(), isVirtual, newLayout));
|
||||
}
|
||||
|
||||
@@ -155,15 +155,10 @@ import com.facebook.react.uimanager.annotations.ReactPropGroup;
|
||||
float right,
|
||||
float bottom,
|
||||
boolean isVirtual) {
|
||||
if (mHitSlop != null) {
|
||||
left -= mHitSlop.left;
|
||||
top -= mHitSlop.top;
|
||||
bottom += mHitSlop.bottom;
|
||||
right += mHitSlop.right;
|
||||
}
|
||||
|
||||
if (!getNodeRegion().matches(left, top, right, bottom, isVirtual)) {
|
||||
setNodeRegion(new NodeRegion(left, top, right, bottom, getReactTag(), isVirtual));
|
||||
setNodeRegion(mHitSlop == null ?
|
||||
new NodeRegion(left, top, right, bottom, getReactTag(), isVirtual) :
|
||||
new HitSlopNodeRegion(mHitSlop, left, top, right, bottom, getReactTag(), isVirtual));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@ import android.text.Spanned;
|
||||
if (mLayout != null) {
|
||||
CharSequence text = mLayout.getText();
|
||||
if (text instanceof Spanned) {
|
||||
int y = Math.round(touchY - mTop);
|
||||
int y = Math.round(touchY - getTop());
|
||||
if (y >= mLayout.getLineTop(0) && y < mLayout.getLineBottom(mLayout.getLineCount() - 1)) {
|
||||
float x = Math.round(touchX - mLeft);
|
||||
float x = Math.round(touchX - getLeft());
|
||||
int line = mLayout.getLineForVertical(y);
|
||||
|
||||
if (mLayout.getLineLeft(line) <= x && x <= mLayout.getLineRight(line)) {
|
||||
|
||||
@@ -70,11 +70,11 @@ import android.util.SparseIntArray;
|
||||
public static void fillMaxMinArrays(NodeRegion[] regions, float[] maxBottom, float[] minTop) {
|
||||
float last = 0;
|
||||
for (int i = 0; i < regions.length; i++) {
|
||||
last = Math.max(last, regions[i].mBottom);
|
||||
last = Math.max(last, regions[i].getTouchableBottom());
|
||||
maxBottom[i] = last;
|
||||
}
|
||||
for (int i = regions.length - 1; i >= 0; i--) {
|
||||
last = Math.min(last, regions[i].mTop);
|
||||
last = Math.min(last, regions[i].getTouchableTop());
|
||||
minTop[i] = last;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user