diff --git a/Limelight/Database/TemporarySettings.h b/Limelight/Database/TemporarySettings.h index 45d36ba0..81642cf2 100644 --- a/Limelight/Database/TemporarySettings.h +++ b/Limelight/Database/TemporarySettings.h @@ -11,7 +11,7 @@ #define REGULAR_NATIVE_TOUCH 1 #define PURE_NATIVE_TOUCH 2 #define ABSOLUTE_TOUCH 3 -#define OSC_TOOL_FINGERS 5 +#define OSC_TOOL_FINGERS 4 @interface TemporarySettings : NSObject diff --git a/Limelight/Input/OnScreenControls.m b/Limelight/Input/OnScreenControls.m index 7d958c32..465bcde4 100644 --- a/Limelight/Input/OnScreenControls.m +++ b/Limelight/Input/OnScreenControls.m @@ -1044,8 +1044,7 @@ static float L3_Y; bool oscTouched = updated || stickTouch; if(oscTouched){ - StreamView *streamView = (StreamView* )self->_view; - for (UIGestureRecognizer *gesture in _view.gestureRecognizers) { + for (UIGestureRecognizer *gesture in _view.superview.gestureRecognizers) { // we'll iterate the superview(streamframe view, where all the custom gestures are added), instead the streamview, that the osc buttons are pressed if ([gesture isKindOfClass:[CustomTapGestureRecognizer class]]) { // This is a CustomTapGestureRecognizer CustomTapGestureRecognizer *tapGesture = (CustomTapGestureRecognizer *)gesture; diff --git a/Limelight/Input/RelativeTouchHandler.m b/Limelight/Input/RelativeTouchHandler.m index e6f6954a..681d50eb 100644 --- a/Limelight/Input/RelativeTouchHandler.m +++ b/Limelight/Input/RelativeTouchHandler.m @@ -42,7 +42,7 @@ static const int REFERENCE_HEIGHT = 720; _mouseRightClickTapRecognizer.tapDownTimeThreshold = RIGHTCLICK_TAP_DOWN_TIME_THRESHOLD_S; // tap down time in seconds. _mouseRightClickTapRecognizer.delaysTouchesBegan = NO; _mouseRightClickTapRecognizer.delaysTouchesEnded = NO; - [self->view addGestureRecognizer:_mouseRightClickTapRecognizer]; + [self->view.superview addGestureRecognizer:_mouseRightClickTapRecognizer]; // add all additional gestures to the streamframeview instead of the streamview. diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m index bc70b97f..009f6b89 100644 --- a/Limelight/Input/StreamView.m +++ b/Limelight/Input/StreamView.m @@ -63,6 +63,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; - (void) setupStreamView:(ControllerSupport*)controllerSupport interactionDelegate:(id)interactionDelegate config:(StreamConfiguration*)streamConfig { + self->interactionDelegate = interactionDelegate; self->streamAspectRatio = (float)streamConfig.width / (float)streamConfig.height; @@ -77,7 +78,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; [keyInputField setSpellCheckingType:UITextSpellCheckingTypeNo]; [self addSubview:keyInputField]; - [self removeGestureRecognizer:keyboardToggleRecognizer]; // for reconfig streamview in realtime isInputingText = false; keyboardToggleRecognizer = [[CustomTapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleKeyboard)]; keyboardToggleRecognizer.numberOfTouchesRequired = settings.keyboardToggleFingers.intValue; //will be changed accordinly by touch modes. @@ -93,7 +93,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; - [self addGestureRecognizer:keyboardToggleRecognizer]; + [self.superview addGestureRecognizer:keyboardToggleRecognizer]; #if TARGET_OS_TV // tvOS requires RelativeTouchHandler to manage Apple Remote input @@ -151,14 +151,12 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; if (@available(iOS 13.4, *)) { [self addInteraction:[[UIPointerInteraction alloc] initWithDelegate:self]]; - [self removeGestureRecognizer:discreteMouseWheelRecognizer]; // for realtime reconfig stream view UIPanGestureRecognizer *discreteMouseWheelRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mouseWheelMovedDiscrete:)]; discreteMouseWheelRecognizer.maximumNumberOfTouches = 0; discreteMouseWheelRecognizer.allowedScrollTypesMask = UIScrollTypeMaskDiscrete; discreteMouseWheelRecognizer.allowedTouchTypes = @[@(UITouchTypeIndirectPointer)]; [self addGestureRecognizer:discreteMouseWheelRecognizer]; - [self removeGestureRecognizer:continuousMouseWheelRecognizer]; // for realtime reconfig stream view UIPanGestureRecognizer *continuousMouseWheelRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mouseWheelMovedContinuous:)]; continuousMouseWheelRecognizer.maximumNumberOfTouches = 0; continuousMouseWheelRecognizer.allowedScrollTypesMask = UIScrollTypeMaskContinuous; @@ -168,7 +166,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; #if defined(__IPHONE_16_1) || defined(__TVOS_16_1) if (@available(iOS 16.1, *)) { - [self removeGestureRecognizer:stylusHoverRecognizer]; // for realtime reconfig streamview UIHoverGestureRecognizer *stylusHoverRecognizer = [[UIHoverGestureRecognizer alloc] initWithTarget:self action:@selector(sendStylusHoverEvent:)]; stylusHoverRecognizer.allowedTouchTypes = @[@(UITouchTypePencil)]; [self addGestureRecognizer:stylusHoverRecognizer]; diff --git a/Limelight/Localization/Localizable.xcstrings b/Limelight/Localization/Localizable.xcstrings index 61ea437a..754b6924 100644 --- a/Limelight/Localization/Localizable.xcstrings +++ b/Limelight/Localization/Localizable.xcstrings @@ -2119,48 +2119,48 @@ } } }, - "Tap 5 fingers to change on-screen controller layout in stream view" : { + "Tap %d fingers to change on-screen controller layout in stream view" : { "extractionState" : "manual", "localizations" : { "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "在串流视图中轻按5根手指修改虚拟手柄布局" + "value" : "在串流视图中轻按%d根手指修改虚拟手柄布局" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "在串流视图中轻按5根手指修改虚拟手柄布局" + "value" : "在串流视图中轻按%d根手指修改虚拟手柄布局" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "在串流视图中轻按5根手指修改虚拟手柄布局" + "value" : "在串流视图中轻按%d根手指修改虚拟手柄布局" } } } }, - "Tap 5 Fingers to Change OSC Layout in Stream View" : { + "Tap %d Fingers to Change OSC Layout in Stream View" : { "extractionState" : "manual", "localizations" : { "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "在串流视图中轻按5根手指修改虚拟手柄布局" + "value" : "在串流视图中轻按%d根手指修改虚拟手柄布局" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "在串流视图中轻按5根手指修改虚拟手柄布局" + "value" : "在串流视图中轻按%d根手指修改虚拟手柄布局" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "在串流视图中轻按5根手指修改虚拟手柄布局" + "value" : "在串流视图中轻按%d根手指修改虚拟手柄布局" } } } diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m index 1c27ee97..e230a802 100644 --- a/Limelight/ViewControllers/SettingsViewController.m +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -483,7 +483,7 @@ BOOL isCustomResolution(CGSize res) { - (void)showCustomOSCTip { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Rebase in Stream View"] - message:[LocalizationHelper localizedStringForKey:@"Tap 5 fingers to change on-screen controller layout in stream view"] + message:[LocalizationHelper localizedStringForKey:@"Tap %d fingers to change on-screen controller layout in stream view", OSC_TOOL_FINGERS] preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey: @"Got it!"] style:UIAlertActionStyleDefault @@ -518,7 +518,7 @@ BOOL isCustomResolution(CGSize res) { // [self.keyboardToggleFingerNumSlider setValue:3.0]; // [self keyboardToggleFingerNumSliderMoved]; [self keyboardToggleFingerNumSliderMoved]; // go to exclude 5 fingers - [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"Tap 5 Fingers to Change OSC Layout in Stream View"]]; + [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"Tap %d Fingers to Change OSC Layout in Stream View", OSC_TOOL_FINGERS]]; [self showCustomOSCTip]; justEnteredSettingsViewDoNotOpenOscLayoutTool = false; //if (self.layoutOnScreenControlsVC.isBeingPresented == NO) @@ -611,7 +611,7 @@ BOOL isCustomResolution(CGSize res) { if(customOscEnabled) { // [self.keyboardToggleFingerNumSlider setValue:3.0]; // [self.keyboardToggleFingerNumLabel setText:[LocalizationHelper localizedStringForKey:@"To Toggle Local Keyboard: Tap %d Fingers", (uint16_t)self.keyboardToggleFingerNumSlider.value]]; - [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"Tap 5 Fingers to Change OSC Layout in Stream View"]]; + [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"Tap %d Fingers to Change OSC Layout in Stream View", OSC_TOOL_FINGERS]]; [self keyboardToggleFingerNumSliderMoved]; // go exclude 5 fingers //if (self.layoutOnScreenControlsVC.isBeingPresented == NO) } @@ -814,9 +814,9 @@ BOOL isCustomResolution(CGSize res) { CGFloat sliderValue = self.keyboardToggleFingerNumSlider.value; if(customOscEnabled){ - // exclude 5 fingers when custom osc is enabled - if(sliderValue > OSC_TOOL_FINGERS - 1 && sliderValue < OSC_TOOL_FINGERS) [self.keyboardToggleFingerNumSlider setValue:4.0]; - if(sliderValue >= OSC_TOOL_FINGERS && sliderValue < OSC_TOOL_FINGERS + 1) [self.keyboardToggleFingerNumSlider setValue:6.0]; + // exclude OSC_TOOL_FINGERS when custom osc is enabled + if(sliderValue > OSC_TOOL_FINGERS - 1 && sliderValue < OSC_TOOL_FINGERS) [self.keyboardToggleFingerNumSlider setValue: OSC_TOOL_FINGERS - 1]; + if(sliderValue >= OSC_TOOL_FINGERS && sliderValue < OSC_TOOL_FINGERS + 1) [self.keyboardToggleFingerNumSlider setValue: OSC_TOOL_FINGERS + 1]; } sliderValue = self.keyboardToggleFingerNumSlider.value; diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m index 70b1edc8..7891199f 100644 --- a/Limelight/ViewControllers/StreamFrameViewController.m +++ b/Limelight/ViewControllers/StreamFrameViewController.m @@ -63,7 +63,6 @@ - (void)configOscLayoutTool{ - [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 = OSC_TOOL_FINGERS; //tap a predefined number of fingers to open osc layout tool @@ -71,7 +70,7 @@ _oscLayoutTapRecoginizer.delaysTouchesBegan = NO; _oscLayoutTapRecoginizer.delaysTouchesEnded = NO; - [self->_streamView addGestureRecognizer:_oscLayoutTapRecoginizer]; // all gesture recognizers created in this view controller will be added to the streamview instead of self.view + [self.view addGestureRecognizer:_oscLayoutTapRecoginizer]; // /* 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,28 +93,25 @@ [self presentViewController:cmdManViewController animated:YES completion:nil]; } -- (void)configGestures{ - [self->_streamView removeGestureRecognizer:_slideToSettingsRecognizer]; +- (void)configSwipeGestures{ _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->_streamView addGestureRecognizer:_slideToSettingsRecognizer]; + [self.view addGestureRecognizer:_slideToSettingsRecognizer]; - [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->_streamView addGestureRecognizer:_slideToCmdToolRecognizer]; + [self.view addGestureRecognizer:_slideToCmdToolRecognizer]; } - (void)configZoomGesture{ - [_scrollView removeFromSuperview]; if (_settings.touchMode.intValue == ABSOLUTE_TOUCH) { _scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame]; #if !TARGET_OS_TV @@ -130,20 +126,31 @@ // Add StreamView inside a UIScrollView for absolute mode [_scrollView addSubview:_streamView]; [self.view addSubview:_scrollView]; - return; } - [self.view addSubview:_streamView]; + else{ + // Add streamView directly to self.view in other touch modes + [self.view addSubview:_streamView]; + } } // key implementation of reconfiguring streamview after realtime setting menu is closed. - (void)reConfigStreamViewRealtime{ //[self.view removeGestureRecognizer:] + //first, remove all gesture recognizers: + for (UIGestureRecognizer *recognizer in _streamView.gestureRecognizers) { + [_streamView removeGestureRecognizer:recognizer]; + } + for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) { + [self.view removeGestureRecognizer:recognizer]; + } + _settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here. [self configOscLayoutTool]; - [self configGestures]; + [self configSwipeGestures]; [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 + _controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig delegate:self]; // reload controllerSupport obj, this is mandatory for OSC reload,especially when the stream view is launched without OSC [_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig]; //reinitiate setupStreamView process. [self->_streamView reloadOnScreenControlsRealtimeWith:(ControllerSupport*)_controllerSupport @@ -155,6 +162,9 @@ selector:@selector(updateStatsOverlay) userInfo:nil repeats:_settings.statsOverlay]; + + NSLog(@"frameview gestures: %d", (uint32_t)[self.view.gestureRecognizers count]); + NSLog(@"streamview gestures: %d", (uint32_t)[_streamView.gestureRecognizers count]); } @@ -248,7 +258,8 @@ _inactivityTimer = nil; _streamView = [[StreamView alloc] initWithFrame:self.view.frame]; - [_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig]; + //[_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig]; + [self reConfigStreamViewRealtime]; // call this method again to make sure all gestures are configured & added to the superview(self.view), including the gestures added from inside the streamview. #if TARGET_OS_TV if (!_menuTapGestureRecognizer || !_menuDoubleTapGestureRecognizer || !_playPauseTapGestureRecognizer) { @@ -269,8 +280,8 @@ [self.view addGestureRecognizer:_playPauseTapGestureRecognizer]; #else - [self configGestures]; // swipe & exit gesture configured here - [self configOscLayoutTool]; //_oscLayoutTapRecoginizer will be added or removed to the view here + //[self configSwipeGestures]; // swipe & exit gesture configured here + //[self configOscLayoutTool]; //_oscLayoutTapRecoginizer will be added or removed to the view here #endif _tipLabel = [[UILabel alloc] init]; @@ -328,26 +339,6 @@ object: nil]; #endif - // Only enable scroll and zoom in absolute touch mode - if (_settings.touchMode.intValue == ABSOLUTE_TOUCH) { - _scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame]; -#if !TARGET_OS_TV - [_scrollView.panGestureRecognizer setMinimumNumberOfTouches:2]; - [_scrollView.panGestureRecognizer setMaximumNumberOfTouches:2]; // reduce competing with keyboardToggleRecognizer in StreamView. -#endif - [_scrollView setShowsHorizontalScrollIndicator:NO]; - [_scrollView setShowsVerticalScrollIndicator:NO]; - [_scrollView setDelegate:self]; - [_scrollView setMaximumZoomScale:10.0f]; - - // Add StreamView inside a UIScrollView for absolute mode - [_scrollView addSubview:_streamView]; - [self.view addSubview:_scrollView]; - } - else { - // Add StreamView directly in relative mode - [self.view addSubview:_streamView]; - } [self.view addSubview:_stageLabel]; [self.view addSubview:_spinner]; [self.view addSubview:_tipLabel];