Skip to content

Commit

Permalink
[macOS] Add ManualGestureHandler (#3018)
Browse files Browse the repository at this point in the history
## Description

This PR adds `ManualGestureHandler` on `macOS`.

## Test plan

Tested on example App.
  • Loading branch information
m-bert authored Aug 2, 2024
1 parent fc15107 commit 7042beb
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 37 deletions.
11 changes: 3 additions & 8 deletions MacOSExample/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import React from 'react';
import {
Text,
View,
StyleSheet,
SectionList,
Platform,
Pressable,
} from 'react-native';
import { Text, View, StyleSheet, SectionList, Platform } from 'react-native';
import {
createStackNavigator,
StackScreenProps,
Expand All @@ -20,6 +13,7 @@ import {
import Draggable from './basic/draggable';
import PinchableBox from './recipes/scaleAndRotate';
import Tap from './basic/tap';
import ManualExample from './basic/manual';

interface Example {
name: string;
Expand All @@ -38,6 +32,7 @@ const EXAMPLES: ExamplesSection[] = [
{ name: 'Draggable', component: Draggable },
{ name: 'Pinch & rotate', component: PinchableBox },
{ name: 'Tap', component: Tap },
{ name: 'Manual', component: ManualExample },
],
},
];
Expand Down
76 changes: 76 additions & 0 deletions MacOSExample/src/basic/manual/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { StyleSheet, View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, {
interpolateColor,
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated';

export default function ManualExample() {
const isPressed = useSharedValue(false);
const colorProgress = useSharedValue(0);

const animatedStyles = useAnimatedStyle(() => {
const backgroundColor = interpolateColor(
colorProgress.value,
[0, 1],
['#0a2688', '#6fcef5']
);

return {
transform: [
{ scale: withTiming(isPressed.value ? 1.2 : 1, { duration: 100 }) },
],
backgroundColor,
};
});

const g = Gesture.Manual()
.onBegin(() => console.log('onBegin'))
.onStart(() => {
console.log('onStart');
isPressed.value = true;
colorProgress.value = withTiming(1, {
duration: 100,
});
})
.onFinalize(() => {
console.log('onFinalize');
isPressed.value = false;
colorProgress.value = withTiming(0, {
duration: 100,
});
})
.onTouchesDown((e, stateManager) => {
console.log('onTouchesDown', e);
stateManager.activate();
})
.onTouchesMove((e) => console.log('onTouchesMove', e.state))
.onTouchesUp((e, stateManager) => {
stateManager.end();
console.log('onTouchesUp', e);
});

return (
<View style={styles.container}>
<GestureDetector gesture={g}>
<Animated.View style={[animatedStyles, styles.pressBox]} />
</GestureDetector>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'space-around',
alignItems: 'center',
},

pressBox: {
width: 100,
height: 100,
borderRadius: 20,
},
});
82 changes: 53 additions & 29 deletions apple/Handlers/RNManualHandler.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#import "RNManualHandler.h"

#if !TARGET_OS_OSX

@interface RNManualRecognizer : UIGestureRecognizer

#else
@interface RNManualRecognizer : NSGestureRecognizer
#endif
- (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler;

@end
Expand All @@ -19,25 +20,27 @@ - (id)initWithGestureHandler:(RNGestureHandler *)gestureHandler
_gestureHandler = gestureHandler;
_shouldSendBeginEvent = YES;
}

return self;
}

- (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
- (void)interactionsBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[_gestureHandler setCurrentPointerType:event];
[super touchesBegan:touches withEvent:event];
[_gestureHandler.pointerTracker touchesBegan:touches withEvent:event];

if (_shouldSendBeginEvent) {
[_gestureHandler handleGesture:self];
#if TARGET_OS_OSX
self.state = NSGestureRecognizerStateBegan;
#endif
_shouldSendBeginEvent = NO;
}
}

- (void)touchesMoved:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
- (void)interactionsMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
[_gestureHandler.pointerTracker touchesMoved:touches withEvent:event];
[_gestureHandler handleGesture:self];

if ([self shouldFail]) {
self.state = (self.state == UIGestureRecognizerStatePossible) ? UIGestureRecognizerStateFailed
Expand All @@ -47,10 +50,31 @@ - (void)touchesMoved:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
}
}

- (void)interactionsEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[_gestureHandler.pointerTracker touchesEnded:touches withEvent:event];
[_gestureHandler handleGesture:self];
}

#if !TARGET_OS_OSX
- (void)touchesBegan:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
{
[_gestureHandler setCurrentPointerType:event];
[super touchesBegan:touches withEvent:event];

[self interactionsBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
[self interactionsMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
[_gestureHandler.pointerTracker touchesEnded:touches withEvent:event];
[self interactionsEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)event
Expand All @@ -60,6 +84,26 @@ - (void)touchesCancelled:(NSSet<RNGHUITouch *> *)touches withEvent:(UIEvent *)ev
[self reset];
}

#else

- (void)mouseDown:(NSEvent *)event
{
[_gestureHandler setCurrentPointerTypeToMouse];
[self interactionsBegan:[NSSet setWithObject:event] withEvent:event];
}

- (void)mouseDragged:(NSEvent *)event
{
[self interactionsMoved:[NSSet setWithObject:event] withEvent:event];
}

- (void)mouseUp:(NSEvent *)event
{
[self interactionsEnded:[NSSet setWithObject:event] withEvent:event];
}

#endif

- (void)reset
{
[_gestureHandler.pointerTracker reset];
Expand All @@ -71,11 +115,7 @@ - (void)reset

- (BOOL)shouldFail
{
if (_gestureHandler.shouldCancelWhenOutside && ![_gestureHandler containsPointInView]) {
return YES;
} else {
return NO;
}
return _gestureHandler.shouldCancelWhenOutside && ![_gestureHandler containsPointInView];
}

@end
Expand All @@ -87,24 +127,8 @@ - (instancetype)initWithTag:(NSNumber *)tag
if ((self = [super initWithTag:tag])) {
_recognizer = [[RNManualRecognizer alloc] initWithGestureHandler:self];
}
return self;
}

@end

#else

@implementation RNManualGestureHandler

- (instancetype)initWithTag:(NSNumber *)tag
{
RCTLogWarn(@"ManualGestureHandler is not supported on macOS");
if ((self = [super initWithTag:tag])) {
_recognizer = [NSGestureRecognizer alloc];
}
return self;
}

@end

#endif

0 comments on commit 7042beb

Please sign in to comment.