- tweak widget templates

- multiple on-screen widget tweaks and improvements
This commit is contained in:
True Zhuanjia
2026-06-05 16:58:51 +08:00
parent f762ecc3b2
commit e2eccd7968
14 changed files with 289 additions and 80 deletions
+3
View File
@@ -29,6 +29,7 @@ import UIKit
@objc public static var alertController:UIAlertController = UIAlertController()
@objc public static var cancelButtonString:String = "Cancel"
@objc public static var autoCompletion:Bool = false
@objc public static var isCountingDown:Bool = false
@objc class func showAlert(
in viewController: UIViewController? = nil,
@@ -76,6 +77,7 @@ import UIKit
}
viewController.present(alertController, animated: true, completion: action)
isCountingDown = !autoCompletion && countdown > 0
if(countdown == 0) {return}
@@ -91,6 +93,7 @@ import UIKit
remainingSeconds -= 1
if remainingSeconds <= 0 {
isCountingDown = false
isAlertDismissed = true
timer.cancel()
if autoCompletion {
+6 -6
View File
@@ -3057,7 +3057,7 @@
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="16383" translatesAutoresizingMaskIntoConstraints="NO" id="YBB-sq-fpO">
<slider verifyAmbiguity="off" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="32766" translatesAutoresizingMaskIntoConstraints="NO" id="YBB-sq-fpO">
<rect key="frame" x="195" y="0.0" width="455" height="34"/>
<color key="tintColor" red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<color key="maximumTrackTintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -3958,22 +3958,22 @@
<image name="tray.full.fill" catalog="system" width="128" height="88"/>
<image name="video.and.waveform" catalog="system" width="128" height="94"/>
<systemColor name="linkColor">
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.67450980392156867" green="0.49803921568627452" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGray3Color">
<color red="0.7803921568627451" green="0.7803921568627451" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGray5Color">
<color red="0.89803921568627454" green="0.89803921568627454" blue="0.91764705882352937" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.8980392157" green="0.8980392157" blue="0.91764705879999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemTealColor">
<color red="0.0" green="0.76470588235294112" blue="0.81568627450980391" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
+10 -10
View File
@@ -155,10 +155,10 @@
<rect key="frame" x="515" y="190" width="410" height="45"/>
<subviews>
<stackView opaque="NO" contentMode="scaleAspectFill" distribution="fillEqually" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="4he-pe-kYB">
<rect key="frame" x="0.0" y="-2.5" width="410" height="50"/>
<rect key="frame" x="0.0" y="-2.5" width="1300" height="50"/>
<subviews>
<button opaque="NO" tag="40" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="fill" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nHH-6h-4D1" userLabel="Exit">
<rect key="frame" x="0.0" y="9.5" width="50" height="31"/>
<rect key="frame" x="0.0" y="9.5" width="177" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="sBF-hd-nF8"/>
</constraints>
@@ -174,7 +174,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Pdg-l4-BvF" userLabel="Undo">
<rect key="frame" x="60" y="0.0" width="50" height="50"/>
<rect key="frame" x="187" y="0.0" width="177.5" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="7KW-Xe-OEK"/>
<constraint firstAttribute="width" constant="50" id="gHD-A0-AVS"/>
@@ -191,7 +191,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rXW-Ms-2cJ" userLabel="Load">
<rect key="frame" x="120" y="0.0" width="50" height="50"/>
<rect key="frame" x="374.5" y="0.0" width="177" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="91g-27-mVH"/>
<constraint firstAttribute="height" constant="50" id="kRj-b6-Bx1"/>
@@ -207,7 +207,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LPA-ea-YHC" userLabel="Save">
<rect key="frame" x="180" y="0.0" width="50" height="50"/>
<rect key="frame" x="561.5" y="0.0" width="177" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="Lot-pn-o60"/>
<constraint firstAttribute="height" constant="50" id="uWO-So-qxr"/>
@@ -223,7 +223,7 @@
</connections>
</button>
<button opaque="NO" tag="20" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dhG-Fo-0GK" userLabel="Trash">
<rect key="frame" x="240" y="0.0" width="50" height="50"/>
<rect key="frame" x="748.5" y="0.0" width="177" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="0vV-wV-Efz"/>
<constraint firstAttribute="width" constant="50" id="j9W-Ja-bVn"/>
@@ -239,7 +239,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Up4-28-sgF" userLabel="Add">
<rect key="frame" x="300" y="0.0" width="50" height="50"/>
<rect key="frame" x="935.5" y="0.0" width="177.5" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="rWU-US-9dl"/>
<constraint firstAttribute="width" constant="50" id="wWj-wB-MRd"/>
@@ -254,7 +254,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4pE-po-Zn1" userLabel="Edit">
<rect key="frame" x="360" y="0.0" width="50" height="50"/>
<rect key="frame" x="1123" y="0.0" width="177" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="oFn-jm-orG"/>
<constraint firstAttribute="height" constant="50" id="sls-Vh-uxz"/>
@@ -273,7 +273,7 @@
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zll-IP-PFt" userLabel="Chevron View">
<rect key="frame" x="179" y="45" width="52" height="25"/>
<rect key="frame" x="624" y="45" width="52" height="25"/>
<subviews>
<imageView clipsSubviews="YES" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ChevronCompactUp" translatesAutoresizingMaskIntoConstraints="NO" id="76O-3K-aa8">
<rect key="frame" x="0.0" y="0.0" width="52" height="25"/>
@@ -696,7 +696,7 @@
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<slider clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="16383" translatesAutoresizingMaskIntoConstraints="NO" id="w5M-fB-8rI">
<slider clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="32766" translatesAutoresizingMaskIntoConstraints="NO" id="w5M-fB-8rI">
<rect key="frame" x="200" y="0.0" width="350" height="20"/>
<color key="tintColor" red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<color key="maximumTrackTintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+1 -1
View File
@@ -125,7 +125,7 @@ import UIKit
@objc public static let stickTouchPads: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD"]
@objc public static let displacementBasedStickPads: [String] = ["LSPAD", "RSPAD"]
@objc public static let stickWheels: [String] = ["LSWHEEL", "RSWHEEL"]
@objc public static let vectorTouchPads: [String] = ["LSVPAD", "RSVPAD", "MOUSEPAD", "TRACKBALL"]
@objc public static let velocityBasedTouchPads: [String] = ["LSVPAD", "RSVPAD", "MOUSEPAD", "TRACKBALL", "LTPAD", "RTPAD", "MOUSEWHEEL", "WHEEL"]
@objc public static let inertialTouchPads: [String] = ["LSVPAD", "RSVPAD", "TRACKBALL", "LSPAD", "RSPAD"]
@objc public static let verticalTouchPads: [String] = ["LTPAD", "RTPAD", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL"]
@objc public static let bidirectionalVerticalTouchPads: [String] = ["LTPAD", "RTPAD", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL"]
+2
View File
@@ -773,11 +773,13 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
return YES;
}
/*
for(OnScreenWidgetView* widget in OnScreenWidgetView.mapping.allValues) {
if(widget.isFolder && widget.parentSequence<0 && widget.autoDockIdleDuration>0) {
[widget restartAutoDockCountdown];
}
}
*/
uint8_t type = LI_CTYPE_UNKNOWN;
uint16_t capabilities = 0;
+37 -22
View File
@@ -10,7 +10,7 @@ import UIKit
import SVGKit
import ObjectiveC.runtime
@objc class OnScreenWidgetView: UIView {
@objc class OnScreenWidgetView: UIButton {
@objc(widgetWithCmdString:buttonLabel:shape:profile:)
class func widget(cmdString: String, buttonLabel: String, shape: String, profile: OSCProfile) -> OnScreenWidgetView {
return OnScreenWidgetView(cmdString: cmdString, buttonLabel: buttonLabel, shape: shape, profile: profile)
@@ -124,7 +124,7 @@ import ObjectiveC.runtime
}
}
private func highlightBorderDuringResizing() {
if widgetType == .touchPad {
if widgetType == .touchPad || self.isMotionControlButton {
self.highlightBorder(highlighted: true, color: standardHighlightColor.cgColor)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
if !self.isBeingResized {
@@ -252,6 +252,7 @@ import ObjectiveC.runtime
@objc public var isMousePadWithButtonActions: Bool = false
@objc public var hasInertia: Bool = false
@objc public var isFunctionalButton: Bool = false
@objc public var isMotionControlButton: Bool = false
@objc public var isTapToToggleException: Bool = false
@objc public var hasHapticFeedback: Bool = false
@objc public var isDirectionPad: Bool = false
@@ -262,6 +263,7 @@ import ObjectiveC.runtime
@objc public var isFolder: Bool = false
@objc public var containsShortcutAction: Bool = false
@objc public var hasNonEditableLabel: Bool = false
@objc public var hasTemporaryLabel: Bool = false
@objc public var isMagnifier: Bool = false
@objc public var animatesTransition: Bool = true
@@ -642,10 +644,11 @@ import ObjectiveC.runtime
self.isMousePadWithButtonActions = CommandManager.mousePadWithButtonActions.contains(self.touchPadString) && widgetType == WidgetTypeEnum.touchPad
self.hasInertia = CommandManager.inertialTouchPads.contains(self.touchPadString)
self.isFunctionalButton = self.functionalButtonString != "" || self.cmdString.contains("+")
self.isMotionControlButton = !self.motionControlButtonString.isEmpty
self.isTapToToggleException = (self.functionalButtonString == "NOSINGLETOUCH"
|| self.functionalButtonString == "PENCILHOVER"
|| self.functionalButtonString == "ABSTCHDRAG"
)
)
self.hasHapticFeedback = !self.comboButtonStrings.isEmpty || CommandManager.directionPads.contains(self.touchPadString)
self.isDirectionPad = self.widgetType == WidgetTypeEnum.touchPad && CommandManager.directionPads.contains(self.touchPadString)
self.hasWalkSprintKeys = self.isDirectionPad && (self.touchPadString == "WASDPAD"
@@ -658,13 +661,16 @@ import ObjectiveC.runtime
self.hasL3R3Indicator = !self.isStickWheel && !self.isDirectionPad && self.widgetType == WidgetTypeEnum.touchPad
/*
self.hasTrackPoint = (CommandManager.vectorTouchPads.contains(self.touchPadString)
|| self.isStickWheel
|| (self.widgetType == WidgetTypeEnum.button
&& (buttonMode == .slideAndHold || buttonMode == .slideToToggle)))*/
self.hasTrackPoint = (CommandManager.vectorTouchPads.contains(self.touchPadString)
|| self.isStickWheel
|| (self.widgetType == WidgetTypeEnum.button
&& (buttonMode == .slideAndHold || buttonMode == .slideToToggle)))*/
self.hasTrackPoint = true
self.hasNonEditableLabel = (self.cmdString == "DISABLETOUCH"
|| self.cmdString == "GAMEPADOVERLAY")
self.hasTemporaryLabel = CommandManager.velocityBasedTouchPads.contains(self.touchPadString) && (self.isMotionControlButton || self.buttonString == "NULL")
|| self.cmdString == "RSVPAD"
|| self.cmdString == "LSVPAD"
self.mouseButtonActionDelay = self.cmdString.contains("ABSMOUSEPAD") ? 0.005 : 0
@@ -1031,7 +1037,7 @@ import ObjectiveC.runtime
@objc func setupAtrributedText(){
var text = self.widgetLabel.contains("#") ? "\(self.widgetLabel.split(separator: "#").first ?? "")" : LocalizationHelper.localizedString(forKey: self.widgetLabel)
if !OnScreenWidgetView.editMode, self.widgetType == .touchPad {
if !OnScreenWidgetView.editMode, self.widgetType == .touchPad, !self.hasTemporaryLabel {
text = ""
}
@@ -1121,7 +1127,7 @@ import ObjectiveC.runtime
if CommandManager.stickWheels.contains(self.touchPadString) {label.isHidden = true}
}
else{
label.isHidden = self.widgetLabel.uppercased() == self.touchPadString // allow touchPad label to be display if it's different from touchPad cmdString
label.isHidden = !self.hasTemporaryLabel
}
}
@@ -2053,7 +2059,8 @@ import ObjectiveC.runtime
self.directionPadTouchBegan = true
self.firstTouchMoved = false
self.tickFlag = 0
super.touchesBegan(touches, with: event)
// super.touchesBegan(touches, with: event)
if OnScreenWidgetView.editMode {self.parentViewController?.touchesBegan(touches, with: event)}
self.isMultipleTouchEnabled = self.widgetType == WidgetTypeEnum.button
|| CommandManager.mousePadWithButtonActions.contains(self.touchPadString)
@@ -2096,6 +2103,8 @@ import ObjectiveC.runtime
}
if !OnScreenWidgetView.editMode {
if self.hasTemporaryLabel, !self.label.isHidden {self.label.isHidden = true}
if self.widgetType == WidgetTypeEnum.touchPad && touches.count == 1{ // don't use event?.allTouches?.count here, it will counts all touches including the ones captured by other UIViews
switch self.touchPadString {
case "LSWHEEL","RSWHEEL":
@@ -2453,7 +2462,8 @@ import ObjectiveC.runtime
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
// super.touchesMoved(touches, with: event)
if OnScreenWidgetView.editMode {self.parentViewController?.touchesMoved(touches, with: event)}
if !OnScreenWidgetView.editMode {
@@ -2831,7 +2841,7 @@ import ObjectiveC.runtime
switch self.functionalButtonString {
case "FOLDER":
if self.buttonMode != .slideAndHold {break}
GenericUtils.handleSlideAndHoldFolderButtonTip(in: self.parentViewController)
// GenericUtils.handleSlideAndHoldFolderButtonTip(in: self.parentViewController)
self.folded = false
OnScreenWidgetView.set(folded: false, for: self)
case "ABSTCHDRAG":
@@ -3001,7 +3011,8 @@ import ObjectiveC.runtime
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.touchBegan = false
super.touchesEnded(touches, with: event)
// super.touchesEnded(touches, with: event)
if OnScreenWidgetView.editMode {self.parentViewController?.touchesEnded(touches, with: event)}
CATransaction.begin()
CATransaction.setDisableActions(true)
@@ -3754,8 +3765,9 @@ import ObjectiveC.runtime
}
DispatchQueue.main.async {
widget.isUserInteractionEnabled = false
if ((folder.buttonMode != .slideAndHold && widget.widgetType == .touchPad)
|| abs(widget.backgroundAlpha) < 0.1){
if (widget.widgetType == .touchPad
|| abs(widget.backgroundAlpha) < 0.1
|| widget.hasTemporaryLabel){
widget.highlightBorder(highlighted: OnScreenWidgetView.enableFolderAnimation && folder.animatesTransition, color: OnScreenWidgetView.enableFolderAnimation ? UIColor.systemBlue.cgColor : UIColor.clear.cgColor)
}
let duration = (OnScreenWidgetView.enableFolderAnimation && folder.animatesTransition)
@@ -3767,8 +3779,9 @@ import ObjectiveC.runtime
widget.isUserInteractionEnabled = !folded
widget.center = folder.folded ? folder.storedCenter : widget.storedCenter
widget.isHidden = folder.folded
if ((folder.buttonMode != .slideAndHold && widget.widgetType == .touchPad)
|| abs(widget.backgroundAlpha) < 0.1){
if (widget.widgetType == .touchPad
|| abs(widget.backgroundAlpha) < 0.1
|| widget.hasTemporaryLabel){
widget.highlightBorder(highlighted: false)
}
})
@@ -3783,8 +3796,9 @@ import ObjectiveC.runtime
widget.capturedTouches.removeAllObjects()
widget.center = folder.storedCenter
widget.isHidden = false
if ((folder.buttonMode != .slideAndHold && widget.widgetType == .touchPad)
|| abs(widget.backgroundAlpha) < 0.1){
if (widget.widgetType == .touchPad
|| abs(widget.backgroundAlpha) < 0.1
|| widget.hasTemporaryLabel){
widget.highlightBorder(highlighted: OnScreenWidgetView.enableFolderAnimation && folder.animatesTransition, color: OnScreenWidgetView.enableFolderAnimation ? UIColor.systemBlue.cgColor : UIColor.clear.cgColor)
}
UIView.animate(withDuration: (OnScreenWidgetView.enableFolderAnimation && folder.animatesTransition)
@@ -3797,9 +3811,10 @@ import ObjectiveC.runtime
widget.isUserInteractionEnabled = !folder.folded
widget.center = folder.folded ? folder.storedCenter : widget.storedCenter
widget.isHidden = folder.folded
if ((folder.buttonMode != .slideAndHold && widget.widgetType == .touchPad)
|| abs(widget.backgroundAlpha) < 0.1){
DispatchQueue.main.asyncAfter(deadline: .now() + (widget.widgetType == .touchPad ? 0.15 : 0)) {
if (widget.widgetType == .touchPad
|| abs(widget.backgroundAlpha) < 0.1
|| widget.hasTemporaryLabel){
DispatchQueue.main.asyncAfter(deadline: .now() + ((widget.widgetType == .touchPad || widget.hasTemporaryLabel) && folder.animatesTransition ? 0.15 : 0)) {
widget.highlightBorder(highlighted: false)
}
}
+9 -1
View File
@@ -784,7 +784,10 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
if(widgetView.isFolder && widgetView.parentSequence<0 && widgetView.autoDockIdleDuration>0) {
[widgetView setAutoDockWithEnabled:true];
if(ControllerUtil.activeGCControllers.count > 0) [widgetView restartAutoDockCountdown];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
if(!AlertControllerUtil.isCountingDown) [widgetView restartAutoDockCountdown];
});
}
if(sequenceGenerated){
@@ -804,6 +807,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
OnScreenWidgetView.deepestButton = nil;
UIView* deepestButton = [OnScreenWidgetView getDeepestButton];
NSMutableSet* motionControlButtons = [NSMutableSet new];
if(deepestButton){
for (UIView *subview in self->_streamFrameTopLayerView.subviews) {
if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
@@ -811,8 +815,12 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
if(widget.widgetType == WidgetTypeEnumTouchPad){
[self->_streamFrameTopLayerView insertSubview:subview belowSubview:deepestButton];
}
if(widget.isMotionControlButton) [motionControlButtons addObject:widget];
}
}
for(OnScreenWidgetView* button in motionControlButtons) {
[self->_streamFrameTopLayerView insertSubview:button belowSubview:deepestButton];
}
}
}
+135 -19
View File
@@ -1510,7 +1510,7 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gyro+RStick"
"value" : "Gyro+RightStick"
}
},
"zh-Hans" : {
@@ -1521,13 +1521,13 @@
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "陀螺儀+右搖桿"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "陀螺儀+右搖桿"
}
}
@@ -6454,7 +6454,7 @@
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "一块啥都不干的挡板区域"
}
},
@@ -7400,25 +7400,25 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n1. By default, The widget menu button will be automatically docked to bottom edge, then become almost transparent after staying idle for 10 seconds. \nThis timeout can be changed by entering “Edit” in the widget menu.\n\n2. From %@ edge, slide %d%% screen width to open settings menu\n\n3. From %@ edge, slide %d%% screen width to open toolbox menu\n\n4. Slide from top 40%% of screen edge to avoid sending touch events to PC side\n\nIf the screen shows large green or purple color artifacts, disable variable display refresh rate on the PC and set the display refresh rate to match the streaming frame rate."
"value" : "\n1. By default, The widget menu button will be automatically docked to bottom edge, then become almost transparent after staying idle for 2 seconds. \nThis timeout can be changed by entering “Edit” in the widget menu.\n\n2. From %@ edge, slide %d%% screen width to open settings menu\n\n3. From %@ edge, slide %d%% screen width to open toolbox menu\n\n4. Slide from top 40%% of screen edge to avoid sending touch events to PC side\n\nIf the screen shows large green or purple color artifacts, disable variable display refresh rate (G-Sync, Free-Sync) on the PC and set the display refresh rate to match the streaming frame rate."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n1. 默认状态下,控件菜单按键在闲置3秒后将自动吸附屏幕【右下方边缘】,并进入高透明状态。\n可展开控件菜单,进入“修改布局”修改该延迟。\n\n2. 展开设置菜单: 从%@边缘滑动%d%%屏幕宽度\n\n3. 展开工具箱菜单: 从%@边缘滑动%d%%屏幕宽度\n\n4. 从40%%上半边缘滑动避免触控事件影响PC端\n\n若画面出现大片发绿、发紫的颜色异常,请在主机端关闭可变显示刷新率,并将显示刷新率设定为与串流帧率一致。"
"value" : "\n1. 默认状态下,控件菜单按键在闲置2秒后将自动吸附屏幕【右下方边缘】,并进入高透明状态。\n可展开控件菜单,进入“修改布局”修改该延迟。\n\n2. 展开设置菜单: 从%@边缘滑动%d%%屏幕宽度\n\n3. 展开工具箱菜单: 从%@边缘滑动%d%%屏幕宽度\n\n4. 从40%%上半边缘滑动避免触控事件影响PC端\n\n若画面出现大片发绿、发紫的颜色异常,请在主机端关闭【可变显示刷新率(G-Sync, Free-Sync)】,并将显示刷新率设定为与串流帧率一致。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n1. 預設狀態下,控件選單按鍵在閒置3秒後將自動吸附至螢幕【右下方邊緣】,並進入高透明狀態。\n可展開控件選單,進入「修改佈局」修改該延遲。\n\n2. 展開設定選單: 從%@邊緣滑動%d%%螢幕寬度\n\n3. 展開工具箱選單: 從%@邊緣滑動%d%%螢幕寬度\n\n4. 從40%%上半邊緣滑動避免觸控事件影響PC端\n\n若畫面出現大片發綠、發紫等色彩異常,請在主機端關閉可變顯示更新率,並將顯示更新率設定為與串流幀率一致。"
"value" : "\n1. 預設狀態下,控件選單按鍵在閒置2秒後將自動吸附至螢幕【右下方邊緣】,並進入高透明狀態。\n可展開控件選單,進入「修改佈局」修改該延遲。\n\n2. 展開設定選單: 從%@邊緣滑動%d%%螢幕寬度\n\n3. 展開工具箱選單: 從%@邊緣滑動%d%%螢幕寬度\n\n4. 從40%%上半邊緣滑動避免觸控事件影響PC端\n\n若畫面出現大片發綠、發紫等色彩異常,請在主機端關閉「可變顯示更新率(G-Sync, Free-Sync)」,並將顯示更新率設定為與串流幀率一致。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n1. 預設狀態下,控件選單按鍵在閒置3秒後將自動吸附至螢幕【右下方邊緣】,並進入高透明狀態。\n可展開控件選單,進入「修改佈局」修改該延遲。\n\n2. 展開設定選單: 從%@邊緣滑動%d%%螢幕寬度\n\n3. 展開工具箱選單: 從%@邊緣滑動%d%%螢幕寬度\n\n4. 從40%%上半邊緣滑動避免觸控事件影響PC端\n\n若畫面出現大片發綠、發紫等色彩異常,請在主機端關閉可變顯示更新率,並將顯示更新率設定為與串流幀率一致。"
"value" : "\n1. 預設狀態下,控件選單按鍵在閒置3秒後將自動吸附至螢幕【右下方邊緣】,並進入高透明狀態。\n可展開控件選單,進入「修改佈局」修改該延遲。\n\n2. 展開設定選單: 從%@邊緣滑動%d%%螢幕寬度\n\n3. 展開工具箱選單: 從%@邊緣滑動%d%%螢幕寬度\n\n4. 從40%%上半邊緣滑動避免觸控事件影響PC端\n\n若畫面出現大片發綠、發紫等色彩異常,請在主機端關閉「可變顯示更新率(G-Sync, Free-Sync)」,並將顯示更新率設定為與串流幀率一致。"
}
}
}
@@ -7556,25 +7556,25 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "\nDrag other widgets (buttons or touchpads). Release when the touch point enters the folder’s bounding frame to complete collecting.\n\n- When the folder is unfolded, the collected widget will snap back to its original position.\n\n- When the folder is folded, the collected widget will be hidden.\n\n- Drag a sub-widget or a folder over the trash icon (do not release) to detach it from the collection."
"value" : "\nDrag other widgets (buttons or touchpads). Release when the touch point enters the folder’s bounding frame to complete collecting.\n\n- When the folder is unfolded, the collected widget will snap back to its original position. Otherwise, the collected widget will be hidden\n\n- Drag a sub-widget or a folder over the trash icon (do not release) to detach it from the collection.\n\n- The [Widgets] folder button (you just selected) can be dragged & relocated during streaming by quick double tap and keep holding-down."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "\n拖动其他控件(按键或触控板),当手指触点进入控件夹边框时松开,即可完成收纳。\n\n- 当控件夹处于展开状态时, 被收纳控件将弹回原先的位置。\n\n- 当控件夹处于折叠状态时,被收纳控件将隐藏。\n\n- 拖动子控件或控件夹划过垃圾桶图标(不要松开),即可解除收纳关系。"
"state" : "translated",
"value" : "\n拖动其他控件(按键或触控板),当手指触点进入控件夹按键边框时松开,即可完成收纳。\n\n- 当控件夹展开, 被收纳控件将弹回原先的位置,反之则隐藏。\n\n- 拖动子控件或控件夹划过垃圾桶图标(不要松开),即可解除收纳关系。\n\n- 您刚刚选择的 [控件菜单] 控件夹,在串流时也能通过快速双击并保持长按,拖动改变其位置。\n"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "\n拖動其他螢幕控制項(按鍵或觸控板),當手指觸點進入資料夾邊框時放開,即可完成收納。\n\n- 當控制項夾處於展開狀態時,被收納的控制項會彈回原本的位置。\n\n- 當控制項夾處於折疊狀態時,被收納的控制項會隱藏。\n\n- 拖動子控制項或控制項夾按键,劃過垃圾桶圖示(不要放開),即可解除收納關係。\n"
"state" : "translated",
"value" : "\n拖動其他螢幕控制項(按鍵或觸控板),當手指觸點進入控制項夾按键邊框時放開,即可完成收納。\n\n- 當控制項夾處於展開狀態時,被收納的控制項會彈回原本的位置。反之被收納的控制項會隱藏。\n\n- 拖動子控制項或控制項夾按键,劃過垃圾桶圖示(不要放開),即可解除收納關係。\n\n- 您剛剛選擇的 [控制項選單] 控制項夾,在串流時可透過快速雙擊後持續按住,拖曳變更其位置。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "\n拖動其他螢幕控制項(按鍵或觸控板),當手指觸點進入資料夾邊框時放開,即可完成收納。\n\n- 當控制項夾處於展開狀態時,被收納的控制項會彈回原本的位置。\n\n- 當控制項夾處於折疊狀態時,被收納的控制項會隱藏。\n\n- 拖動子控制項或控制項夾按键,劃過垃圾桶圖示(不要放開),即可解除收納關係。\n"
"state" : "translated",
"value" : "\n拖動其他螢幕控制項(按鍵或觸控板),當手指觸點進入控制項夾按键邊框時放開,即可完成收納。\n\n- 當控制項夾處於展開狀態時,被收納的控制項會彈回原本的位置。反之被收納的控制項會隱藏。\n\n- 拖動子控制項或控制項夾按键,劃過垃圾桶圖示(不要放開),即可解除收納關係。\n\n- 您剛剛選擇的 [控制項選單] 控制項夾,在串流時可透過快速雙擊後持續按住,拖曳變更其位置。"
}
}
}
@@ -8138,6 +8138,35 @@
}
}
},
"gamingLayoutFolderTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Best way to edit your gaming widgets for this universal template:\n\n- Edit on another profile instead of current complicated layout\n- Unfold current folder\n- Tap “clear” to remove sub-widgets\n- Tap “import” and select the edited target profile\n- Gaming widgets will be imported to current folder\n(“Widgets”, “Layouts” & “Edit layout” buttons will be filtered automatically)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "为全能型方案编辑游戏布局的最佳方法:\n\n- 当前布局层级较多, 建议从在其他配置文件中编辑游戏布局。\n- 完成后,展开当前控件夹\n- 点“清空” 移除子控件\n- 点“导入”并选择已编辑好的目标配置文件\n- 选中配置的布局将导入到当前控件夹中\n(自动过滤”控件菜单”, “切换布局”, “修改布局”按键)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "適用於全能型方案的遊戲佈局編輯最佳方式:\n\n- 目前佈局層級較多,建議先在其他配置檔中編輯遊戲佈局。\n- 完成後,展開目前的控制項夾。\n- 點擊「清空」移除所有子控制項。\n- 點擊「匯入」,並選擇已編輯完成的目標遊戲配置。\n- 所選遊戲配置中的佈局將匯入至目前的控制項夾中。\n(系統會自動過濾「控制項選單」、「切換佈局」、「修改佈局」按鍵。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "適用於全能型方案的遊戲佈局編輯最佳方式:\n\n- 目前佈局層級較多,建議先在其他配置檔中編輯遊戲佈局。\n- 完成後,展開目前的控制項夾。\n- 點擊「清空」移除所有子控制項。\n- 點擊「匯入」,並選擇已編輯完成的目標遊戲配置。\n- 所選遊戲配置中的佈局將匯入至目前的控制項夾中。\n(系統會自動過濾「控制項選單」、「切換佈局」、「修改佈局」按鍵。"
}
}
}
},
"Gestures" : {
"extractionState" : "manual",
"localizations" : {
@@ -9262,6 +9291,35 @@
}
}
},
"layoutToolTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Welcome to the world of touch control game streaming!\n\n- The “Default” layout can’t be modified, please tap the “tray / drawer” icon to duplicate it and edit the copy instead.\n\n- Please carefully read the one-time pop-up tips that appear during use. They will help you understand how to use this layout tool."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "欢迎来到触屏串流的世界!\n\n- “Default” 即默认布局无法被修改保存,请点击 [抽屉] 图标,将其复制并修改其副本。\n\n- 请仔细阅读使用过程中弹出的其他一次性提示, 这将帮助您理解如何使用布局修改工具。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "歡迎來到觸控串流的世界!\n\n- 「Default」即預設佈局,無法被修改儲存。請點選「抽屜」圖示,將其複製後再修改副本。\n\n- 請仔細閱讀使用過程中彈出的其他一次性提示,這將幫助您理解如何使用佈局修改工具。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "歡迎來到觸控串流的世界!\n\n- 「Default」即預設佈局,無法被修改儲存。請點選「抽屜」圖示,將其複製後再修改副本。\n\n- 請仔細閱讀使用過程中彈出的其他一次性提示,這將幫助您理解如何使用佈局修改工具。"
}
}
}
},
"LB/L1" : {
"extractionState" : "manual",
"localizations" : {
@@ -9717,6 +9775,35 @@
}
}
},
"Lsvpad" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Left Stick"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "左摇杆"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "左搖桿"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "左搖桿"
}
}
}
},
"LsWheel cannot be combined with other widgets" : {
"extractionState" : "manual",
"localizations" : {
@@ -13417,6 +13504,35 @@
}
}
},
"Rsvpad" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Right Stick"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "右摇杆"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "右搖桿"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "右搖桿"
}
}
}
},
"RsWheel cannot be combined with other widgets" : {
"extractionState" : "manual",
"localizations" : {
@@ -16051,25 +16167,25 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "This is a velocity based, transparent right stick touchpad (RsvPad). Please increase the in-game right stick sensitivity first, then adjust the RsvPad sensitivity itself."
"value" : "This is a velocity based, transparent right stick touchpad (RsvPad) for 3D game camera control. Please increase the in-game right stick sensitivity first, then adjust the RsvPad sensitivity itself.\n\nCheck out the tutorial to learn how to set up the best control experience."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "这是一个透明的速度矢量型右摇杆触控板(RsvPad)。请先将游戏内的右摇杆灵敏度调大,再调整RsvPad自身灵敏度。"
"value" : "这是一个用于3D 游戏视角控制、透明的速度矢量型右摇杆触控板(RsvPad)。请先将游戏内的右摇杆灵敏度调大,再调整RsvPad自身灵敏度。\n\n查看教程了解如何设置最佳操作手感。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "這是一個透明的速度向量型右搖桿觸控板(RsvPad)。請先將遊戲內的右搖桿靈敏度調高,再調整 RsvPad 自身的靈敏度。"
"value" : "这是一個用於 3D 遊戲視角控制、透明的速度向量型右搖桿觸控板(RsvPad)。請先將遊戲內的右搖桿靈敏度調高,再調整 RsvPad 自身的靈敏度。\n\n查看教學了解如何設定最佳操作手感。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "這是一個透明的速度向量型右搖桿觸控板(RsvPad)。請先將遊戲內的右搖桿靈敏度調高,再調整 RsvPad 自身的靈敏度。"
"value" : "这是一個用於 3D 遊戲視角控制、透明的速度向量型右搖桿觸控板(RsvPad)。請先將遊戲內的右搖桿靈敏度調高,再調整 RsvPad 自身的靈敏度。\n\n查看教學了解如何設定最佳操作手感。"
}
}
}
Binary file not shown.
Binary file not shown.
+50
View File
@@ -213,6 +213,56 @@ import UIKit
}
}
@objc static var hasTappedGamingLayoutFolderInEditMode: Bool = false
@objc static func isFirstTappingGamingLayoutFolderInEditMode() -> Bool {
guard !hasTappedGamingLayoutFolderInEditMode else { return false }
hasTappedGamingLayoutFolderInEditMode = true
let key = "hasTappedGamingLayoutFolderInEditMode"
let defaults = UserDefaults.standard
let launchedBefore = defaults.bool(forKey: key)
if !launchedBefore {
defaults.set(true, forKey: key)
return true
}
return false
}
@objc static func handleGamingLayoutFolderTip(in vc: UIViewController?) {
if isFirstTappingGamingLayoutFolderInEditMode() {
AlertControllerUtil.showAlert(
in: vc,
title: LocalizationHelper.localizedString(forKey: "Tips"),
message: "\n\(LocalizationHelper.localizedString(forKey: "gamingLayoutFolderTip"))",
withCancel: false,
buttonTitle: LocalizationHelper.localizedString(forKey: "Got it!"),
countdown: 5,
)
}
}
@objc static func isFirstEnteringLayoutTool() -> Bool {
let key = "hasEnteredLayoutTool1"
let defaults = UserDefaults.standard
let launchedBefore = defaults.bool(forKey: key)
if !launchedBefore {
defaults.set(true, forKey: key)
return true
}
return false
}
@objc static func handleLayoutToolTip(in vc: UIViewController?) {
if isFirstEnteringLayoutTool() {
AlertControllerUtil.showAlert(
in: vc,
title: LocalizationHelper.localizedString(forKey: "Tips"),
message: "\n\(LocalizationHelper.localizedString(forKey: "layoutToolTip"))",
withCancel: false,
buttonTitle: LocalizationHelper.localizedString(forKey: "Got it!"),
countdown: 7,
)
}
}
@objc static var hasTappedOnscreenGyroButton = false
@objc static func isFirstTappingOnscreenGyroButton() -> Bool {
guard !hasTappedOnscreenGyroButton else { return false }
@@ -307,6 +307,9 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widgetPanelStoredCenter = widgetPanelStack.center
setupWidgetPanel()
profileRefresh()
if !toolbarStackView.isHidden {
GenericUtils.handleLayoutToolTip(in: self)
}
}
override func viewDidDisappear(_ animated: Bool) {
@@ -474,12 +477,13 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
if let folder = folder {
for widget in newWidgetBatch where
widget.isFolder
&& widget.parentSequence != -1
widget.parentSequence != -1
&& widget != folder
{
widget.sequenceSet = Set(widget.sequenceSet.map {importedWidgetSequenceMap[$0] ?? -1})
if !independentWidgetSequencesPriorToImport.contains(widget.sequence) {widget.parentSequence = importedWidgetSequenceMap[widget.parentSequence] ?? -1}
if widget.isFolder {widget.sequenceSet = Set(widget.sequenceSet.map {importedWidgetSequenceMap[$0] ?? -1})}
if !independentWidgetSequencesPriorToImport.contains(widget.sequence) {
widget.parentSequence = importedWidgetSequenceMap[widget.parentSequence] ?? folder.sequence
}
// print("label: \(widget.widgetLabel) sequence: \(widget.sequence) set: \(widget.sequenceSet) parent: \(String(describing: OnScreenWidgetView.mapping[widget.parentSequence]?.widgetLabel))")
}
}
@@ -488,8 +492,8 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widget.accessWidgetAttributes()
}
OnScreenWidgetView.unfoldedExclusiveFolderSequence = oscProfile.unfoldedExclusiveFolderSequence
OnScreenWidgetView.setPostExclusiveUnfoldeds(oscProfile.postExclusiveUnfoldedSequences as NSSet)
OnScreenWidgetView.unfoldedExclusiveFolderSequence = folder == nil ? -1 : oscProfile.unfoldedExclusiveFolderSequence
if folder == nil {OnScreenWidgetView.setPostExclusiveUnfoldeds(oscProfile.postExclusiveUnfoldedSequences as NSSet)}
OnScreenWidgetView.restoreFoldedStates()
if hasLegacyWidget {
@@ -503,12 +507,15 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
OnScreenWidgetView.deepestButton = nil;
_ = OnScreenWidgetView.getDeepestButton()
var motionControlButtons = Set<OnScreenWidgetView>()
if let deepestButton = OnScreenWidgetView.deepestButton {
for widget in OnScreenWidgetView.mapping.values {
if widget.widgetType == .touchPad {
widget.superview?.insertSubview(widget, belowSubview: deepestButton)
self.view.insertSubview(widget, belowSubview: deepestButton)
}
if widget.isMotionControlButton {motionControlButtons.insert(widget)}
}
for button in motionControlButtons {self.view.insertSubview(button, belowSubview: deepestButton)}
}
view.bringSubviewToFront(toolbarRootView)
@@ -1083,9 +1090,13 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
}
refreshPanelForSelectedWidget(widgetView)
if (widgetView.isFolder && GenericUtils.isFirstTappingFolderInLayoutTool()) {
if widgetView.isFolder && GenericUtils.isFirstTappingFolderInLayoutTool() {
self.popFolderTutorialTip()
}
if widgetView.widgetLabel == "=virtualGamepad"
|| widgetView.widgetLabel == "=kbm" {
GenericUtils.handleGamingLayoutFolderTip(in: self)
}
}
@objc private func legacyOscLayerTapped(_ notification: Notification) {
@@ -1244,6 +1255,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
newWidget.sequence = widget.sequence
newWidget.autoDockIdleDuration = widget.autoDockIdleDuration
newWidget.autoDockSettledAlpha = widget.autoDockSettledAlpha
newWidget.folded = widget.folded
newWidget.revealMode = widget.revealMode
newWidget.bulkMoveEnabled = widget.bulkMoveEnabled
newWidget.layoutUpdateDelegate = self
@@ -1292,8 +1304,11 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
OnScreenWidgetView.set(widget: newWidget, for: newWidget.sequence)
newWidget.sizeReference = widget.sizeReference
newWidget.resizeWidgetView()
newWidget.adjustTransparency(alpha: widget.backgroundAlpha, tweakBorderAlpha: false)
newWidget.tweakLabelAlpha(alpha: widget.labelAlpha)
newWidget.adjustTransparency(alpha: widget.originalBackgroundAlpha, tweakBorderAlpha: false)
newWidget.tweakLabelAlpha(alpha: widget.originalLabelAlpha)
if widget.isFolder {newWidget.reverseColorPhase(reversed: !newWidget.folded)}
newWidget.tweakBorderAlpha(alpha: widget.borderAlpha)
newWidget.tweakHighlightAlpha(alpha: widget.highlightAlpha)
newWidget.adjustBorder(width: widget.borderWidth)
@@ -1622,7 +1637,9 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
if oscProfilesTableViewController?.loadingMode != .pickProfileData {
setupWidgetPanel()
}
else {widgetPanelStack.isHidden = false}
else {
widgetPanelStack.isHidden = false
}
case .selectProfileFromMainFrame, .selectProfileFromStreamView:
clearOnScreenWidgets()
dismiss(animated: false)
@@ -2547,7 +2564,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widgetPanelStack.isUserInteractionEnabled = true
if let selectedWidget {
view.insertSubview(selectedWidget, belowSubview: widgetPanelStack)
if selectedWidget.widgetType == .touchPad {
if selectedWidget.widgetType == .touchPad || selectedWidget.isMotionControlButton {
view.sendSubviewToBack(selectedWidget)
}
}
@@ -1309,7 +1309,7 @@ static NSMutableSet* hostList;
BOOL shouldEnableFramePacingSelector = !_settingsExpandedInStreamView && (settingsViewController.renderingBackendSelector.selectedSegmentIndex != RENDER_METAL);
[settingsViewController.framePacingModeSelector setEnabled:shouldEnableFramePacingSelector];
// [settingsViewController.frameTimebaseSwitch setEnabled:shouldEnableFramePacing];
[settingsViewController.asyncFrameDequeueSwitch setEnabled:shouldEnableFramePacingSelector && settingsViewController.framePacingModeSelector.selectedSegmentIndex == FramePacingModeQueue];
[settingsViewController.asyncFrameDequeueSwitch setEnabled:shouldEnableFramePacingSelector];
[settingsViewController setHidden:_settingsExpandedInStreamView || !(shouldEnableFramePacingSelector && settingsViewController.framePacingModeSelector.selectedSegmentIndex == FramePacingModeQueue) forStack:settingsViewController.frameQueueSizeStack];
// Disable mic switch if sunshine does not support mic redirection
@@ -2177,6 +2177,7 @@ BOOL isCustomResolution(int resolutionSelected) {
NSInteger renderingBackend = [self->tempSettings.renderingBackend integerValue];
[self.renderingBackendSelector setSelectedSegmentIndex:renderingBackend];
[self.renderingBackendSelector addTarget:self action:@selector(renderingBackendChanged:) forControlEvents:UIControlEventValueChanged];
[self renderingBackendChanged:self.renderingBackendSelector]; // Update PiP and frame pacing state based on current selection
NSInteger framePacingMode = [self->tempSettings.framePacingMode integerValue];
[self.framePacingModeSelector setSelectedSegmentIndex:framePacingMode];
@@ -2187,7 +2188,6 @@ BOOL isCustomResolution(int resolutionSelected) {
[self.asyncFrameDequeueSwitch setOn:self->tempSettings.asyncFrameDequeue];
[self.sdrPerformanceWorkaroundSwitch setOn:self->tempSettings.sdrPerformanceWorkaround];
[self renderingBackendChanged:self.renderingBackendSelector]; // Update PiP and frame pacing state based on current selection
[self.citrixX1MouseSwitch setOn:self->tempSettings.btMouseSupport];
[self.globeAsEscapeSwitch setOn:self->tempSettings.globeAsEscape];
@@ -2566,7 +2566,6 @@ BOOL isCustomResolution(int resolutionSelected) {
// Set pacing method to Queue and disable selector
[self.framePacingModeSelector setSelectedSegmentIndex:FramePacingModeQueue];
[self.framePacingModeSelector setEnabled:NO];
[self setHidden:true forStack:self.asyncFrameDequeueStack];
} else {
// Balanced mode (AVSB renderer) - enable PiP toggle if iOS 15+
if (@available(iOS 15.0, *)) {
@@ -2576,7 +2575,6 @@ BOOL isCustomResolution(int resolutionSelected) {
[self.pipSwitch setEnabled:NO];
}
[self.framePacingModeSelector setEnabled:YES];
[self setHidden:false forStack:self.asyncFrameDequeueStack];
}
// Get the current settings to compare with the new selection