From d054bbe35ff5810e6717e5004706d254368bb661 Mon Sep 17 00:00:00 2001 From: TrueZhuanjia Date: Thu, 11 Sep 2025 11:37:14 +0800 Subject: [PATCH] - feat: on-screen button visual feedback switch - feat: touch input disabled mode (while allowing on-screen widget input) - fixed: swapAbxy stack dynamic UI --- VoidLink/Base.lproj/iPad.storyboard | 833 +++++++++--------- VoidLink/Base.lproj/iPhone.storyboard | 27 +- VoidLink/Database/DataManager.h | 2 + VoidLink/Database/DataManager.m | 14 +- VoidLink/Database/TemporarySettings.h | 1 + VoidLink/Database/TemporarySettings.m | 1 + VoidLink/Input/MicHandler.swift | 4 +- VoidLink/Input/OnScreenWidgetView.swift | 47 +- VoidLink/Input/StreamView.m | 16 +- .../VoidLink v1.0.xcdatamodel/contents | 1 + VoidLink/Localization/Localizable.xcstrings | 8 +- .../ViewControllers/SettingsViewController.h | 4 +- .../ViewControllers/SettingsViewController.m | 21 +- VoidLink/mul.lproj/iPad.xcstrings | 70 +- VoidLink/mul.lproj/iPhone.xcstrings | 70 +- 15 files changed, 653 insertions(+), 466 deletions(-) diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard index 2db5c623..d95be8af 100644 --- a/VoidLink/Base.lproj/iPad.storyboard +++ b/VoidLink/Base.lproj/iPad.storyboard @@ -213,7 +213,8 @@ - + + @@ -243,309 +244,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -661,30 +359,6 @@ - - - - - - - - - - - - - - - - - - @@ -765,42 +439,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -825,29 +463,6 @@ - - - - - - - - - - - - - - - - - - @@ -892,24 +507,6 @@ - - - - - - - - - - - - - @@ -1030,6 +627,428 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1044,6 +1063,8 @@ + + @@ -1115,7 +1136,7 @@ - + diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard index 2a971a17..38e885f3 100644 --- a/VoidLink/Base.lproj/iPhone.storyboard +++ b/VoidLink/Base.lproj/iPhone.storyboard @@ -952,7 +952,8 @@ - + + @@ -1632,7 +1633,7 @@ - + + + + + + + + + + + + + @@ -1782,6 +1801,8 @@ + + @@ -1852,7 +1873,7 @@ - + diff --git a/VoidLink/Database/DataManager.h b/VoidLink/Database/DataManager.h index 94e412b8..09616a1b 100644 --- a/VoidLink/Database/DataManager.h +++ b/VoidLink/Database/DataManager.h @@ -25,6 +25,7 @@ typedef NS_ENUM(NSInteger, TouchMode) { RelativeTouch, NativeTouch, AbsoluteTouch, + TouchDisabled, NativeTouchOnly }; @@ -77,6 +78,7 @@ typedef NS_ENUM(NSInteger, SettingsMenuMode) { showKeyboardToolbar:(BOOL)showKeyboardToolbar optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController + buttonVisualFeedback:(BOOL)buttonVisualFeedback swapABXYButtons:(BOOL)swapABXYButtons audioOnPC:(BOOL)audioOnPC redirectMic:(BOOL)redirectMic diff --git a/VoidLink/Database/DataManager.m b/VoidLink/Database/DataManager.m index c31e76be..96038ad8 100644 --- a/VoidLink/Database/DataManager.m +++ b/VoidLink/Database/DataManager.m @@ -73,24 +73,25 @@ gyroSensitivity:(CGFloat)gyroSensitivity touchMoveEventInterval:(NSInteger)touchMoveEventInterval reverseMouseWheelDirection:(BOOL)reverseMouseWheelDirection - asyncNativeTouchPriority:(NSInteger)asyncNativeTouchPriority + asyncNativeTouchPriority:(NSInteger)asyncNativeTouchPriority liftStreamViewForKeyboard:(BOOL)liftStreamViewForKeyboard showKeyboardToolbar:(BOOL)showKeyboardToolbar optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController + buttonVisualFeedback:(BOOL)buttonVisualFeedback swapABXYButtons:(BOOL)swapABXYButtons audioOnPC:(BOOL)audioOnPC - redirectMic:(BOOL)redirectMic + redirectMic:(BOOL)redirectMic preferredCodec:(uint32_t)preferredCodec - enableYUV444:(BOOL)enableYUV444 + enableYUV444:(BOOL)enableYUV444 enablePIP:(BOOL)enablePIP enableHdr:(BOOL)enableHdr btMouseSupport:(BOOL)btMouseSupport // absoluteTouchMode:(BOOL)absoluteTouchMode touchMode:(NSInteger)touchMode statsOverlayLevel:(NSInteger)statsOverlayLevel - statsOverlayEnabled:(BOOL)statsOverlayEnabled - unlockDisplayOrientation:(BOOL)unlockDisplayOrientation + statsOverlayEnabled:(BOOL)statsOverlayEnabled + unlockDisplayOrientation:(BOOL)unlockDisplayOrientation resolutionSelected:(NSInteger)resolutionSelected externalDisplayMode:(NSInteger)externalDisplayMode localMousePointerMode:(NSInteger)localMousePointerMode @@ -98,7 +99,7 @@ enableGraphs:(BOOL)enableGraphs graphOpacity:(NSInteger)graphOpacity renderingBackend:(NSInteger)renderingBackend - framePacingMode:(NSInteger)framePacingMode + framePacingMode:(NSInteger)framePacingMode backgroundSessionTimer:(NSInteger)backgroundSessionTimer{ [_managedObjectContext performBlockAndWait:^{ @@ -126,6 +127,7 @@ settingsToSave.showKeyboardToolbar = showKeyboardToolbar; settingsToSave.optimizeGames = optimizeGames; settingsToSave.multiController = multiController; + settingsToSave.buttonVisualFeedback = buttonVisualFeedback; settingsToSave.swapABXYButtons = swapABXYButtons; settingsToSave.playAudioOnPC = audioOnPC; settingsToSave.redirectMic = redirectMic; diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h index d48e2fa5..d6456fb7 100644 --- a/VoidLink/Database/TemporarySettings.h +++ b/VoidLink/Database/TemporarySettings.h @@ -52,6 +52,7 @@ @property (nonatomic) BOOL reverseMouseWheelDirection; @property (nonatomic, retain) NSNumber * asyncNativeTouchPriority; @property (nonatomic) BOOL multiController; +@property (nonatomic) BOOL buttonVisualFeedback; @property (nonatomic) BOOL swapABXYButtons; @property (nonatomic) BOOL playAudioOnPC; @property (nonatomic) BOOL redirectMic; diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m index 6fde4369..9cfba10c 100644 --- a/VoidLink/Database/TemporarySettings.m +++ b/VoidLink/Database/TemporarySettings.m @@ -94,6 +94,7 @@ self.enableHdr = settings.enableHdr; self.optimizeGames = settings.optimizeGames; self.multiController = settings.multiController; + self.buttonVisualFeedback = settings.buttonVisualFeedback; self.swapABXYButtons = settings.swapABXYButtons; self.onscreenControls = settings.onscreenControls; self.gyroMode = settings.gyroMode; diff --git a/VoidLink/Input/MicHandler.swift b/VoidLink/Input/MicHandler.swift index 4a31224a..1f0bc76e 100644 --- a/VoidLink/Input/MicHandler.swift +++ b/VoidLink/Input/MicHandler.swift @@ -193,7 +193,9 @@ public class MicHandler: NSObject { guard let enc = self.opusEncoder else {return} let outBytes = opus_encode(enc, chunk, 960, &packet, Int32(packet.count)) sendMicrophoneData(packet, outBytes) - pcm16Buffer.removeFirst(960) + if pcm16Buffer.count >= 960 { + pcm16Buffer.removeFirst(960) + } } } } diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift index 24c14e6e..ac6cb7c1 100644 --- a/VoidLink/Input/OnScreenWidgetView.swift +++ b/VoidLink/Input/OnScreenWidgetView.swift @@ -34,6 +34,7 @@ import UIKit @objc public var widgetType: WidgetTypeEnum = WidgetTypeEnum.uninitialized @objc static public var editMode: Bool = false + @objc static public var buttonVisualFeedbackEnabled: Bool = true @objc public var buttonLabel: String @objc public var cmdString: String private var buttonString: String = "" @@ -555,13 +556,15 @@ import UIKit } private func showl3r3Indicator(){ - CATransaction.begin() - CATransaction.setDisableActions(true) - - self.l3r3Indicator.borderColor = voidlinkPurple - self.l3r3Indicator.position = CGPointMake(CGRectGetMinX(self.frame)+touchBeganLocation.x, CGRectGetMinY(self.frame)+touchBeganLocation.y) - - CATransaction.commit() + if OnScreenWidgetView.buttonVisualFeedbackEnabled { + CATransaction.begin() + CATransaction.setDisableActions(true) + + self.l3r3Indicator.borderColor = voidlinkPurple + self.l3r3Indicator.position = CGPointMake(CGRectGetMinX(self.frame)+touchBeganLocation.x, CGRectGetMinY(self.frame)+touchBeganLocation.y) + + CATransaction.commit() + } if vibrationOn { vibrationGenerator.prepare() @@ -1021,28 +1024,32 @@ import UIKit private func handleButtonDown() { if !OnScreenWidgetView.editMode {self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)} - CATransaction.begin() - CATransaction.setDisableActions(true) - // self.layer.borderWidth = 0 - buttonDownVisualEffectLayer.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) // update position every time we press down the button - buttonDownVisualEffectLayer.borderWidth = self.buttonDownVisualEffectWidth // this will show the visual effect - buttonDownVisualEffectLayer.borderColor = voidlinkPurple + if OnScreenWidgetView.buttonVisualFeedbackEnabled { + CATransaction.begin() + CATransaction.setDisableActions(true) + // self.layer.borderWidth = 0 + buttonDownVisualEffectLayer.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) // update position every time we press down the button + buttonDownVisualEffectLayer.borderWidth = self.buttonDownVisualEffectWidth // this will show the visual effect + buttonDownVisualEffectLayer.borderColor = voidlinkPurple + CATransaction.commit() + } if vibrationOn { vibrationGenerator.prepare() vibrationGenerator.impactOccurred() // print("vibrationInstance: \(vibrationGenerator)") } - CATransaction.commit() } private func handleButtonUp() { if !OnScreenWidgetView.editMode {self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings)} - CATransaction.begin() - CATransaction.setDisableActions(true) - // self.layer.borderWidth = 1 - buttonDownVisualEffectLayer.borderWidth = 0 - buttonDownVisualEffectLayer.borderColor = defaultBorderColor - CATransaction.commit() + if OnScreenWidgetView.buttonVisualFeedbackEnabled { + CATransaction.begin() + CATransaction.setDisableActions(true) + // self.layer.borderWidth = 1 + buttonDownVisualEffectLayer.borderWidth = 0 + buttonDownVisualEffectLayer.borderColor = defaultBorderColor + CATransaction.commit() + } } private func setupLrudDirectionIndicatorlayers() { diff --git a/VoidLink/Input/StreamView.m b/VoidLink/Input/StreamView.m index 51731231..afcbd83d 100644 --- a/VoidLink/Input/StreamView.m +++ b/VoidLink/Input/StreamView.m @@ -115,7 +115,6 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; keyboardToggleTip.numberOfLines = 1; keyboardToggleTip.layer.cornerRadius = 10; keyboardToggleTip.clipsToBounds = true; - NSLog(@"setup streamView %f", CACurrentMediaTime()); // if(settings.touchMode.intValue == NativeTouchOnly) [self addGestureRecognizer:keyboardToggleRecognizer]; //keep legacy approach in pure native mode // else [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes @@ -144,7 +143,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self]; keyboardToggleRecognizer.immediateTriggering = true; //triggers signal in touchesBegan callback stage break; - + case TouchDisabled: + self->touchHandler = nil; + keyboardToggleRecognizer.immediateTriggering = false; + break; + default: break; } @@ -416,8 +419,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; } // we'll enable on screen buttons, and disable on screen controllers for absolute touch -- (bool) isOnScreenButtonEnabled{ - return (settings.touchMode.intValue == RelativeTouch || settings.touchMode.intValue == NativeTouch || settings.touchMode.intValue == AbsoluteTouch) && settings.onscreenControls.intValue == OnScreenControlsLevelCustom; +- (bool) isOnScreenWidgetEnabled{ + return (settings.touchMode.intValue == RelativeTouch || settings.touchMode.intValue == NativeTouch || settings.touchMode.intValue == AbsoluteTouch || settings.touchMode.intValue == TouchDisabled) && settings.onscreenControls.intValue == OnScreenControlsLevelCustom; } - (void) reloadOnScreenControlsRealtimeWith:(ControllerSupport*)controllerSupport @@ -474,12 +477,15 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; // bool customOscEnabled = [self isOscEnabled] && settings.onscreenControls.intValue == OnScreenControlsLevelCustom; - if(![self isOnScreenButtonEnabled]) return; + if(![self isOnScreenWidgetEnabled]) return; + + OnScreenWidgetView.buttonVisualFeedbackEnabled = settings.buttonVisualFeedback; OSCProfilesManager* profilesManager = [OSCProfilesManager sharedManager: self.bounds]; OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile if(!OnScreenWidgetView.editMode){ // in edit mode, keyboard widget view will be updated within layoutool view controller. + for (NSData *buttonStateEncoded in oscProfile.buttonStates) { OnScreenButtonState* buttonState = [profilesManager unarchiveButtonStateEncoded:buttonStateEncoded]; if(buttonState.buttonType == CustomOnScreenWidget){ diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents index 1f8d307e..bf836daa 100644 --- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents +++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents @@ -26,6 +26,7 @@ + diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings index 183794d9..182338c0 100644 --- a/VoidLink/Localization/Localizable.xcstrings +++ b/VoidLink/Localization/Localizable.xcstrings @@ -5514,24 +5514,24 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "- Touchpad: Dragging works exactly like on Windows laptop touchpad. A quick double-tap, starting from the second tap, enters drag mode.\n\n- Native Touch: Aka multi-touch passthrough, not supported on macOS.\n\n- Absolute Touch: Provides a touchscreen-like experience on macOS." + "value" : "- Touchpad: Dragging works exactly like on Windows laptop touchpad. A quick double-tap, starting from the second tap, enters drag mode.\n\n- Native Touch: Aka multi-touch passthrough, not supported on macOS.\n\n- Single Point: Provides a touchscreen-like experience on macOS." } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "- 触控板: 拖移方式与Windows笔记本电脑触控板相同, 快速双击的第2下开始进入拖动状态.\n\n- 多点触控: 不支持macOS.\n\n- 单点鼠标: 可为macOS提供类触屏体验." } }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "- 觸控板:拖曳方式與 Windows 筆記型電腦觸控板完全相同。快速輕點兩下,從第二次輕點開始進入拖曳模式。\n\n- 多点觸控:macOS 不支援。\n\n- 單點滑鼠:在 macOS 上提供類似觸控螢幕的體驗。" } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "- 觸控板:拖曳方式與 Windows 筆記型電腦觸控板完全相同。快速輕點兩下,從第二次輕點開始進入拖曳模式。\n\n- 多点觸控:macOS 不支援。\n\n- 單點滑鼠:在 macOS 上提供類似觸控螢幕的體驗。" } } diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h index 4fc82921..fffb74f5 100644 --- a/VoidLink/ViewControllers/SettingsViewController.h +++ b/VoidLink/ViewControllers/SettingsViewController.h @@ -43,7 +43,7 @@ @property (strong, nonatomic) IBOutlet UIStackView *optimizeGamesStack; @property (strong, nonatomic) IBOutlet UIStackView *multiControllerStack; @property (strong, nonatomic) IBOutlet UISwitch *multiControllerSwitch; -@property (strong, nonatomic) IBOutlet UIStackView *swapAbaxyStack; +@property (strong, nonatomic) IBOutlet UIStackView *swapAbxyStack; @property (strong, nonatomic) IBOutlet UIStackView *audioOnPcStack; @property (strong, nonatomic) IBOutlet UISwitch *audioOnPcSwitch; @property (strong, nonatomic) IBOutlet UIStackView *codecStack; @@ -129,6 +129,8 @@ @property (strong, nonatomic) IBOutlet UIStackView *redirectMicStack; @property (strong, nonatomic) IBOutlet UISwitch *redirectMicSwitch; +@property (strong, nonatomic) IBOutlet UIStackView *buttonVisualFeedbackStack; +@property (strong, nonatomic) IBOutlet UISwitch *buttonVisualFeedbackSwitch; @property (nonatomic, strong) MicHandler *micHandler; diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index ec937a86..8ae1e264 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -620,7 +620,8 @@ BOOL isCustomResolution(int resolutionSelected) { [self addSetting:self.pointerVelocityFactorStack ofId:@"pointerVelocityFactorStack" withInfoTag:YES withDynamicLabel:YES to:touchAndControlSection]; [self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" withInfoTag:NO withDynamicLabel:YES to:touchAndControlSection]; [self addSetting:self.onScreenWidgetStack ofId:@"onScreenWidgetStack" withInfoTag:YES withDynamicLabel:YES to:touchAndControlSection]; - [self addSetting:self.swapAbaxyStack ofId:@"swapAbaxyStack" withInfoTag:NO withDynamicLabel:NO to:touchAndControlSection]; + [self addSetting:self.buttonVisualFeedbackStack ofId:@"buttonVisualFeedbackStack" withInfoTag:NO withDynamicLabel:NO to:touchAndControlSection]; + [self addSetting:self.swapAbxyStack ofId:@"swapAbaxyStack" withInfoTag:NO withDynamicLabel:NO to:touchAndControlSection]; [self addSetting:self.emulatedControllerTypeStack ofId:@"emulatedControllerTypeStack" withInfoTag:YES withDynamicLabel:NO to:touchAndControlSection]; [self addSetting:self.gyroModeStack ofId:@"gyroModeStack" withInfoTag:YES withDynamicLabel:YES to:touchAndControlSection]; [self addSetting:self.gyroSensitivityStack ofId:@"gyroSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:touchAndControlSection]; @@ -1500,7 +1501,8 @@ BOOL isCustomResolution(int resolutionSelected) { [self.optimizeGamesSwitch setOn: currentSettings.optimizeGames]; [self.multiControllerSwitch setOn:currentSettings.multiController]; [self.swapAbxySwitch setOn:currentSettings.swapABXYButtons]; - + [self.buttonVisualFeedbackSwitch setOn:currentSettings.buttonVisualFeedback]; + [self.gyroModeSelector setSelectedSegmentIndex:currentSettings.gyroMode.intValue]; [self.gyroSensitivitySlider setValue: (uint16_t)(currentSettings.gyroSensitivity.floatValue * 100) animated:YES]; // Load old setting. [self.gyroSensitivitySlider addTarget:self action:@selector(gyroSensitivitySliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. @@ -1718,7 +1720,7 @@ BOOL isCustomResolution(int resolutionSelected) { } - (bool)isNotNativeTouchOnly{ - return (self.enableOswForNativeTouchSwitch.isOn && self.touchModeSelector.selectedSegmentIndex == NativeTouch) || self.touchModeSelector.selectedSegmentIndex == RelativeTouch || self.touchModeSelector.selectedSegmentIndex == AbsoluteTouch; + return (self.enableOswForNativeTouchSwitch.isOn && self.touchModeSelector.selectedSegmentIndex == NativeTouch) || self.touchModeSelector.selectedSegmentIndex != NativeTouch; } - (void)handleOswGestureChange{ @@ -1974,7 +1976,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self setHidden:!(sender.selectedSegmentIndex == RelativeTouch) forStack:self.mousePointerVelocityStack]; [self setHidden:![self isNotNativeTouchOnly] forStack:self.onScreenWidgetStack]; - [self setHidden:![self isNotNativeTouchOnly] forStack:self.swapAbaxyStack]; + [self setHidden:![self isNotNativeTouchOnly] forStack:self.buttonVisualFeedbackStack]; [self handleOswGestureChange]; [touchAndControlSection updateViewForFoldState]; @@ -2003,15 +2005,12 @@ BOOL isCustomResolution(int resolutionSelected) { } - (void)enableOswForNativeTouchSwitchFlipped:(UISwitch *)sender{ - //self.onScreenWidgetStack.hidden = !sender.isOn; - [self setHidden:!sender.isOn forStack:_onScreenWidgetStack]; - //[self setHidden:!sender.isOn forStack:_swapAbaxyStack]; + [self setHidden:!sender.isOn forStack:self.onScreenWidgetStack]; + [self setHidden:!sender.isOn forStack:self.buttonVisualFeedbackStack]; [self handleOswGestureChange]; - //self.swapAbaxyStack.hidden = !sender.isOn; [touchAndControlSection updateViewForFoldState]; } - - (void) updateBitrate { NSInteger fps = [self getChosenFrameRate]; NSInteger width = [self getChosenStreamWidth]; @@ -2395,6 +2394,7 @@ BOOL isCustomResolution(int resolutionSelected) { BOOL optimizeGames = self.optimizeGamesSwitch.isOn; BOOL multiController = self.multiControllerSwitch.isOn; BOOL swapABXYButtons = self.swapAbxySwitch.isOn; + BOOL buttonVisualFeedback = self.buttonVisualFeedbackSwitch.isOn; NSInteger gyroMode = self.gyroModeSelector.selectedSegmentIndex; NSInteger emulatedControllerType = [self segmentIndexToControllerType:self.emulatedControllerTypeSelector.selectedSegmentIndex]; //self.emulatedControllerTypeSelector.selectedSegmentIndex; BOOL audioOnPC = self.audioOnPcSwitch.isOn; @@ -2442,9 +2442,10 @@ BOOL isCustomResolution(int resolutionSelected) { showKeyboardToolbar:showKeyboardToolbar optimizeGames:optimizeGames multiController:multiController + buttonVisualFeedback:buttonVisualFeedback swapABXYButtons:swapABXYButtons audioOnPC:audioOnPC - redirectMic:redirectMic + redirectMic:redirectMic preferredCodec:preferredCodec enableYUV444:enableYUV444 enablePIP:enablePIP diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings index 33a8221a..1025c1db 100644 --- a/VoidLink/mul.lproj/iPad.xcstrings +++ b/VoidLink/mul.lproj/iPad.xcstrings @@ -986,35 +986,65 @@ } }, "bhC-da-VGd.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[2] = \"Absolute Touch\"; ObjectID = \"bhC-da-VGd\";", + "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[2] = \"Single Point\"; ObjectID = \"bhC-da-VGd\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Absolute Touch" + "value" : "Single Point" } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "单点鼠标" } }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "單點滑鼠" } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "單點滑鼠" } } } }, + "bhC-da-VGd.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[3] = \"Disabled\"; ObjectID = \"bhC-da-VGd\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Disabled" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "關閉" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "關閉" + } + } + } + }, "Bhn-IO-Wlt.title" : { "comment" : "Class = \"UIBarButtonItem\"; title = \"ExportAll\"; ObjectID = \"Bhn-IO-Wlt\";", "extractionState" : "extracted_with_value", @@ -1657,6 +1687,36 @@ } } }, + "Gmb-bu-KCv.text" : { + "comment" : "Class = \"UILabel\"; text = \"Button Visual Feedback\"; ObjectID = \"Gmb-bu-KCv\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Button Visual Feedback" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "按键视觉反馈" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "按鍵視覺回饋" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "按鍵視覺回饋" + } + } + } + }, "H8S-aI-EBo.segmentTitles[0]" : { "comment" : "Class = \"UISegmentedControl\"; H8S-aI-EBo.segmentTitles[0] = \"hovering\"; ObjectID = \"H8S-aI-EBo\";", "extractionState" : "extracted_with_value", diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings index da92bfb4..1386171a 100644 --- a/VoidLink/mul.lproj/iPhone.xcstrings +++ b/VoidLink/mul.lproj/iPhone.xcstrings @@ -818,35 +818,65 @@ } }, "A9r-dE-rT4.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; A9r-dE-rT4.segmentTitles[2] = \"Absolute Touch\"; ObjectID = \"A9r-dE-rT4\";", + "comment" : "Class = \"UISegmentedControl\"; A9r-dE-rT4.segmentTitles[2] = \"Single Point\"; ObjectID = \"A9r-dE-rT4\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Absolute Touch" + "value" : "Single Point" } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "单点鼠标" } }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "單點滑鼠" } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "單點滑鼠" } } } }, + "A9r-dE-rT4.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; A9r-dE-rT4.segmentTitles[3] = \"Disabled\"; ObjectID = \"A9r-dE-rT4\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Disabled" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "關閉" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "關閉" + } + } + } + }, "awK-Ei-T9i.text" : { "comment" : "Class = \"UILabel\"; text = \"Open Toolbox in Streaming\"; ObjectID = \"awK-Ei-T9i\";", "extractionState" : "extracted_with_value", @@ -2899,6 +2929,36 @@ } } }, + "SQK-JJ-izW.text" : { + "comment" : "Class = \"UILabel\"; text = \"Button Visual Feedback\"; ObjectID = \"SQK-JJ-izW\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Button Visual Feedback" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "按键视觉反馈" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "按鍵視覺回饋" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "按鍵視覺回饋" + } + } + } + }, "sUC-Ur-7eI.title" : { "comment" : "Class = \"UIBarButtonItem\"; title = \"Exit\"; ObjectID = \"sUC-Ur-7eI\";", "extractionState" : "extracted_with_value",