From 9dda59451917a55de14fff9c20a64ec6cd549f04 Mon Sep 17 00:00:00 2001 From: TrueZhuanjia Date: Sun, 19 Oct 2025 11:04:56 +0800 Subject: [PATCH] feat: on-screen widget border alpha tweak --- VoidLink/Input/CustomOSC/OSCProfilesManager.m | 1 + .../Input/CustomOSC/OnScreenButtonState.h | 1 + .../Input/CustomOSC/OnScreenButtonState.m | 2 + VoidLink/Input/OnScreenWidgetView.swift | 32 ++++--- VoidLink/Input/StreamView.m | 3 +- VoidLink/Localization/Localizable.xcstrings | 23 +++++ VoidLink/ThemeManager.m | 2 - .../LayoutOnScreenControlsViewController.m | 83 +++++++++++++------ 8 files changed, 101 insertions(+), 46 deletions(-) diff --git a/VoidLink/Input/CustomOSC/OSCProfilesManager.m b/VoidLink/Input/CustomOSC/OSCProfilesManager.m index cd37c925..f5395a45 100644 --- a/VoidLink/Input/CustomOSC/OSCProfilesManager.m +++ b/VoidLink/Input/CustomOSC/OSCProfilesManager.m @@ -394,6 +394,7 @@ static CGRect layoutViewBounds; buttonState.heightFactor = [self normalizeSizeHeightFactor:widgetView and:buttonState]; buttonState.backgroundAlpha = widgetView.backgroundAlpha; buttonState.labelAlpha = widgetView.labelAlpha; + buttonState.borderAlpha = widgetView.borderAlpha; buttonState.borderWidth = widgetView.borderWidth; buttonState.autoTapInterval = widgetView.autoTapInterval; buttonState.vibrationStyle = widgetView.vibrationStyle; diff --git a/VoidLink/Input/CustomOSC/OnScreenButtonState.h b/VoidLink/Input/CustomOSC/OnScreenButtonState.h index bd67f961..c7f525a3 100644 --- a/VoidLink/Input/CustomOSC/OnScreenButtonState.h +++ b/VoidLink/Input/CustomOSC/OnScreenButtonState.h @@ -45,6 +45,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) CGFloat oscLayerSizeFactor; // for OnScreenController CALayer @property (nonatomic, assign) CGFloat backgroundAlpha; @property (nonatomic, assign) CGFloat labelAlpha; +@property (nonatomic, assign) CGFloat borderAlpha; @property (nonatomic, assign) uint8_t vibrationStyle; @property (nonatomic, assign) uint8_t mouseButtonAction; @property (nonatomic, assign) uint16_t autoTapInterval; diff --git a/VoidLink/Input/CustomOSC/OnScreenButtonState.m b/VoidLink/Input/CustomOSC/OnScreenButtonState.m index c72c5a99..1adccb81 100644 --- a/VoidLink/Input/CustomOSC/OnScreenButtonState.m +++ b/VoidLink/Input/CustomOSC/OnScreenButtonState.m @@ -53,6 +53,7 @@ [encoder encodeFloat:self.oscLayerSizeFactor forKey:@"oscLayerSizeFactor"]; [encoder encodeFloat:self.backgroundAlpha forKey:@"backgroundAlpha"]; [encoder encodeFloat:self.labelAlpha forKey:@"labelAlpha"]; + [encoder encodeFloat:self.borderAlpha forKey:@"borderAlpha"]; [encoder encodeFloat:self.borderWidth forKey:@"borderWidth"]; [encoder encodeObject:self.widgetShape forKey:@"widgetShape"]; [encoder encodeFloat:self.minStickOffset forKey:@"minStickOffset"]; @@ -82,6 +83,7 @@ self.oscLayerSizeFactor = [decoder decodeFloatForKey:@"oscLayerSizeFactor"]; self.backgroundAlpha = [decoder containsValueForKey:@"backgroundAlpha"] ? [decoder decodeFloatForKey:@"backgroundAlpha"] : 0.5; self.labelAlpha = [decoder containsValueForKey:@"labelAlpha"] ? [decoder decodeFloatForKey:@"labelAlpha"] : 0.82; + self.borderAlpha = [decoder containsValueForKey:@"borderAlpha"] ? [decoder decodeFloatForKey:@"borderAlpha"] : self.labelAlpha*1.01; self.borderWidth = [decoder decodeFloatForKey:@"borderWidth"]; self.widgetShape = [decoder decodeObjectForKey:@"widgetShape"]; self.minStickOffset = [decoder decodeFloatForKey:@"minStickOffset"]; diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift index 74edb6cc..3f9b5eac 100644 --- a/VoidLink/Input/OnScreenWidgetView.swift +++ b/VoidLink/Input/OnScreenWidgetView.swift @@ -74,6 +74,7 @@ import UIKit @objc public var borderWidth: CGFloat = 0.0 @objc public var backgroundAlpha: CGFloat = 0.5 @objc public var labelAlpha: CGFloat = 0.82 + @objc public var borderAlpha: CGFloat = 0.82 * 1.01 @objc public var vibrationStyle: Int = 6 @objc public var latestTouchLocation: CGPoint @objc public var selfViewOnTheRight: Bool = false @@ -407,15 +408,9 @@ import UIKit layoutChanges.removeLast() } - @objc public func adjustTransparency(alpha: CGFloat){ - if alpha != 0 { - self.backgroundAlpha = alpha - } - else{ - // self.backgroundAlpha = 0.5 - self.backgroundAlpha = alpha - } - self.tweakAlpha() + @objc public func adjustTransparency(alpha: CGFloat, tweakBorderAlpha:Bool){ + self.backgroundAlpha = alpha + self.tweakAlpha(tweakBorderAlpha: tweakBorderAlpha) } @objc public func adjustBorder(width: CGFloat){ @@ -461,17 +456,18 @@ import UIKit label.textColor = UIColor(white: 1.0, alpha: labelAlpha) } - private func tweakAlpha(){ + @objc public func tweakBorderAlpha(alpha:CGFloat){ + borderAlpha = alpha + defaultBorderColor = UIColor(white: 0.2, alpha: borderAlpha).cgColor + self.layer.borderColor = defaultBorderColor + } + + private func tweakAlpha(tweakBorderAlpha:Bool){ // setup default border from self.backgroundAlpha let realBackgroundAlpha = self.backgroundAlpha - 0.18 // offset to be consistent with legacy onScreen controller layer opacity self.backgroundColor = UIColor(white: 0.2, alpha: realBackgroundAlpha) // offset to be consistent with legacy onScreen controller layer opacity - var borderAlpha = realBackgroundAlpha * 1.01 - if widgetType == WidgetTypeEnum.touchPad { - minimumBorderAlpha = 0.0 - } - if borderAlpha < minimumBorderAlpha { - borderAlpha = minimumBorderAlpha - } + + borderAlpha = tweakBorderAlpha ? realBackgroundAlpha * 1.01 : borderAlpha defaultBorderColor = UIColor(white: 0.2, alpha: borderAlpha).cgColor self.layer.borderColor = defaultBorderColor @@ -580,7 +576,7 @@ import UIKit self.setSquareWidgetCornerRadius() self.layer.borderWidth = self.borderWidth - self.tweakAlpha() + self.tweakAlpha(tweakBorderAlpha: false) if self.shape == "default" || self.shape.isEmpty { if CommandManager.oscButtonMappings.keys.contains(self.buttonString) && !CommandManager.oscRectangleButtonCmds.contains(self.buttonString){ //make oscButtons round diff --git a/VoidLink/Input/StreamView.m b/VoidLink/Input/StreamView.m index 3a295fd2..ffe2f809 100644 --- a/VoidLink/Input/StreamView.m +++ b/VoidLink/Input/StreamView.m @@ -575,9 +575,10 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; // widgetView.sizeReference = buttonState.sizeReference; //portrait markmarkmark [widgetView resizeWidgetView]; // resize must be called after relocation - [widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha]; + [widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha tweakBorderAlpha:NO]; [widgetView adjustBorderWithWidth:buttonState.borderWidth]; [widgetView tweakLabelAlphaWithAlpha:buttonState.labelAlpha]; + [widgetView tweakBorderAlphaWithAlpha:buttonState.borderAlpha]; [widgetView setupAutoTapTimer]; } } diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings index 171858ad..8500bae8 100644 --- a/VoidLink/Localization/Localizable.xcstrings +++ b/VoidLink/Localization/Localizable.xcstrings @@ -1025,6 +1025,29 @@ } } }, + "Border alpha: %.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" + } + } + } + }, "Border width" : { "extractionState" : "manual", "localizations" : { diff --git a/VoidLink/ThemeManager.m b/VoidLink/ThemeManager.m index 8248c3a5..d4da5d8c 100644 --- a/VoidLink/ThemeManager.m +++ b/VoidLink/ThemeManager.m @@ -28,8 +28,6 @@ static UIUserInterfaceStyle _userInterfaceStyle; } } - - + (UIUserInterfaceStyle)userInterfaceStyle { [ThemeManager setPublicUIStyle]; return _userInterfaceStyle; diff --git a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m index 8ee999c2..e19ba6f4 100644 --- a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m +++ b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m @@ -21,6 +21,13 @@ @interface LayoutOnScreenControlsViewController () +typedef NS_ENUM(NSUInteger, AlphaSliderMode) { + widgetAlpha, + labelAlpha, + borderAlpha, + AlphaSliderModeCount +}; + @end @@ -28,7 +35,7 @@ BOOL isToolbarHidden; OSCProfilesManager* profilesManager; OnScreenWidgetView* selectedWidgetView; - bool labelAlphaLoaded; + AlphaSliderMode alphaSliderMode; CALayer* selectedControllerLayer; CGRect controllerLoadedBounds; bool widgetViewSelected; @@ -152,8 +159,9 @@ [widgetView setLocationWithPosition:buttonState.position]; widgetView.sizeReference = [self getCurrentWidgetSizeReference]; [widgetView resizeWidgetView]; // resize must be called after relocation - [widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha]; + [widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha tweakBorderAlpha:NO]; [widgetView tweakLabelAlphaWithAlpha:buttonState.labelAlpha]; + [widgetView tweakBorderAlphaWithAlpha:buttonState.borderAlpha]; [widgetView adjustBorderWithWidth:buttonState.borderWidth]; [self.onScreenWidgetViews addObject:widgetView]; } @@ -339,10 +347,30 @@ - (void)switchAlphaSlider:(UISwipeGestureRecognizer *)sender { if(!widgetViewSelected) return; - labelAlphaLoaded = !labelAlphaLoaded; - if(labelAlphaLoaded) [self.widgetAlphaSlider setValue: self->selectedWidgetView.labelAlpha]; - else [self.widgetAlphaSlider setValue: self->selectedWidgetView.backgroundAlpha]; - [self widgetAlphaSliderMoved:self.widgetAlphaSlider]; + alphaSliderMode = (alphaSliderMode + 1) % AlphaSliderModeCount; + [self loadWidgetAlphas]; +} + +- (void)loadWidgetAlphas{ + if(self->selectedWidgetView != nil && self->widgetViewSelected){ + switch(alphaSliderMode){ + case widgetAlpha: + [self.widgetAlphaSlider setValue: self->selectedWidgetView.backgroundAlpha]; + [self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Alpha: %.2f", _widgetAlphaSlider.value]]; + break; + case labelAlpha: + [self.widgetAlphaSlider setValue: self->selectedWidgetView.labelAlpha]; + [self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Label alpha: %.2f", _widgetAlphaSlider.value]]; + break; + case borderAlpha: + [self.widgetAlphaSlider setValue: self->selectedWidgetView.borderAlpha]; + [self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Border alpha: %.2f", _widgetAlphaSlider.value]]; + break; + case AlphaSliderModeCount: + default: + break; + } + } } /* animates the toolbar up and off the screen or back down onto the screen */ @@ -672,8 +700,9 @@ else [newWidget setLocationWithPosition:widget.center]; newWidget.sizeReference = widget.sizeReference; [newWidget resizeWidgetView]; // resize must be called after relocation - [newWidget adjustTransparencyWithAlpha:widget.backgroundAlpha]; + [newWidget adjustTransparencyWithAlpha:widget.backgroundAlpha tweakBorderAlpha:NO]; [newWidget tweakLabelAlphaWithAlpha:widget.labelAlpha]; + [newWidget tweakBorderAlphaWithAlpha:widget.borderAlpha]; [newWidget adjustBorderWithWidth:widget.borderWidth]; [self.onScreenWidgetViews addObject:newWidget]; self->selectedWidgetView = newWidget; @@ -763,8 +792,6 @@ */ - (void)widgetViewTapped: (NSNotification *)notification{ - //self.undoButton.alpha = selectedWidgetView.layoutChanges.count>1 && !CGPointEqualToPoint(selectedWidgetView.layoutChanges.lastObject.CGPointValue, selectedWidgetView.initialCenter)? 1.0 : 0.3; - // labelAlphaLoaded = false; [self hideStickIndicators]; @@ -851,10 +878,9 @@ [self autoFitLabel:self.widgetHeightLabel]; [self.widgetHeightLabel setText:[LocalizationHelper localizedStringForKey:@"Height: %.2f", self->selectedWidgetView.deNormalizedHeightFactor]]; - if(labelAlphaLoaded) [self.widgetAlphaSlider setValue: self->selectedWidgetView.labelAlpha]; - else [self.widgetAlphaSlider setValue: self->selectedWidgetView.backgroundAlpha]; + + [self loadWidgetAlphas]; [self autoFitLabel:self.widgetAlphaLabel]; - [self widgetAlphaSliderMoved:self.widgetAlphaSlider]; [self.widgetBorderWidthSlider setValue:self->selectedWidgetView.borderWidth]; [self autoFitLabel:self.widgetBorderWidthLabel]; @@ -871,7 +897,6 @@ NSForegroundColorAttributeName:[[UIColor whiteColor] colorWithAlphaComponent:0.77] }]; [self autoFitLabel:self.autoTapLabel]; - // [self autoTapSliderMoved:self.autoTapSlider]; self.decelerationRateStack.hidden = !selectedWidgetView.hasTrackBall; [self.decelerationRateSlider setValue:selectedWidgetView.trackballDecelerationRate]; @@ -967,20 +992,28 @@ } - (void)widgetAlphaSliderMoved:(UISlider* )sender{ - if(labelAlphaLoaded){ - [self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Label alpha: %.2f", sender.value]]; - [selectedWidgetView tweakLabelAlphaWithAlpha:sender.value]; - } - else{ - [self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Alpha: %.2f", sender.value]]; - if(self->selectedWidgetView != nil && self->widgetViewSelected){ - [self->selectedWidgetView adjustTransparencyWithAlpha:sender.value]; - } - - if(self->selectedControllerLayer != nil && self->controllerLayerSelected){ - [self.layoutOSC adjustControllerLayerOpacityWith:self->selectedControllerLayer and:sender.value]; + if(self->selectedWidgetView != nil && self->widgetViewSelected){ + switch(alphaSliderMode){ + case widgetAlpha: + [self->selectedWidgetView adjustTransparencyWithAlpha:sender.value tweakBorderAlpha:YES]; + break; + case labelAlpha: + [selectedWidgetView tweakLabelAlphaWithAlpha:sender.value]; + break; + case borderAlpha: + [self->selectedWidgetView tweakBorderAlphaWithAlpha:sender.value]; + break; + case AlphaSliderModeCount: + default: + break; } + [self loadWidgetAlphas]; } + + if(self->selectedControllerLayer != nil && self->controllerLayerSelected){ + [self.layoutOSC adjustControllerLayerOpacityWith:self->selectedControllerLayer and:sender.value]; + } + return; }