diff --git a/android/src/main/java/com/horcrux/svg/RenderableView.java b/android/src/main/java/com/horcrux/svg/RenderableView.java index e7769b2a..d575faf2 100644 --- a/android/src/main/java/com/horcrux/svg/RenderableView.java +++ b/android/src/main/java/com/horcrux/svg/RenderableView.java @@ -27,6 +27,7 @@ import com.facebook.react.bridge.JavaOnlyArray; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableType; +import com.facebook.react.uimanager.PointerEvents; import com.facebook.react.uimanager.annotations.ReactProp; import java.lang.reflect.Field; @@ -522,6 +523,10 @@ abstract public class RenderableView extends VirtualView { return -1; } + if (mPointerEvents == PointerEvents.NONE) { + return -1; + } + float[] dst = new float[2]; mInvMatrix.mapPoints(dst, src); mInvTransform.mapPoints(dst); diff --git a/android/src/main/java/com/horcrux/svg/RenderableViewManager.java b/android/src/main/java/com/horcrux/svg/RenderableViewManager.java index 949cef5d..ab9badcb 100644 --- a/android/src/main/java/com/horcrux/svg/RenderableViewManager.java +++ b/android/src/main/java/com/horcrux/svg/RenderableViewManager.java @@ -23,12 +23,16 @@ import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.MatrixMathHelper; import com.facebook.react.uimanager.PixelUtil; +import com.facebook.react.uimanager.PointerEvents; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.TransformHelper; import com.facebook.react.uimanager.ViewGroupManager; +import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; +import java.util.Locale; + import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -1230,6 +1234,17 @@ class RenderableViewManager extends ViewGroupManager { node.setResponsible(responsible); } + @ReactProp(name = ViewProps.POINTER_EVENTS) + public void setPointerEvents(VirtualView view, @androidx.annotation.Nullable String pointerEventsStr) { + if (pointerEventsStr == null) { + view.setPointerEvents(PointerEvents.AUTO); + } else { + PointerEvents pointerEvents = + PointerEvents.valueOf(pointerEventsStr.toUpperCase(Locale.US).replace("-", "_")); + view.setPointerEvents(pointerEvents); + } + } + @ReactProp(name = "onLayout") public void setOnLayout(VirtualView node, boolean onLayout) { node.setOnLayout(onLayout); diff --git a/android/src/main/java/com/horcrux/svg/VirtualView.java b/android/src/main/java/com/horcrux/svg/VirtualView.java index 633e46d2..9c0b0c22 100644 --- a/android/src/main/java/com/horcrux/svg/VirtualView.java +++ b/android/src/main/java/com/horcrux/svg/VirtualView.java @@ -17,6 +17,7 @@ import com.facebook.react.bridge.ReadableType; import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.OnLayoutEvent; +import com.facebook.react.uimanager.PointerEvents; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.events.EventDispatcher; @@ -102,6 +103,11 @@ abstract public class VirtualView extends ReactViewGroup { Region mStrokeRegion; Region mClipRegion; ArrayList elements; + PointerEvents mPointerEvents; + + void setPointerEvents(PointerEvents pointerEvents) { + mPointerEvents = pointerEvents; + } @Override public void invalidate() { diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index 037c470d..96a37f24 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -518,6 +518,11 @@ UInt32 saturate(CGFloat value) { return nil; } + BOOL canReceiveTouchEvents = (([self isUserInteractionEnabled] || self.responsible) && ![self isHidden]); + if(!canReceiveTouchEvents) { + return nil; + } + if (self.active) { if (!event) { self.active = NO; diff --git a/ios/ViewManagers/RNSVGNodeManager.m b/ios/ViewManagers/RNSVGNodeManager.m index 23267347..a33c5792 100644 --- a/ios/ViewManagers/RNSVGNodeManager.m +++ b/ios/ViewManagers/RNSVGNodeManager.m @@ -236,4 +236,30 @@ RCT_CUSTOM_VIEW_PROPERTY(display, id, RNSVGNode) RCT_CUSTOM_SHADOW_PROPERTY(direction, id, RNSVGNode) {} +RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RNSVGNode) +{ + if (!json) { + view.userInteractionEnabled = defaultView.userInteractionEnabled; + return; + } + + switch ([RCTConvert RCTPointerEvents:json]) { + case RCTPointerEventsBoxNone: + case RCTPointerEventsBoxOnly: + case RCTPointerEventsUnspecified: + // Pointer events "unspecified" acts as if a stylesheet had not specified, + // which is different than "auto" in CSS (which cannot and will not be + // supported in `React`. "auto" may override a parent's "none". + // Unspecified values do not. + // This wouldn't override a container view's `userInteractionEnabled = NO` + view.userInteractionEnabled = YES; + break; + case RCTPointerEventsNone: + view.userInteractionEnabled = NO; + break; + default: + view.userInteractionEnabled = NO; + RCTLogError(@"UIView base class does not support pointerEvent value: %@", json); + } +} @end