From b7d8889180117ac528b16c8f451d38e9f81e4fd0 Mon Sep 17 00:00:00 2001 From: TrueZhuangjia Date: Tue, 28 Jan 2025 10:15:17 +0800 Subject: [PATCH] sensitivity & stick indicator settings in touchPad profile config --- Limelight/Base.lproj/iPhone.storyboard | 24 +++++-- .../Input/CustomOSC/OSCProfilesManager.m | 3 + .../Input/CustomOSC/OnScreenButtonState.h | 3 +- .../Input/CustomOSC/OnScreenButtonState.m | 6 +- Limelight/Input/OnScreenButtonView.swift | 22 +++--- Limelight/Input/StreamView.m | 2 + Limelight/Localization/Localizable.xcstrings | 69 +++++++++++++++++++ .../LayoutOnScreenControlsViewController.m | 28 ++++++-- 8 files changed, 134 insertions(+), 23 deletions(-) diff --git a/Limelight/Base.lproj/iPhone.storyboard b/Limelight/Base.lproj/iPhone.storyboard index 912e0526..278e400f 100644 --- a/Limelight/Base.lproj/iPhone.storyboard +++ b/Limelight/Base.lproj/iPhone.storyboard @@ -870,24 +870,30 @@ ICAgICAgICAgICAgIA - + - + - + + + + + + + + + + + + + @@ -910,6 +922,8 @@ ICAgICAgICAgICAgIA + + @@ -997,13 +1011,13 @@ ICAgICAgICAgICAgIA - + - + diff --git a/Limelight/Input/CustomOSC/OSCProfilesManager.m b/Limelight/Input/CustomOSC/OSCProfilesManager.m index 4a15bc11..b7fc9834 100644 --- a/Limelight/Input/CustomOSC/OSCProfilesManager.m +++ b/Limelight/Input/CustomOSC/OSCProfilesManager.m @@ -290,6 +290,9 @@ static NSMutableDictionary *onScreenButtonViewsDict; buttonState.widthFactor = buttonView.widthFactor; buttonState.heightFactor = buttonView.heightFactor; buttonState.backgroundAlpha = buttonView.backgroundAlpha; + buttonState.sensitivityFactor = buttonView.sensitivityFactor; + buttonState.stickIndicatorXOffset = buttonView.stickIndicatorXOffset; + NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil]; [buttonStatesEncoded addObject: buttonStateEncoded]; }]; diff --git a/Limelight/Input/CustomOSC/OnScreenButtonState.h b/Limelight/Input/CustomOSC/OnScreenButtonState.h index bcf50f1e..2394defe 100644 --- a/Limelight/Input/CustomOSC/OnScreenButtonState.h +++ b/Limelight/Input/CustomOSC/OnScreenButtonState.h @@ -27,7 +27,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) NSTimeInterval timestamp; @property (nonatomic, assign) CGFloat widthFactor; // for OnScreenButtonView @property (nonatomic, assign) CGFloat heightFactor; // for OnScreenButtonView -@property (nonatomic, assign) CGFloat velocityFactor; // for OnScreenButtonView +@property (nonatomic, assign) CGFloat sensitivityFactor; // for OnScreenButtonView +@property (nonatomic, assign) CGFloat stickIndicatorXOffset; // for OnScreenButtonView @property (nonatomic, assign) CGFloat oscLayerSizeFactor; // for OnScreenController CALayer @property (nonatomic, assign) CGFloat backgroundAlpha; // for OnScreenController CALayer diff --git a/Limelight/Input/CustomOSC/OnScreenButtonState.m b/Limelight/Input/CustomOSC/OnScreenButtonState.m index dbbed24e..71f1419f 100644 --- a/Limelight/Input/CustomOSC/OnScreenButtonState.m +++ b/Limelight/Input/CustomOSC/OnScreenButtonState.m @@ -35,7 +35,8 @@ [encoder encodeBool:self.isHidden forKey:@"isHidden"]; [encoder encodeFloat:self.widthFactor forKey:@"widthFactor"]; [encoder encodeFloat:self.heightFactor forKey:@"heightFactor"]; - [encoder encodeFloat:self.velocityFactor forKey:@"velocityFactor"]; + [encoder encodeFloat:self.sensitivityFactor forKey:@"velocityFactor"]; + [encoder encodeFloat:self.stickIndicatorXOffset forKey:@"stickIndicatorOffset"]; [encoder encodeFloat:self.oscLayerSizeFactor forKey:@"oscLayerSizeFactor"]; [encoder encodeFloat:self.backgroundAlpha forKey:@"backgroundAlpha"]; } @@ -50,7 +51,8 @@ self.isHidden = [decoder decodeBoolForKey:@"isHidden"]; self.widthFactor = [decoder decodeFloatForKey:@"widthFactor"]; self.heightFactor = [decoder decodeFloatForKey:@"heightFactor"]; - self.velocityFactor = [decoder decodeFloatForKey:@"velocityFactor"]; + self.sensitivityFactor = [decoder decodeFloatForKey:@"velocityFactor"]; + self.stickIndicatorXOffset = [decoder decodeFloatForKey:@"stickIndicatorOffset"]; self.oscLayerSizeFactor = [decoder decodeFloatForKey:@"oscLayerSizeFactor"]; self.backgroundAlpha = [decoder decodeFloatForKey:@"backgroundAlpha"]; } diff --git a/Limelight/Input/OnScreenButtonView.swift b/Limelight/Input/OnScreenButtonView.swift index 393d9d60..4637d399 100644 --- a/Limelight/Input/OnScreenButtonView.swift +++ b/Limelight/Input/OnScreenButtonView.swift @@ -120,6 +120,8 @@ import UIKit self.mousePointerMoved = false self.touchLockedForMoveEvent = UITouch() self.twoTouchesDetected = false + self.stickIndicatorXOffset = 120 + self.sensitivityFactor = 1.0 super.init(frame: .zero) upIndicator = createLrudDirectionLayer() @@ -305,7 +307,7 @@ import UIKit // create stick indicator: the crossMark & stickBall: @objc public func showStickIndicator(){ // tell if the self button is located on the left or right - self.selfViewOnTheRight = (self.storedLocation.x + self.frame.width/2 > self.appWindow.frame.width*0.5) + self.selfViewOnTheRight = (self.storedLocation.x > self.appWindow.frame.width*0.5) let offsetSign = selfViewOnTheRight ? -1 : 1 let stickMarkerRelativeLocation:CGPoint if !OnScreenButtonView.editMode { @@ -356,7 +358,7 @@ import UIKit let stickBallLayer = CAShapeLayer() stickBallLayer.path = path.cgPath // Assign the circular path to the shape layer self.layer.superlayer?.addSublayer(stickBallLayer) - stickBallLayer.position = CGPointMake(CGRectGetMidX(self.crossMarkLayer.frame), CGRectGetMinY(self.crossMarkLayer.frame)) + stickBallLayer.position = CGPointMake(CGRectGetMidX(self.crossMarkLayer.frame), CGRectGetMidY(self.crossMarkLayer.frame)) // stickBallLayer.position = CG @@ -373,18 +375,18 @@ import UIKit return stickBallLayer } - @objc public func updateStickBallPosition(){ + @objc public func updateStickIndicator(){ CATransaction.begin() CATransaction.setDisableActions(true) self.stickBallLayer.removeAllAnimations() if !OnScreenButtonView.editMode { - self.stickBallLayer.position = CGPointMake(CGRectGetMidX(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetX), CGRectGetMinY(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetY)) + self.stickBallLayer.position = CGPointMake(CGRectGetMidX(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetX*sensitivityFactor), CGRectGetMidY(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetY*sensitivityFactor)) } else{ // illustrate offset distance in edit mode let offsetSign = self.selfViewOnTheRight ? -1 : 1 - let illlustrationPoint = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame)/4) - self.stickBallLayer.position = CGPointMake(CGRectGetMidX(self.crossMarkLayer.frame) + CGFloat(offsetSign) * stickIndicatorXOffset, CGRectGetMinY(self.crossMarkLayer.frame)) + // let illlustrationPoint = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame)/4) + self.crossMarkLayer.position = CGPointMake(CGRectGetMidX(self.stickBallLayer.frame) + CGFloat(offsetSign) * stickIndicatorXOffset, CGRectGetMidY(self.stickBallLayer.frame)) } CATransaction.commit() } @@ -816,10 +818,10 @@ import UIKit break case "LSPAD": self.sendLeftStickTouchPadEvent(inputX: offSetX * sensitivityFactor, inputY: offSetY*sensitivityFactor) - updateStickBallPosition() + updateStickIndicator() case "RSPAD": self.sendRightStickTouchPadEvent(inputX: offSetX * sensitivityFactor, inputY: offSetY * sensitivityFactor); - updateStickBallPosition() + updateStickIndicator() case "LSVPAD": self.sendLeftStickTouchPadEvent(inputX: deltaX*1.5167*sensitivityFactor, inputY: deltaY*1.5167*sensitivityFactor) case "RSVPAD": @@ -942,7 +944,9 @@ import UIKit if CommandManager.nonVectorStickPads.contains(self.keyString) { self.crossMarkLayer.removeFromSuperlayer() self.stickBallLayer.removeFromSuperlayer() - self.showStickIndicator()} + self.showStickIndicator() + self.updateStickIndicator() + } } } } diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m index 6c3be13f..f51f8df2 100644 --- a/Limelight/Input/StreamView.m +++ b/Limelight/Input/StreamView.m @@ -401,6 +401,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; buttonView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place buttonView.widthFactor = buttonState.widthFactor; buttonView.heightFactor = buttonState.heightFactor; + buttonView.sensitivityFactor = buttonState.sensitivityFactor; + buttonView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset; // Add the buttonView to the view controller's view [self->streamFrameTopLayerView addSubview:buttonView]; // add keyboard button to the stream frame view. must add it to the target view before setting location. [buttonView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y]; diff --git a/Limelight/Localization/Localizable.xcstrings b/Limelight/Localization/Localizable.xcstrings index a2d792e7..8e6f156f 100644 --- a/Limelight/Localization/Localizable.xcstrings +++ b/Limelight/Localization/Localizable.xcstrings @@ -191,6 +191,29 @@ } } }, + "Ball: assumed touch point. Cross: indicator location" : { + "extractionState" : "manual", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "小球: 假定的触点 十字: 指示器偏离位置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "灵敏度: %.2f" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "小球: 假定的触点 十字: 指示器偏离位置" + } + } + } + }, "Bitrate: %.1f Mbps" : { "extractionState" : "manual", "localizations" : { @@ -962,6 +985,29 @@ } } }, + "Indicator Offset: %.2f" : { + "extractionState" : "manual", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "指示器偏离: %.2f" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "小球: 假定的触点 十字: 指示器偏离位置" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "指示器偏离: %.2f" + } + } + } + }, "Key label (optional)" : { "extractionState" : "manual", "localizations" : { @@ -2102,6 +2148,29 @@ } } }, + "Sensitivity: %.2f" : { + "extractionState" : "manual", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "灵敏度: %.2f" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "指示器偏离: %.2f" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "灵敏度: %.2f" + } + } + } + }, "Set PC/Game resolution:" : { "extractionState" : "manual", "localizations" : { diff --git a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m index 76e607d1..8a07f3a4 100644 --- a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m +++ b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m @@ -47,6 +47,10 @@ - (void) viewWillDisappear:(BOOL)animated{ OnScreenButtonView.editMode = false; + for (OnScreenButtonView* buttonView in self.onScreenButtonViewsDict.allValues){ + [buttonView.stickBallLayer removeFromSuperlayer]; + [buttonView.crossMarkLayer removeFromSuperlayer]; + } [super viewWillDisappear:animated]; [[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutCloseNotification" object:self]; } @@ -74,6 +78,8 @@ buttonView.timestamp = buttonState.timestamp; // will be set as key in in the dict. buttonView.widthFactor = buttonState.widthFactor; buttonView.heightFactor = buttonState.heightFactor; + buttonView.sensitivityFactor = buttonState.sensitivityFactor; + buttonView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset; // buttonView.backgroundAlpha = buttonState.backgroundAlpha; // Add the buttonView to the view controller's view [self.view addSubview:buttonView]; @@ -143,7 +149,7 @@ object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(buttonViewSelected:) + selector:@selector(buttonViewTapped:) name:@"OnScreenButtonViewSelected" object:nil]; @@ -380,7 +386,7 @@ } } -- (void)buttonViewSelected: (NSNotification *)notification{ +- (void)buttonViewTapped: (NSNotification *)notification{ // receive the selected buttonView obj passed from the notification OnScreenButtonView* buttonView = (OnScreenButtonView* )notification.object; self->buttonViewSelected = true; @@ -406,7 +412,9 @@ [selectedButtonView.crossMarkLayer removeFromSuperlayer]; selectedButtonView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedButtonView.frame)/2, CGRectGetHeight(selectedButtonView.frame)/4); [selectedButtonView showStickIndicator];// this will create the indicator CAShapeLayers - [stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f \n", self->selectedButtonView.stickIndicatorXOffset]]; + [self.stickIndicatorOffsetSlider setValue:self->selectedButtonView.stickIndicatorXOffset]; + [stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self->selectedButtonView.stickIndicatorXOffset]]; + [self->selectedButtonView updateStickIndicator]; } [widgetSizeSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Size: %.2f", self->selectedButtonView.widthFactor]]; [widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self->selectedButtonView.heightFactor]]; @@ -417,6 +425,12 @@ // receive the selected buttonView obj passed from the notification CALayer* controllerLayer = (CALayer* )notification.object; self->buttonViewSelected = false; + self->stickIndicatorOffsetExplain.hidden = true; + self->stickIndicatorOffsetSliderLabel.hidden = true; + self.stickIndicatorOffsetSlider.hidden = true; + self->sensitivitySliderLabel.hidden = true; + self.sensitivityFactorSlider.hidden = true; + self->controllerLayerSelected = true; self->selectedControllerLayer = controllerLayer; self->controllerLoadedBounds = controllerLayer.bounds; @@ -480,7 +494,7 @@ [stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self.stickIndicatorOffsetSlider.value]]; if(self->selectedButtonView != nil && self->buttonViewSelected){ self->selectedButtonView.stickIndicatorXOffset = self.stickIndicatorOffsetSlider.value; - [self->selectedButtonView updateStickBallPosition]; + [self->selectedButtonView updateStickIndicator]; } return; } @@ -569,7 +583,7 @@ widgetAlphaSliderLabel.hidden = NO; - // sensivity slider + // sensitivity slider self.sensitivityFactorSlider.hidden = YES; self.sensitivityFactorSlider.frame = CGRectMake(sliderXPosition, self.sensitivityFactorSlider.frame.origin.y, self.sensitivityFactorSlider.frame.size.width, self.sensitivityFactorSlider.frame.size.height); [self.sensitivityFactorSlider addTarget:self action:@selector(sensitivitySliderMoved) forControlEvents:(UIControlEventValueChanged)]; @@ -599,7 +613,7 @@ stickIndicatorOffsetSliderLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; stickIndicatorOffsetSliderLabel.translatesAutoresizingMaskIntoConstraints = NO; // Disable autoresizing mask for Auto Layout // tips for stick indicator - stickIndicatorOffsetExplain.text = [LocalizationHelper localizedStringForKey:@"Cross: assumed touch point. Ball: indicator location"]; + stickIndicatorOffsetExplain.text = [LocalizationHelper localizedStringForKey:@"Ball: assumed touch point. Cross: indicator location"]; //stickIndicatorOffsetExplain.frame = CGRectMake(sliderXPosition, self.stickIndicatorOffsetSlider.frame.origin.y + self.stickIndicatorOffsetSlider.frame.size.height, self.stickIndicatorOffsetSlider.frame.size.width, self.stickIndicatorOffsetSlider.frame.size.height); // label bigger show some tips stickIndicatorOffsetExplain.font = [UIFont systemFontOfSize:18]; stickIndicatorOffsetExplain.textColor = [UIColor whiteColor]; @@ -750,6 +764,8 @@ if([self touchWithinTashcanButton:touch]){ [self.onScreenButtonViewsDict[@(OnScreenButtonView.timestampOfButtonBeingDragged)] removeFromSuperview]; [self.onScreenButtonViewsDict removeObjectForKey:@(OnScreenButtonView.timestampOfButtonBeingDragged)]; + [selectedButtonView.stickBallLayer removeFromSuperlayer]; + [selectedButtonView.crossMarkLayer removeFromSuperlayer]; OnScreenButtonView.timestampOfButtonBeingDragged = 0; //reset thie timestamp }