From f0e812e9e2370c39b6c0ec5601a8ae0d83b53f4a Mon Sep 17 00:00:00 2001 From: True Zhuanjia Date: Thu, 15 Aug 2024 21:55:01 +0800 Subject: [PATCH] iterate all customTapGestureRecognizer in OnScreenControls implementation to resolve conflict between tap gesture & osc touch --- .../Input/CustomOSC/LayoutOnScreenControls.m | 1 + Limelight/Input/CustomTapGestureRecognizer.h | 3 ++- Limelight/Input/CustomTapGestureRecognizer.m | 6 +++--- Limelight/Input/OnScreenControls.h | 3 ++- Limelight/Input/OnScreenControls.m | 20 ++++++++++++++++--- Limelight/Input/StreamView.m | 18 ++++++++++++++--- .../LayoutOnScreenControlsViewController.m | 2 +- .../StreamFrameViewController.m | 18 ++++++++--------- 8 files changed, 50 insertions(+), 21 deletions(-) diff --git a/Limelight/Input/CustomOSC/LayoutOnScreenControls.m b/Limelight/Input/CustomOSC/LayoutOnScreenControls.m index 8557c797..889f5c58 100644 --- a/Limelight/Input/CustomOSC/LayoutOnScreenControls.m +++ b/Limelight/Input/CustomOSC/LayoutOnScreenControls.m @@ -31,6 +31,7 @@ _view.multipleTouchEnabled = false; self = [super initWithView:view controllerSup:controllerSupport streamConfig:streamConfig]; + self.isLayingOut = true; // make sure the super class have a flag to tell it's currently laying out the OSCs, intead play mode. self._level = oscLevel; layoutChanges = [[NSMutableArray alloc] init]; // will contain OSC button layout changes the user has made for this profile diff --git a/Limelight/Input/CustomTapGestureRecognizer.h b/Limelight/Input/CustomTapGestureRecognizer.h index 10fad7df..dfb113d0 100644 --- a/Limelight/Input/CustomTapGestureRecognizer.h +++ b/Limelight/Input/CustomTapGestureRecognizer.h @@ -18,7 +18,8 @@ @property (nonatomic, assign) uint8_t numberOfTouchesRequired; @property (nonatomic, assign) bool immediateTriggering; // if enabled, trigger the signal on touchesBegan stage. @property (nonatomic, assign) double tapDownTimeThreshold; // tap down threshold in seconds. -@property (nonatomic, assign) bool areVirtualControllerTaps; // will be set by the onscreencontrol class +@property (nonatomic, assign) bool areOnScreenButtonTaps; // will be set by the onscreencontrol or other related class +//@property (nonatomic, assign) bool haveOnScreenButtonsOnStreamview; @property (nonatomic, readonly) CGFloat lowestTouchPointHeight; @property (nonatomic, readonly) bool gestureCaptured; @property (nonatomic, readonly) NSTimeInterval gestureCapturedTime; diff --git a/Limelight/Input/CustomTapGestureRecognizer.m b/Limelight/Input/CustomTapGestureRecognizer.m index b3ae1a89..ea2a22d3 100644 --- a/Limelight/Input/CustomTapGestureRecognizer.m +++ b/Limelight/Input/CustomTapGestureRecognizer.m @@ -32,7 +32,7 @@ static CGFloat screenWidthInPoints; _immediateTriggering = false; _tapDownTimeThreshold = 0.3; _gestureCaptured = false; - _areVirtualControllerTaps = false; + _areOnScreenButtonTaps = false; return self; } @@ -73,14 +73,14 @@ static CGFloat screenWidthInPoints; _gestureCaptured = false; self.state = UIGestureRecognizerStateFailed; } - else if(_gestureCaptured && allTouchesCount == [touches count] && !_areVirtualControllerTaps){ //must exclude virtual controller taps here to prevent stucked button, _areVirtualControllerTaps flag is set by onscreencontrols or anyother related classes. + else if(_gestureCaptured && allTouchesCount == [touches count] && !_areOnScreenButtonTaps){ //must exclude virtual controller taps here to prevent stucked button, _areVirtualControllerTaps flag is set by onscreencontrols or anyother related classes. _gestureCaptured = false; //reset for next recognition if((CACurrentMediaTime() - _gestureCapturedTime) < _tapDownTimeThreshold){ lowestTouchPointYCoord = 0.0; //reset for next recognition self.state = UIGestureRecognizerStateRecognized; } } - if (allTouchesCount == [touches count]) _areVirtualControllerTaps = false; // need to reset this flag anyway, when all fingers are lefting + if (allTouchesCount == [touches count]) _areOnScreenButtonTaps = false; // need to reset this flag anyway, when all fingers are lefting } @end diff --git a/Limelight/Input/OnScreenControls.h b/Limelight/Input/OnScreenControls.h index 21e54604..6bdf59d2 100644 --- a/Limelight/Input/OnScreenControls.h +++ b/Limelight/Input/OnScreenControls.h @@ -33,7 +33,8 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) { }; -@property (nonatomic, assign) CustomTapGestureRecognizer* mouseRightClickTapRecognizer; // this object will be passed to onscreencontrols class for areVirtualControllerTaps flag setting +// @property (nonatomic, assign) CustomTapGestureRecognizer* mouseRightClickTapRecognizer; // this object will be passed to onscreencontrols class for areVirtualControllerTaps flag setting +@property (nonatomic, assign) bool isLayingOut; @property CALayer* _aButton; @property CALayer* _bButton; @property CALayer* _xButton; diff --git a/Limelight/Input/OnScreenControls.m b/Limelight/Input/OnScreenControls.m index 3bafb2e5..7d958c32 100644 --- a/Limelight/Input/OnScreenControls.m +++ b/Limelight/Input/OnScreenControls.m @@ -8,6 +8,7 @@ #import "OnScreenControls.h" #import "StreamView.h" +#import "CustomTapGestureRecognizer.h" #import "Controller.h" #include "Limelight.h" #import "OnScreenButtonState.h" @@ -128,6 +129,7 @@ static float L3_Y; - (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport streamConfig:(StreamConfiguration*)streamConfig { self = [self init]; + self.isLayingOut = false; // set false by default (play mode instead of layout mode) _view = view; profilesManager = [OSCProfilesManager sharedManager]; @@ -1037,11 +1039,23 @@ static float L3_Y; } } if (updated) { - _mouseRightClickTapRecognizer.areVirtualControllerTaps = true; //inform the tap recognizer that this will be a controller tap. - [_controllerSupport updateFinished:_controller]; } - return updated || stickTouch; + + bool oscTouched = updated || stickTouch; + if(oscTouched){ + StreamView *streamView = (StreamView* )self->_view; + for (UIGestureRecognizer *gesture in _view.gestureRecognizers) { + if ([gesture isKindOfClass:[CustomTapGestureRecognizer class]]) { + // This is a CustomTapGestureRecognizer + CustomTapGestureRecognizer *tapGesture = (CustomTapGestureRecognizer *)gesture; + tapGesture.areOnScreenButtonTaps = true; + // Perform actions with tapGesture + } + } + } + + return oscTouched; } - (BOOL)handleTouchUpEvent:touches { diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m index 09510778..b86faf2d 100644 --- a/Limelight/Input/StreamView.m +++ b/Limelight/Input/StreamView.m @@ -124,11 +124,12 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; } onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport streamConfig:streamConfig]; + /* // here we pass the tap recognizer to the onscreencontrols obj if (settings.touchMode.intValue == RELATIVE_TOUCH){ RelativeTouchHandler* relativeTouchHandler = (RelativeTouchHandler*) touchHandler; onScreenControls.mouseRightClickTapRecognizer = relativeTouchHandler.mouseRightClickTapRecognizer; - } + } */ OnScreenControlsLevel level = (OnScreenControlsLevel)[settings.onscreenControls integerValue]; if (settings.touchMode.intValue != RELATIVE_TOUCH && settings.touchMode.intValue != REGULAR_NATIVE_TOUCH ) { @@ -301,11 +302,14 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; #endif } +- (bool) isOscEnabled{ + return (settings.touchMode.intValue == RELATIVE_TOUCH || settings.touchMode.intValue == REGULAR_NATIVE_TOUCH) && settings.onscreenControls.intValue != OnScreenControlsLevelOff; +} + - (void) reloadOnScreenControlsRealtimeWith:(ControllerSupport*)controllerSupport andConfig:(StreamConfiguration*)streamConfig { [self reloadOnScreenControlsWith:controllerSupport andConfig:streamConfig]; - bool oscEnabled = (settings.touchMode.intValue == RELATIVE_TOUCH || settings.touchMode.intValue == REGULAR_NATIVE_TOUCH) && settings.onscreenControls.intValue != OnScreenControlsLevelOff; - if(oscEnabled) [self showOnScreenControls]; + if([self isOscEnabled]) [self showOnScreenControls]; else [self disableOnScreenControls]; } @@ -313,6 +317,14 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; - (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport andConfig:(StreamConfiguration*)streamConfig { onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport streamConfig:streamConfig]; + + /* + // pass mouseRightClickTapRecognizer to onScreenControls obj here: + if([self isOscEnabled]){ + + RelativeTouchHandler* relativeTouchHandler = (RelativeTouchHandler *)touchHandler; + onScreenControls.mouseRightClickTapRecognizer = relativeTouchHandler.mouseRightClickTapRecognizer; + } */ [onScreenControls setLevel:(OnScreenControlsLevel)settings.onscreenControls.intValue]; } diff --git a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m index f39a8890..b6793bc4 100644 --- a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m +++ b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m @@ -9,7 +9,7 @@ #import "LayoutOnScreenControlsViewController.h" #import "OSCProfilesTableViewController.h" #import "OnScreenButtonState.h" -#import "OnScreenControls.h" +//#import "OnScreenControls.h" #import "OSCProfilesManager.h" #import "LocalizationHelper.h" #import "Moonlight-Swift.h" diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m index aa1ecd03..7a20f966 100644 --- a/Limelight/ViewControllers/StreamFrameViewController.m +++ b/Limelight/ViewControllers/StreamFrameViewController.m @@ -63,7 +63,7 @@ - (void)configOscLayoutTool{ - [self.view removeGestureRecognizer:_oscLayoutTapRecoginizer]; + [self->_streamView removeGestureRecognizer:_oscLayoutTapRecoginizer]; if((_settings.touchMode.intValue == RELATIVE_TOUCH || _settings.touchMode.intValue == REGULAR_NATIVE_TOUCH) && _settings.onscreenControls.intValue == OnScreenControlsLevelCustom){ _oscLayoutTapRecoginizer = [[CustomTapGestureRecognizer alloc] initWithTarget:self action:@selector(layoutOSC)]; _oscLayoutTapRecoginizer.numberOfTouchesRequired = 4; //tap 4 fingers to invoke OSC rebase @@ -71,7 +71,7 @@ _oscLayoutTapRecoginizer.delaysTouchesBegan = NO; _oscLayoutTapRecoginizer.delaysTouchesEnded = NO; - [self.view addGestureRecognizer:_oscLayoutTapRecoginizer]; + [self->_streamView addGestureRecognizer:_oscLayoutTapRecoginizer]; // all gesture recognizers created in this view controller will be added to the streamview instead of self.view /* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */ _layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init]; BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone); @@ -94,24 +94,24 @@ [self presentViewController:cmdManViewController animated:YES completion:nil]; } -- (void)configSwipeGestures{ - [self.view removeGestureRecognizer:_slideToSettingsRecognizer]; +- (void)configGestures{ + [self->_streamView removeGestureRecognizer:_slideToSettingsRecognizer]; _slideToSettingsRecognizer = [[CustomEdgeSwipeGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)]; _slideToSettingsRecognizer.edges = _settings.slideToSettingsScreenEdge.intValue; _slideToSettingsRecognizer.normalizedThresholdDistance = _settings.slideToSettingsDistance.floatValue; _slideToSettingsRecognizer.delaysTouchesBegan = NO; _slideToSettingsRecognizer.delaysTouchesEnded = NO; - [self.view addGestureRecognizer:_slideToSettingsRecognizer]; + [self->_streamView addGestureRecognizer:_slideToSettingsRecognizer]; - [self.view removeGestureRecognizer:_slideToCmdToolRecognizer]; + [self->_streamView removeGestureRecognizer:_slideToCmdToolRecognizer]; _slideToCmdToolRecognizer = [[CustomEdgeSwipeGestureRecognizer alloc] initWithTarget:self action:@selector(presentCommandManagerViewController)]; if(_settings.slideToSettingsScreenEdge.intValue == UIRectEdgeLeft) _slideToCmdToolRecognizer.edges = UIRectEdgeRight; else _slideToCmdToolRecognizer.edges = UIRectEdgeLeft; // _commandManager triggered by sliding from another side. _slideToCmdToolRecognizer.normalizedThresholdDistance = _settings.slideToSettingsDistance.floatValue; _slideToCmdToolRecognizer.delaysTouchesBegan = NO; _slideToCmdToolRecognizer.delaysTouchesEnded = NO; - [self.view addGestureRecognizer:_slideToCmdToolRecognizer]; + [self->_streamView addGestureRecognizer:_slideToCmdToolRecognizer]; } - (void)configZoomGesture{ @@ -140,7 +140,7 @@ //[self.view removeGestureRecognizer:] _settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here. [self configOscLayoutTool]; - [self configSwipeGestures]; + [self configGestures]; [self configZoomGesture]; [self->_streamView disableOnScreenControls]; //don't know why but this must be called outside the streamview class, just put it here. execute in streamview class cause hang [self.mainFrameViewcontroller reloadStreamConfig]; // reload streamconfig @@ -269,7 +269,7 @@ [self.view addGestureRecognizer:_playPauseTapGestureRecognizer]; #else - [self configSwipeGestures]; // swipe & exit gesture configured here + [self configGestures]; // swipe & exit gesture configured here [self configOscLayoutTool]; //_oscLayoutTapRecoginizer will be added or removed to the view here #endif