Skip to content

Commit

Permalink
Merge branch 'main' into @latekvo/fix-nested-gesture-stealing-activit…
Browse files Browse the repository at this point in the history
…y-from-native-gesture
  • Loading branch information
latekvo authored Sep 17, 2024
2 parents 208d664 + 56008d2 commit e82b044
Show file tree
Hide file tree
Showing 17 changed files with 337 additions and 408 deletions.
3 changes: 1 addition & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ android {
externalNativeBuild {
cmake {
cppFlags "-O2", "-frtti", "-fexceptions", "-Wall", "-Werror", "-std=c++20", "-DANDROID"
arguments "-DAPP_BUILD_DIR=${appProject.buildDir}",
"-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
arguments "-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
"-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
"-DANDROID_STL=c++_shared"
abiFilters (*reactNativeArchitectures())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,22 +286,11 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager<ButtonViewGroup>(), R
return false
}

private fun updateBackgroundColor(backgroundColor: Int, selectable: Drawable?) {
private fun updateBackgroundColor(backgroundColor: Int, borderDrawable: Drawable, selectable: Drawable?) {
val colorDrawable = PaintDrawable(backgroundColor)
val borderDrawable = PaintDrawable(Color.TRANSPARENT)

if (hasBorderRadii) {
colorDrawable.setCornerRadii(buildBorderRadii())
borderDrawable.setCornerRadii(buildBorderRadii())
}

if (borderWidth > 0f) {
borderDrawable.paint.apply {
style = Paint.Style.STROKE
strokeWidth = borderWidth
color = borderColor ?: Color.BLACK
pathEffect = buildBorderStyle()
}
}

val layerDrawable = LayerDrawable(if (selectable != null) arrayOf(colorDrawable, selectable, borderDrawable) else arrayOf(colorDrawable, borderDrawable))
Expand All @@ -324,6 +313,7 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager<ButtonViewGroup>(), R
}

val selectable = createSelectableDrawable()
val borderDrawable = createBorderDrawable()

if (hasBorderRadii && selectable is RippleDrawable) {
val mask = PaintDrawable(Color.WHITE)
Expand All @@ -334,13 +324,32 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager<ButtonViewGroup>(), R
if (useDrawableOnForeground && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
foreground = selectable
if (_backgroundColor != Color.TRANSPARENT) {
updateBackgroundColor(_backgroundColor, null)
updateBackgroundColor(_backgroundColor, borderDrawable, null)
}
} else if (_backgroundColor == Color.TRANSPARENT && rippleColor == null) {
background = selectable
background = LayerDrawable(arrayOf(selectable, borderDrawable))
} else {
updateBackgroundColor(_backgroundColor, selectable)
updateBackgroundColor(_backgroundColor, borderDrawable, selectable)
}
}

private fun createBorderDrawable(): Drawable {
val borderDrawable = PaintDrawable(Color.TRANSPARENT)

if (hasBorderRadii) {
borderDrawable.setCornerRadii(buildBorderRadii())
}

if (borderWidth > 0f) {
borderDrawable.paint.apply {
style = Paint.Style.STROKE
strokeWidth = borderWidth
color = borderColor ?: Color.BLACK
pathEffect = buildBorderStyle()
}
}

return borderDrawable
}

private fun createSelectableDrawable(): Drawable? {
Expand Down
2 changes: 2 additions & 0 deletions apple/Handlers/RNLongPressHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,12 @@ - (void)configure:(NSDictionary *)config
recognizer.allowableMovement = [RCTConvert CGFloat:prop];
}

#if !TARGET_OS_TV
prop = config[@"numberOfPointers"];
if (prop != nil) {
recognizer.numberOfTouchesRequired = [RCTConvert CGFloat:prop];
}
#endif
}

#if !TARGET_OS_OSX
Expand Down
35 changes: 35 additions & 0 deletions apple/RNGestureHandlerButtonComponentView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,41 @@ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childCompo
[_buttonView unmountChildComponentView:childComponentView index:index];
}

- (LayoutMetrics)buildWrapperMetrics:(const LayoutMetrics &)metrics
{
LayoutMetrics result = metrics;
result.borderWidth = EdgeInsets::ZERO;
result.contentInsets = EdgeInsets::ZERO;
return result;
}

- (LayoutMetrics)buildButtonMetrics:(const LayoutMetrics &)metrics
{
LayoutMetrics result = metrics;
result.frame.origin = {0, 0};
return result;
}

- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics
{
// due to nested structure of Button and ComponentView, layout metrics for both
// need to be modified:
// - wrapper shouldn't have any insets as they should be applied to the button
// so that it can intercept touches on padding and borders, applying them
// twice breaks expected layout
// - frame origin needs to be zeroes on metrics of the button as it should fill
// the entirety of the wrapper component
const LayoutMetrics wrapperMetrics = [self buildWrapperMetrics:layoutMetrics];
const LayoutMetrics oldWrapperMetrics = [self buildWrapperMetrics:oldLayoutMetrics];

const LayoutMetrics buttonMetrics = [self buildButtonMetrics:layoutMetrics];
const LayoutMetrics oldbuttonMetrics = [self buildButtonMetrics:oldLayoutMetrics];

[super updateLayoutMetrics:wrapperMetrics oldLayoutMetrics:oldWrapperMetrics];
[_buttonView updateLayoutMetrics:buttonMetrics oldLayoutMetrics:oldbuttonMetrics];
}

#pragma mark - RCTComponentViewProtocol

+ (ComponentDescriptorProvider)componentDescriptorProvider
Expand Down
Loading

0 comments on commit e82b044

Please sign in to comment.