From 3973e13706dbfd428f97691ad02077cd4a61015a Mon Sep 17 00:00:00 2001 From: True Zhuanjia Date: Mon, 9 Feb 2026 20:59:41 +0800 Subject: [PATCH] feat: disablePencilSlideGestureSwitch --- VoidLink/Base.lproj/iPad.storyboard | 135 ++++++++++-------- VoidLink/Base.lproj/iPhone.storyboard | 25 +--- VoidLink/Input/CustomOSC/OSCProfile.h | 1 + VoidLink/Input/CustomOSC/OSCProfile.m | 3 + .../VoidLink v1.0.xcdatamodel/contents | 2 +- .../CustomEdgeSlideGestureRecognizer.h | 1 + .../CustomEdgeSlideGestureRecognizer.m | 4 +- .../ViewControllers/SettingsViewController.h | 3 + .../ViewControllers/SettingsViewController.m | 19 +++ .../StreamFrameViewController.h | 1 + .../StreamFrameViewController.m | 5 + VoidLink/mul.lproj/iPad.xcstrings | 32 ++++- VoidLink/mul.lproj/iPhone.xcstrings | 2 +- 13 files changed, 148 insertions(+), 85 deletions(-) diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard index d6bf3457..cf73ad9e 100644 --- a/VoidLink/Base.lproj/iPad.storyboard +++ b/VoidLink/Base.lproj/iPad.storyboard @@ -649,28 +649,20 @@ - + - - @@ -1886,6 +1878,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1990,64 +2042,24 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -2089,6 +2101,8 @@ + + @@ -3174,9 +3188,6 @@ - - - diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard index 5845838b..ac53a79a 100644 --- a/VoidLink/Base.lproj/iPhone.storyboard +++ b/VoidLink/Base.lproj/iPhone.storyboard @@ -1931,28 +1931,20 @@ - + - - @@ -3106,19 +3098,16 @@ - - - - + - + - + - + diff --git a/VoidLink/Input/CustomOSC/OSCProfile.h b/VoidLink/Input/CustomOSC/OSCProfile.h index 81245401..c0ae75e2 100644 --- a/VoidLink/Input/CustomOSC/OSCProfile.h +++ b/VoidLink/Input/CustomOSC/OSCProfile.h @@ -56,6 +56,7 @@ typedef NS_ENUM(NSInteger, MapGyroTo) { @property NSString *brushShortcut; @property NSString *eraserShortcut; @property (nonatomic, assign) bool pencilPausesNativeTouch; +@property (nonatomic, assign) bool disablePencilSlideGestures; - (id) initWithName:(NSString*)name buttonStates:(NSMutableArray*)buttonStates isSelected:(BOOL)isSelected; diff --git a/VoidLink/Input/CustomOSC/OSCProfile.m b/VoidLink/Input/CustomOSC/OSCProfile.m index 38a7bfe1..6844c537 100644 --- a/VoidLink/Input/CustomOSC/OSCProfile.m +++ b/VoidLink/Input/CustomOSC/OSCProfile.m @@ -57,6 +57,7 @@ [encoder encodeObject:self.brushShortcut forKey:@"brushShortcut"]; [encoder encodeObject:self.eraserShortcut forKey:@"eraserShortcut"]; [encoder encodeBool:self.pencilPausesNativeTouch forKey:@"pencilPausesNativeTouch"]; + [encoder encodeBool:self.disablePencilSlideGestures forKey:@"disablePencilSlideGestures"]; } - (id) initWithCoder:(NSCoder*)decoder { @@ -134,6 +135,7 @@ : @""; self.pencilPausesNativeTouch = [decoder containsValueForKey:@"pencilPausesNativeTouch"] ? [decoder decodeBoolForKey:@"pencilPausesNativeTouch"] : false; + self.disablePencilSlideGestures = [decoder containsValueForKey:@"disablePencilSlideGestures"] ? [decoder decodeBoolForKey:@"disablePencilSlideGestures"] : false; } return self; @@ -169,6 +171,7 @@ copy.brushShortcut = [self.brushShortcut mutableCopy]; // NSString → NSMutableString copy.eraserShortcut = [self.eraserShortcut mutableCopy]; // NSString → NSMutableString copy.pencilPausesNativeTouch = self.pencilPausesNativeTouch; + copy.disablePencilSlideGestures = self.disablePencilSlideGestures; return copy; } diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents index 383019b0..0acfa002 100644 --- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents +++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents @@ -42,7 +42,7 @@ - + diff --git a/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.h b/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.h index 0cde9ed2..375321e5 100644 --- a/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.h +++ b/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.h @@ -16,6 +16,7 @@ @property (nonatomic, assign) UIRectEdge edges; // Specify the edge(s) you want to recognize the swipe gesture on @property (nonatomic, assign) CGFloat normalizedThresholdDistance; // Distance from the edge to start recognizing the gesture @property (nonatomic, assign) bool immediateTriggering; +@property (nonatomic, assign) bool excludePencilEvent; @property (nonatomic, assign) CGFloat edgeTolerance; @end diff --git a/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.m b/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.m index 2a2ce21a..702d854d 100644 --- a/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.m +++ b/VoidLink/ViewControllers/CustomEdgeSlideGestureRecognizer.m @@ -27,7 +27,7 @@ CGFloat startPointX; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // [super touchesBegan:touches withEvent:event]; UITouch *touch = [touches anyObject]; - if(touch.type != UITouchTypeDirect) return; + if(_excludePencilEvent && touch.type != UITouchTypeDirect) return; capturedUITouch = touch; startPointX = [capturedUITouch locationInView:self.view].x; CGFloat streamFrameViewWidthInPoints = self.view.frame.size.width; @@ -51,7 +51,7 @@ CGFloat startPointX; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // [super touchesEnded:touches withEvent:event]; - if(touches.anyObject.type != UITouchTypeDirect) return; + if(_excludePencilEvent && touches.anyObject.type != UITouchTypeDirect) return; if([touches containsObject:capturedUITouch]){ CGFloat _endPointX = [capturedUITouch locationInView:self.view].x; CGFloat screenWidthInPoints = self.view.frame.size.width; diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h index 701946f0..aaa3170a 100644 --- a/VoidLink/ViewControllers/SettingsViewController.h +++ b/VoidLink/ViewControllers/SettingsViewController.h @@ -273,6 +273,9 @@ @property (weak, nonatomic) IBOutlet UIStackView *pencilPausesNativeTouchStack; @property (weak, nonatomic) IBOutlet UISwitch *pencilPausesNativeTouchSwitch; +@property (weak, nonatomic) IBOutlet UIStackView *disablePencilSlideGestureStack; +@property (weak, nonatomic) IBOutlet UISwitch *disablePencilSlideGestureSwitch; + #pragma clang diagnostic push diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index 3eab383a..6d6434bf 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -393,6 +393,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self.pressureCurveSwitch setOn:oscProfile.pressureCurveEnabled]; [self.doubleTapShortcutSwitch setOn:oscProfile.doubleTapShorcutEnabled]; [self.pencilPausesNativeTouchSwitch setOn:oscProfile.pencilPausesNativeTouch]; + [self.disablePencilSlideGestureSwitch setOn:oscProfile.disablePencilSlideGestures]; } - (void)saveGameProfileConfigs{ @@ -416,6 +417,7 @@ BOOL isCustomResolution(int resolutionSelected) { && oscProfile.pressureCurveEnabled == self.pressureCurveSwitch.isOn && oscProfile.doubleTapShorcutEnabled == self.doubleTapShortcutSwitch.isOn && oscProfile.pencilPausesNativeTouch == self.pencilPausesNativeTouchSwitch.isOn + && oscProfile.disablePencilSlideGestures == self.disablePencilSlideGestureSwitch.isOn ); if(!configNotChanged){ @@ -435,6 +437,7 @@ BOOL isCustomResolution(int resolutionSelected) { oscProfile.pressureCurveEnabled = self.pressureCurveSwitch.isOn; oscProfile.doubleTapShorcutEnabled = self.doubleTapShortcutSwitch.isOn; oscProfile.pencilPausesNativeTouch = self.pencilPausesNativeTouchSwitch.isOn; + oscProfile.disablePencilSlideGestures = self.disablePencilSlideGestureSwitch.isOn; [oscProfileMan replaceSelectedProfileWith:oscProfile overwriteDefault:YES]; } } @@ -876,6 +879,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self addSetting:self.pressureCurveStack ofId:@"pressureCurveStack" withInfoTag:NO withDynamicLabel:NO to:pencilSection]; [self addSetting:self.doubleTapShortcutStack ofId:@"doubleTapShortcutStack" withInfoTag:YES withDynamicLabel:NO to:pencilSection]; [self addSetting:self.pencilPausesNativeTouchStack ofId:@"pencilPausesNativeTouchStack" withInfoTag:NO withDynamicLabel:NO to:pencilSection]; + [self addSetting:self.disablePencilSlideGestureStack ofId:@"disablePencilSlideGestureStack" withInfoTag:NO withDynamicLabel:NO to:pencilSection]; [pencilSection addToParentStack:_parentStack]; } @@ -3393,6 +3397,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self pencilTickModeChanged:self.pencilTickSelector]; [self.doubleTapShortcutSwitch setOn:false]; [self.pencilPausesNativeTouchSwitch setOn:false]; + [self.disablePencilSlideGestureSwitch setOn:false]; }); } @@ -3422,6 +3427,19 @@ BOOL isCustomResolution(int resolutionSelected) { } } +- (void)disablePencilSlideGestureSwitchFlipped:(UISwitch* )sender{ + if(sender.isOn && !settingsViewJustLoaded){ + if (@available(iOS 15.0, *)) { + [IAPManager checkPurchaseInfo:AddOnProductPencilProPack completion:^(PurchaseInfo* info) { + if(info.valid) nil; + else { + [IAPManager inAppPurchaseActionWithViewController:self product:AddOnProductPencilProPack]; + } + }]; + } + } +} + - (void)pencilPausesNativeTouchSwitchFlipped:(UISwitch* )sender{ if(sender.isOn && !settingsViewJustLoaded){ if (@available(iOS 15.0, *)) { @@ -3444,6 +3462,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self.pressureCurveSwitch addTarget:self action:@selector(pressureCurveSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; [self.doubleTapShortcutSwitch addTarget:self action:@selector(doubleTapShortcutSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; + [self.disablePencilSlideGestureSwitch addTarget:self action:@selector(disablePencilSlideGestureSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; [self.pencilPausesNativeTouchSwitch addTarget:self action:@selector(pencilPausesNativeTouchSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; } } diff --git a/VoidLink/ViewControllers/StreamFrameViewController.h b/VoidLink/ViewControllers/StreamFrameViewController.h index c0fd08a5..354033af 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.h +++ b/VoidLink/ViewControllers/StreamFrameViewController.h @@ -45,5 +45,6 @@ - (void)updatePreferredDisplayMode:(BOOL)streamActive; - (void)setUserInteractionEnabledForStreamView:(bool)enabled; - (bool)shallDisableGyroHotSwitch; +- (void)loadGameProfileConfigs:(OSCProfile* )profile; @end diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index 89675549..8ab254c0 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -49,6 +49,7 @@ ControllerSupport *_controllerSupport; StreamManager *_streamMan; TemporarySettings *_settings; + OSCProfile* _oscProfile; NSTimer *_inactivityTimer; NSTimer *_statsUpdateTimer; PaddedLabel *_overlayView; @@ -281,6 +282,7 @@ - (void)configGestures{ _slideToSettingsRecognizer = [[CustomEdgeSlideGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)]; + _slideToSettingsRecognizer.excludePencilEvent = _oscProfile.disablePencilSlideGestures; _slideToSettingsRecognizer.edgeTolerance = _settings.edgeSlidingSensitivity.floatValue; _slideToSettingsRecognizer.edges = _settings.slideToSettingsScreenEdge.intValue; _slideToSettingsRecognizer.normalizedThresholdDistance = _settings.slideToSettingsDistance.floatValue; @@ -290,6 +292,7 @@ _slideToToolboxRecognizer = [[CustomEdgeSlideGestureRecognizer alloc] initWithTarget:self action:@selector(bringUpToolboxMenu)]; + _slideToToolboxRecognizer.excludePencilEvent = _oscProfile.disablePencilSlideGestures; _slideToToolboxRecognizer.edgeTolerance = _settings.edgeSlidingSensitivity.floatValue; if(_settings.slideToSettingsScreenEdge.intValue == UIRectEdgeLeft) _slideToToolboxRecognizer.edges = UIRectEdgeRight; else _slideToToolboxRecognizer.edges = UIRectEdgeLeft; // _commandManager triggered by sliding from another side. @@ -360,6 +363,8 @@ if (reloadSettings) { _settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here. } + _oscProfile = [[OSCProfilesManager sharedManager:CGRectZero] getSelectedProfile]; + overlayLevel = _settings.statsOverlayLevel.intValue; [self setupOverlayView]; diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings index dfd61b6a..bb7467ba 100644 --- a/VoidLink/mul.lproj/iPad.xcstrings +++ b/VoidLink/mul.lproj/iPad.xcstrings @@ -5509,6 +5509,36 @@ } } }, + "w3d-5s-dH3.text" : { + "comment" : "Class = \"UILabel\"; text = \"Disable Pencil Slide Gesture\"; ObjectID = \"w3d-5s-dH3\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Disable Pencil Slide Gesture" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭 Pencil 滑动手势" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "關閉 Pencil 滑動手勢" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "關閉 Pencil 滑動手勢" + } + } + } + }, "wi6-L4-KwS.segmentTitles[0]" : { "comment" : "Class = \"UISegmentedControl\"; wi6-L4-KwS.segmentTitles[0] = \"System\"; ObjectID = \"wi6-L4-KwS\";", "extractionState" : "extracted_with_value", @@ -5847,7 +5877,7 @@ }, "Ylu-hT-Cuz.text" : { "comment" : "Class = \"UILabel\"; text = \"The recommended value is 2. 1 frame provides the lowest latency, but may require an Ethernet connection.\"; ObjectID = \"Ylu-hT-Cuz\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings index de9993f4..34b118b7 100644 --- a/VoidLink/mul.lproj/iPhone.xcstrings +++ b/VoidLink/mul.lproj/iPhone.xcstrings @@ -5127,7 +5127,7 @@ }, "ttV-kY-jCi.text" : { "comment" : "Class = \"UILabel\"; text = \"The recommended value is 2. 1 frame provides the lowest latency, but may require an Ethernet connection.\"; ObjectID = \"ttV-kY-jCi\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : {