diff --git a/VoidLink/Input/CommandManager.swift b/VoidLink/Input/CommandManager.swift index 839c063e..a8ab3074 100644 --- a/VoidLink/Input/CommandManager.swift +++ b/VoidLink/Input/CommandManager.swift @@ -144,7 +144,8 @@ import UIKit "PENCILHOVER", "BRUSH", "ERASER", - "NOSINGLETOUCH" + "NOSINGLETOUCH", + "DISABLETOUCH", ] @objc public static let pencilProButtonCmds: [String] = [ "PENCILHOVER", diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift index 49eaca26..407c9517 100644 --- a/VoidLink/Input/OnScreenWidgetView.swift +++ b/VoidLink/Input/OnScreenWidgetView.swift @@ -54,6 +54,7 @@ import SVGKit func replaceBrush(shortcut:String) func replaceEraser(shortcut:String) func presentPressureCurveVC() + func toggleTouch(disabled:Bool) } @objc enum WidgetTypeEnum: UInt8 { @@ -72,6 +73,7 @@ import SVGKit @objc static public var editMode: Bool = false @objc static public var buttonVisualFeedbackEnabled: Bool = true @objc public var widgetLabel: String + private var nonEditableWidgetLabel: String = "" @objc public var cmdString: String @objc public var sequence: Int16 = -1 private var buttonString: String = "" @@ -165,6 +167,7 @@ import SVGKit @objc public var isStickWheel: Bool = false @objc public var isFolder: Bool = false + @objc public var hasNonEditableLabel: Bool = false // for all stick pads @objc public var minStickOffset: CGFloat = 0 @@ -481,6 +484,7 @@ import SVGKit || (self.widgetType == WidgetTypeEnum.button && (buttonMode == .slideAndHold || buttonMode == .slideToToggle)))*/ self.hasTrackPoint = true + self.hasNonEditableLabel = self.cmdString == "DISABLETOUCH" } // ====================================================================================================== @@ -777,7 +781,15 @@ import SVGKit } private func setupAtrributedText(){ - let text = self.widgetLabel.contains("#") ? "\(self.widgetLabel.split(separator: "#").first ?? "")" : SwiftLocalizationHelper.localizedString(forKey: self.widgetLabel) + var text = self.widgetLabel.contains("#") ? "\(self.widgetLabel.split(separator: "#").first ?? "")" : SwiftLocalizationHelper.localizedString(forKey: self.widgetLabel) + + if self.hasNonEditableLabel { + if cmdString == "DISABLETOUCH" { + self.nonEditableWidgetLabel = SwiftLocalizationHelper.localizedString(forKey: touchDisabledFLag ? "=EnableTouch" : "=DisableTouch" ) + } + text = self.nonEditableWidgetLabel + } + let attr = NSAttributedString( string: self.folded ? "[\(text)]" : text, attributes: [ @@ -2481,10 +2493,19 @@ import SVGKit ].contains(Bundle.main.bundleIdentifier) && GenericUtils.isIPad() { self.functionalButtonDelegate?.presentPressureCurveVC() } + case "DISABLETOUCH": + self.handleTouchDisableButtonUp() default: break } } + + private var touchDisabledFLag:Bool = false + private func handleTouchDisableButtonUp(){ + touchDisabledFLag = !touchDisabledFLag + self.setupAtrributedText() + self.functionalButtonDelegate?.toggleTouch(disabled: touchDisabledFLag) + } private func temporaryDisableFolderButtonAnimation(){ OnScreenWidgetView.enableFolderAnimation = false diff --git a/VoidLink/Input/StreamView.h b/VoidLink/Input/StreamView.h index 0cf36b9e..db39685f 100644 --- a/VoidLink/Input/StreamView.h +++ b/VoidLink/Input/StreamView.h @@ -79,6 +79,7 @@ - (void)enablePencilHover; - (void)disablePencilHover; - (void)setAllowSingleTouchEnabled:(BOOL)enabled; +- (void)toggleTouchDisabled:(bool)disabled; #if !TARGET_OS_TV - (void) updateCursorLocation:(CGPoint)location isMouse:(BOOL)isMouse; diff --git a/VoidLink/Input/StreamView.m b/VoidLink/Input/StreamView.m index f97e8c45..003ef639 100644 --- a/VoidLink/Input/StreamView.m +++ b/VoidLink/Input/StreamView.m @@ -57,7 +57,9 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; int localMousePointerMode; + TouchMode touchMode; UIResponder* touchHandler; + UIResponder* sessionTouchHandler; NSTimer* interactionTimer; BOOL hasUserInteracted; @@ -121,7 +123,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; designatedSoftKeyboardHeight = settings.softKeyboardHeight * GenericUtils.screenHeight; keyboardHeightDesignatedForLandscape = designatedSoftKeyboardHeight != 0; - // if(settings.touchMode.intValue == NativeTouchOnly) [self addGestureRecognizer:keyboardToggleRecognizer]; //keep legacy approach in pure native mode + // if(touchMode == NativeTouchOnly) [self addGestureRecognizer:keyboardToggleRecognizer]; //keep legacy approach in pure native mode // else [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes // [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes @@ -135,8 +137,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; _pencilHandler = PencilHandler.shared; // iOS uses touch Mode depending on user preference - - switch (settings.touchMode.intValue) { + touchMode = settings.touchMode.intValue; + switch (touchMode) { case NativeTouch: keyboardToggleRecognizer.immediateTriggering = false; self->touchHandler = [[NativeTouchHandler alloc] initWithView:self andSettings:settings]; @@ -161,19 +163,20 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; default: break; } + sessionTouchHandler = touchHandler; // we'll render on-screen controls on the toplayer too: _onScreenControls = [[OnScreenControls alloc] initWithView:self->_streamFrameTopLayerView controllerSup:controllerSupport streamConfig:streamConfig]; // don't delete, this is mandatory // OnScreenControls.shared = _onScreenControls; /* // here we pass the tap recognizer to the onscreencontrols obj - if (settings.touchMode.intValue == RelativeTouch){ + if (touchMode == RelativeTouch){ RelativeTouchHandler* relativeTouchHandler = (RelativeTouchHandler*) touchHandler; onScreenControls.mouseRightClickTapRecognizer = relativeTouchHandler.mouseRightClickTapRecognizer; } */ OnScreenControlsLevel level = (OnScreenControlsLevel)[settings.onscreenControls integerValue]; - if (settings.touchMode.intValue != RelativeTouch && settings.touchMode.intValue != NativeTouch ) { + if (touchMode != RelativeTouch && touchMode != NativeTouch ) { Log(LOG_I, @"On-screen controls disabled in non-relative touch mode"); [_onScreenControls setLevel:OnScreenControlsLevelOff]; @@ -181,7 +184,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; [OnScreenControls.touchesCapturedByOnScreenControls removeAllObjects]; // reset the attribute to nil /* - if(settings.touchMode.intValue == NativeTouch){ + if(touchMode == NativeTouch){ NativeTouchHandler* nativeTouchHandler = (NativeTouchHandler* )touchHandler; nativeTouchHandler.touchesCapturedByOnScreenButtons = onScreenControls.touchesCapturedByOnScreenButtons; touchHandler = nativeTouchHandler; @@ -486,7 +489,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; // we'll enable on screen buttons, and disable on screen controllers for absolute touch - (bool) isOscEnabled{ - return (settings.touchMode.intValue == RelativeTouch || settings.touchMode.intValue == NativeTouch || settings.touchMode.intValue == AbsoluteTouch || settings.touchMode.intValue == TouchDisabled) && settings.onscreenControls.intValue != OnScreenControlsLevelOff; + return (touchMode == RelativeTouch || touchMode == NativeTouch || touchMode == AbsoluteTouch || touchMode == TouchDisabled) && settings.onscreenControls.intValue != OnScreenControlsLevelOff; } // we'll enable on screen buttons, and disable on screen controllers for absolute touch @@ -920,7 +923,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; #if !TARGET_OS_TV // if (@available(iOS 13.4, *)) { // cancel restriction of native touch for iOS13.3 & lower - if (settings.touchMode.intValue == NativeTouchOnly) { + if (touchMode == NativeTouchOnly) { [touchHandler touchesBegan:touches withEvent:event]; return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only. } @@ -951,7 +954,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; [self startInteractionTimer]; NSSet* targetTouches = nonPencilTouches ? nonPencilTouches : touches; - if(settings.touchMode.intValue == NativeTouch || settings.touchMode.intValue == RelativeTouch){ + if(touchMode == NativeTouch || touchMode == RelativeTouch){ [self->_onScreenControls handleTouchDownEvent:targetTouches]; [self->touchHandler touchesBegan:targetTouches withEvent:event]; } @@ -1087,7 +1090,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { #if !TARGET_OS_TV - if (settings.touchMode.intValue == NativeTouchOnly) { + if (touchMode == NativeTouchOnly) { [touchHandler touchesMoved:touches withEvent:event]; return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only. } @@ -1128,7 +1131,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; hasUserInteracted = YES; NSSet* targetTouches = nonPencilTouches ? nonPencilTouches : touches; - if(self->settings.touchMode.intValue == NativeTouch || self->settings.touchMode.intValue == RelativeTouch){ + if(self->touchMode == NativeTouch || self->touchMode == RelativeTouch){ [self->touchHandler touchesMoved:targetTouches withEvent:event]; [self->_onScreenControls handleTouchMovedEvent:targetTouches]; } @@ -1202,7 +1205,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { #if !TARGET_OS_TV - if (settings.touchMode.intValue == NativeTouchOnly) { + if (touchMode == NativeTouchOnly) { [touchHandler touchesEnded:touches withEvent:event]; return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only. } @@ -1233,7 +1236,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; hasUserInteracted = YES; NSSet* targetTouches = nonPencilTouches ? nonPencilTouches : touches; - if(settings.touchMode.intValue == NativeTouch || settings.touchMode.intValue == RelativeTouch){ + if(touchMode == NativeTouch || touchMode == RelativeTouch){ [self->touchHandler touchesEnded:targetTouches withEvent:event]; // when touches ended, must call the native touchhandler before onScreenControls, since the NSSet of touches captured by on screen button shall be updated later [self->_onScreenControls handleTouchUpEvent:targetTouches]; } @@ -1243,7 +1246,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [touchHandler touchesCancelled:touches withEvent:event]; #if !TARGET_OS_TV - if (settings.touchMode.intValue == NativeTouchOnly) return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only. + if (touchMode == NativeTouchOnly) return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only. for (UITouch* touch in touches) { if (touch.type == UITouchTypePencil) { [self touchesEnded:touches withEvent:event]; @@ -1613,6 +1616,10 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; } } +- (void)toggleTouchDisabled:(bool)disabled{ + touchHandler = disabled ? nil : sessionTouchHandler; +} + - (void)cleanUp{ [keyInputField resignFirstResponder]; keyInputField.delegate = nil; diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings index 100671d3..62f537e7 100644 --- a/VoidLink/Localization/Localizable.xcstrings +++ b/VoidLink/Localization/Localizable.xcstrings @@ -617,6 +617,64 @@ } } }, + "=DisableTouch" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "🚫 Touch" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "🚫 触摸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "🚫 觸摸" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "🚫 觸摸" + } + } + } + }, + "=EnableTouch" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "🟢 Touch" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "🟢 触摸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "🟢 觸摸" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "🟢 觸摸" + } + } + } + }, "=gyroRsvpad" : { "extractionState" : "manual", "localizations" : { diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index 9e7d5abc..804fe10b 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -1664,6 +1664,10 @@ } } +- (void)toggleTouchWithDisabled:(BOOL)disabled{ + [_streamView toggleTouchDisabled:disabled]; +} + - (void)presentPressureCurveVC{ if(_oscProfile.pressureCurveEnabled){ PressureCurveViewController* pressureCurveVC = [[PressureCurveViewController alloc] init];