Merge branch 'Integration' into stylus3

This commit is contained in:
TrueZhuanjia
2025-12-27 14:52:19 +08:00
29 changed files with 1210 additions and 144 deletions
+38 -1
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 70;
objects = {
/* Begin PBXBuildFile section */
@@ -24,6 +24,9 @@
188973D32E386A670025E48C /* widgetTemplatesIPhone.bin in Resources */ = {isa = PBXBuildFile; fileRef = 188973D22E386A670025E48C /* widgetTemplatesIPhone.bin */; };
18951D1D2EBB6D2300A86E12 /* TouchPadGestureHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18951D1C2EBB6D2300A86E12 /* TouchPadGestureHandler.swift */; };
189AD29A2DE7446000E24B88 /* HostCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */; };
18A0EE252EFB9B5A00BA853A /* SVGKit in Frameworks */ = {isa = PBXBuildFile; productRef = 18A0EE242EFB9B5A00BA853A /* SVGKit */; };
18A0EE272EFB9B5A00BA853A /* SVGKitSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 18A0EE262EFB9B5A00BA853A /* SVGKitSwift */; };
18A0EE2C2EFBCCFD00BA853A /* GraphicUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A0EE2B2EFBCCFD00BA853A /* GraphicUtils.swift */; };
18A765BD2ECD51FB004784AA /* ControllerUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A765BC2ECD51FB004784AA /* ControllerUtil.swift */; };
18B317032EE67A3A009B62C2 /* InertialScroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18B317022EE67A39009B62C2 /* InertialScroller.swift */; };
18E4BCEA2E891895000A8657 /* MotionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18E4BCE92E891895000A8657 /* MotionHandler.swift */; };
@@ -168,6 +171,7 @@
180345E02E819877004AF36F /* libopus-sim.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libopus-sim.a"; sourceTree = "<group>"; };
180E6E362E93BFDB0067C73A /* AlertControllerUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertControllerUtil.swift; sourceTree = "<group>"; };
1817B61D2E6FD04D000D938D /* SafeTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafeTimer.swift; sourceTree = "<group>"; };
182042252EFEE46700309FF6 /* touchCentered.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = touchCentered.swift; sourceTree = "<group>"; };
1829CE3D2E2154DF0074A99A /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = "<group>"; };
1829CE3E2E2154DF0074A99A /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = "<group>"; };
18341A022DEB65AB0094E5F2 /* FixedTintImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FixedTintImageView.h; sourceTree = "<group>"; };
@@ -183,6 +187,7 @@
18951D1C2EBB6D2300A86E12 /* TouchPadGestureHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchPadGestureHandler.swift; sourceTree = "<group>"; };
189AD2962DE743B700E24B88 /* HostCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HostCollectionViewController.h; sourceTree = "<group>"; };
189AD2992DE7446000E24B88 /* HostCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HostCollectionViewController.m; sourceTree = "<group>"; };
18A0EE2B2EFBCCFD00BA853A /* GraphicUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicUtils.swift; sourceTree = "<group>"; };
18A765BC2ECD51FB004784AA /* ControllerUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControllerUtil.swift; sourceTree = "<group>"; };
18B317022EE67A39009B62C2 /* InertialScroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InertialScroller.swift; sourceTree = "<group>"; };
18BF141D2E0D7A00009DEE4F /* VoidLink v1.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "VoidLink v1.0.xcdatamodel"; sourceTree = "<group>"; };
@@ -403,11 +408,17 @@
FBDE86E519F82297001C18A8 /* UIAppView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppView.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
18A0EE282EFBCBFB00BA853A /* SVGs */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = SVGs; sourceTree = "<group>"; };
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
FB290CEB19B2C406004C83CF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
18A0EE272EFB9B5A00BA853A /* SVGKitSwift in Frameworks */,
18A0EE252EFB9B5A00BA853A /* SVGKit in Frameworks */,
9890CF6B203B7EE1006C4B06 /* libxml2.tbd in Frameworks */,
98CFB82F1CAD481B0048EF74 /* libmoonlight-common.a in Frameworks */,
FB8946ED19F6AFE800339C8A /* libopus.a in Frameworks */,
@@ -574,6 +585,7 @@
FB1A67542132419700507771 /* Moonlight TV */,
FB290CF019B2C406004C83CF /* Frameworks */,
FB290CEF19B2C406004C83CF /* Products */,
182042252EFEE46700309FF6 /* touchCentered.swift */,
);
sourceTree = "<group>";
};
@@ -652,6 +664,7 @@
1888C1912E24C33100108730 /* AboutViewController.swift */,
FB89463719F6473800339C8A /* Launch Screen.xib */,
FB290D0819B2C406004C83CF /* Images.xcassets */,
18A0EE282EFBCBFB00BA853A /* SVGs */,
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */,
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */,
FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */,
@@ -767,6 +780,7 @@
isa = PBXGroup;
children = (
18729EDD2E8BD68800101194 /* UUIDHelper.swift */,
18A0EE2B2EFBCCFD00BA853A /* GraphicUtils.swift */,
97E20DD42E2164A9000D5DCA /* BandwidthTracker.h */,
97E20DD52E2164A9000D5DCA /* BandwidthTracker.m */,
97E20DD62E2164A9000D5DCA /* FloatBuffer.h */,
@@ -928,6 +942,9 @@
dependencies = (
98AB2E861CAD468B0089BB98 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
18A0EE282EFBCBFB00BA853A /* SVGs */,
);
name = VoidLink;
productName = Limelight;
productReference = FB290CEE19B2C406004C83CF /* VoidLink.app */;
@@ -963,6 +980,7 @@
packageReferences = (
F74BEF9A2C1A705600224667 /* XCRemoteSwiftPackageReference "OpenSSL-Package" */,
182760F52E83E2EA00EC1C5C /* XCRemoteSwiftPackageReference "swift-collections" */,
18A0EE232EFB9B5A00BA853A /* XCRemoteSwiftPackageReference "SVGKit" */,
);
productRefGroup = FB290CEF19B2C406004C83CF /* Products */;
projectDirPath = "";
@@ -1051,6 +1069,7 @@
18A765BD2ECD51FB004784AA /* ControllerUtil.swift in Sources */,
84E1CDEC2C4F67D300547904 /* CommandManager.swift in Sources */,
847D2FDB2DDA015F00937A62 /* MenuSectionView.m in Sources */,
18A0EE2C2EFBCCFD00BA853A /* GraphicUtils.swift in Sources */,
FB53E1431BE5DC4400CD6ECE /* IdManager.m in Sources */,
189AD29A2DE7446000E24B88 /* HostCollectionViewController.m in Sources */,
9897B6A1221260EF00966419 /* VoidController.m in Sources */,
@@ -1449,6 +1468,14 @@
minimumVersion = 1.1.4;
};
};
18A0EE232EFB9B5A00BA853A /* XCRemoteSwiftPackageReference "SVGKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SVGKit/SVGKit.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 3.0.0;
};
};
F74BEF9A2C1A705600224667 /* XCRemoteSwiftPackageReference "OpenSSL-Package" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/krzyzanowskim/OpenSSL-Package.git";
@@ -1475,6 +1502,16 @@
package = 182760F52E83E2EA00EC1C5C /* XCRemoteSwiftPackageReference "swift-collections" */;
productName = Collections;
};
18A0EE242EFB9B5A00BA853A /* SVGKit */ = {
isa = XCSwiftPackageProductDependency;
package = 18A0EE232EFB9B5A00BA853A /* XCRemoteSwiftPackageReference "SVGKit" */;
productName = SVGKit;
};
18A0EE262EFB9B5A00BA853A /* SVGKitSwift */ = {
isa = XCSwiftPackageProductDependency;
package = 18A0EE232EFB9B5A00BA853A /* XCRemoteSwiftPackageReference "SVGKit" */;
productName = SVGKitSwift;
};
F74BEF9B2C1A705600224667 /* OpenSSL */ = {
isa = XCSwiftPackageProductDependency;
package = F74BEF9A2C1A705600224667 /* XCRemoteSwiftPackageReference "OpenSSL-Package" */;
@@ -1,6 +1,15 @@
{
"originHash" : "f16484589afcd51ca8598428cdd5dc0e795abe386bdc40dfb311787d3f7758a2",
"originHash" : "d1fc50a28d75017e32553df2b233f8a7e2cf1542da32728ce6722b200f745608",
"pins" : [
{
"identity" : "cocoalumberjack",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git",
"state" : {
"revision" : "a9ed4b6f9bdedce7d77046f43adfb8ce1fd54114",
"version" : "3.9.0"
}
},
{
"identity" : "openssl-package",
"kind" : "remoteSourceControl",
@@ -10,6 +19,15 @@
"version" : "3.3.2000"
}
},
{
"identity" : "svgkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SVGKit/SVGKit.git",
"state" : {
"revision" : "58152b9f7c85eab239160b36ffdfd364aa43d666",
"version" : "3.0.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
@@ -18,6 +36,15 @@
"revision" : "c1805596154bb3a265fd91b8ac0c4433b4348fb0",
"version" : "1.2.0"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log",
"state" : {
"revision" : "bc386b95f2a16ccd0150a8235e7c69eab2b866ca",
"version" : "1.8.0"
}
}
],
"version" : 3
+61 -17
View File
@@ -2401,7 +2401,7 @@
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="z5Q-bW-WQ8" userLabel="widgetPanelStack" customClass="WidgetPanelStackView">
<rect key="frame" x="325" y="156" width="650" height="776"/>
<rect key="frame" x="325" y="156" width="650" height="854"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Profile:" textAlignment="center" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iel-xl-xd9">
<rect key="frame" x="0.0" y="0.0" width="650" height="37"/>
@@ -2495,8 +2495,27 @@
</slider>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="9ZS-28-txW" userLabel="borderWidthAlphaStack">
<stackView contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="WHh-JZ-wlT">
<rect key="frame" x="0.0" y="319" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Component Size" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XMg-F0-m2y" userLabel="componentSizeLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="Wrt-If-sQd"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<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="6" minValue="0.59999999999999998" maxValue="6" translatesAutoresizingMaskIntoConstraints="NO" id="ewF-K6-Rkd">
<rect key="frame" x="165" y="0.0" width="485" 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"/>
</slider>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="9ZS-28-txW" userLabel="borderWidthAlphaStack">
<rect key="frame" x="0.0" y="358" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Pwa-YK-6Q2" userLabel="widgetAlphaLabel">
<rect key="frame" x="0.0" y="0.0" width="101" height="34"/>
@@ -2532,7 +2551,7 @@
</subviews>
</stackView>
<stackView contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="zfD-bd-GEN" userLabel="stickIndicatorOffsetStack">
<rect key="frame" x="0.0" y="358" width="650" height="34"/>
<rect key="frame" x="0.0" y="397" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stick Indicator" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tG7-oX-P9b" userLabel="stickIndicatorOffsetLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2551,7 +2570,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="80D-qe-E5D" userLabel="sensitivityFactorXStack">
<rect key="frame" x="0.0" y="397" width="650" height="34"/>
<rect key="frame" x="0.0" y="436" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SensitivityX" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vJs-pg-hHe" userLabel="sensitivityFactorLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2570,7 +2589,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CT5-Ap-Gh0" userLabel="sensitivityFactorYStack">
<rect key="frame" x="0.0" y="436" width="650" height="34"/>
<rect key="frame" x="0.0" y="475" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SensitivityY" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NZO-BM-nef" userLabel="sensitivityFactorYLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2589,7 +2608,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aPm-vW-MUe">
<rect key="frame" x="0.0" y="475" width="650" height="34"/>
<rect key="frame" x="0.0" y="514" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Slide threshold" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qx4-KQ-j2T">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2607,8 +2626,27 @@
</slider>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6eR-pT-3nu">
<rect key="frame" x="0.0" y="553" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Walkmode threshold" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wil-pj-Gru">
<rect key="frame" x="0.0" y="0.0" width="195" height="34"/>
<constraints>
<constraint firstAttribute="width" constant="195" id="Oe3-Id-p0H"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<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="32766" translatesAutoresizingMaskIntoConstraints="NO" id="inm-e3-tvz">
<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"/>
</slider>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Rsp-8X-8le">
<rect key="frame" x="0.0" y="514" width="650" height="34"/>
<rect key="frame" x="0.0" y="592" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Minimum offset" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="F1n-T2-jX6">
<rect key="frame" x="0.0" y="0.0" width="195" height="34"/>
@@ -2627,7 +2665,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2KY-v5-YJv" userLabel="yawFactorStack">
<rect key="frame" x="0.0" y="553" width="650" height="34"/>
<rect key="frame" x="0.0" y="631" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yaw factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iZc-Xt-NaK" userLabel="yawFactorLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2646,7 +2684,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JNt-eT-HCs" userLabel="pitchFactorStack">
<rect key="frame" x="0.0" y="592" width="650" height="34"/>
<rect key="frame" x="0.0" y="670" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Pitch factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fq3-ie-8by" userLabel="pitchFactorLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2665,7 +2703,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zqk-Xa-Dku">
<rect key="frame" x="0.0" y="631" width="650" height="34"/>
<rect key="frame" x="0.0" y="709" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Roll factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="x9i-JN-FSn">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2684,7 +2722,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KXB-uJ-onx" userLabel="decelerationRateStack">
<rect key="frame" x="0.0" y="670" width="650" height="34"/>
<rect key="frame" x="0.0" y="748" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="DecelerationRate" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Pbt-Tw-dnV" userLabel="decelerationRateLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -2703,7 +2741,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GMQ-EQ-Hum" userLabel="mouseDownButtonStack">
<rect key="frame" x="0.0" y="709" width="650" height="31"/>
<rect key="frame" x="0.0" y="787" width="650" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Down button" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c1r-Hf-b7t" userLabel="mouseDownButtonLabel">
<rect key="frame" x="0.0" y="0.0" width="130" height="31"/>
@@ -2730,7 +2768,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LGW-oJ-5Zf" userLabel="triggerModeStack">
<rect key="frame" x="0.0" y="745" width="650" height="31"/>
<rect key="frame" x="0.0" y="823" width="650" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Button mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qNQ-fB-jhY" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="130" height="31"/>
@@ -2792,6 +2830,9 @@
<outlet property="buttonModeStack" destination="LGW-oJ-5Zf" id="Jn6-Mu-XYp"/>
<outlet property="chevronImageView" destination="iVZ-Fd-dY7" id="403-Nj-wRx"/>
<outlet property="chevronView" destination="hKp-ds-86I" id="Og9-aT-zNH"/>
<outlet property="componentSizeLabel" destination="XMg-F0-m2y" id="pQ6-MN-dcV"/>
<outlet property="componentSizeSlider" destination="ewF-K6-Rkd" id="yVC-sP-VSe"/>
<outlet property="componentSizeStack" destination="WHh-JZ-wlT" id="6p9-Rd-Caq"/>
<outlet property="currentProfileLabel" destination="iel-xl-xd9" id="PJ0-FX-z6w"/>
<outlet property="decelerationRateLabel" destination="Pbt-Tw-dnV" id="ypq-iA-NvQ"/>
<outlet property="decelerationRateSlider" destination="nzC-NF-fkv" id="BVc-jj-GzW"/>
@@ -2830,6 +2871,9 @@
<outlet property="toolbarTopConstraintiPad" destination="Ppb-J1-lXg" id="laN-Zh-lHm"/>
<outlet property="trashCanButton" destination="qJs-n8-eV7" id="ubK-qm-Cox"/>
<outlet property="undoButton" destination="F7X-l4-cl3" id="vAI-XQ-hZw"/>
<outlet property="walkModeThresholdLabel" destination="Wil-pj-Gru" id="Sc1-oq-R0y"/>
<outlet property="walkModeThresholdSlider" destination="inm-e3-tvz" id="Qlz-15-hnm"/>
<outlet property="walkModeThresholdStack" destination="6eR-pT-3nu" id="l0o-r6-5mG"/>
<outlet property="widgetAlphaLabel" destination="Pwa-YK-6Q2" id="IPF-Es-yTr"/>
<outlet property="widgetAlphaSlider" destination="ii1-Iq-jI4" id="Rev-dn-n3F"/>
<outlet property="widgetBorderWidthLabel" destination="r8L-dl-yLZ" id="gmo-Fh-btQ"/>
@@ -2944,7 +2988,7 @@
<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.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemGroupedBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -2953,13 +2997,13 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.67450980392156867" green="0.49803921568627452" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGray3Color">
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.7803921568627451" green="0.7803921568627451" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemTealColor">
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.76470588235294112" blue="0.81568627450980391" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
+64 -14
View File
@@ -315,7 +315,7 @@
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="BVp-3O-vZ7" userLabel="widgetPanelStack" customClass="WidgetPanelStackView">
<rect key="frame" x="375" y="132" width="550" height="732"/>
<rect key="frame" x="375" y="132" width="550" height="786"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Profile:" textAlignment="center" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f46-Pt-0Pv">
<rect key="frame" x="0.0" y="0.0" width="550" height="28"/>
@@ -418,8 +418,30 @@
<constraint firstAttribute="height" constant="20" id="6UM-Pm-4Ej"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="50p-sC-ObU" userLabel="borderWidthAlphaStack">
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xNe-VP-2ix">
<rect key="frame" x="0.0" y="388" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Component size" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kcX-kR-3gl">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="0Of-Rc-ij9"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<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.60000002384185791" maxValue="6" translatesAutoresizingMaskIntoConstraints="NO" id="hTI-E5-8cp">
<rect key="frame" x="160" y="0.0" width="390" 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"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="20" id="z0b-f7-vpR"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="50p-sC-ObU" userLabel="borderWidthAlphaStack">
<rect key="frame" x="0.0" y="415" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qPQ-U2-aSg" userLabel="widgetAlphaLabel">
<rect key="frame" x="0.0" y="0.0" width="101" height="20"/>
@@ -458,7 +480,7 @@
</constraints>
</stackView>
<stackView contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Ejp-Jq-phL" userLabel="stickIndicatorOffsetStack">
<rect key="frame" x="0.0" y="415" width="550" height="20"/>
<rect key="frame" x="0.0" y="442" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stick indicator" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fcy-zp-LGa" userLabel="stickIndicatorOffsetLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -480,7 +502,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fem-TG-vr3" userLabel="sensitivityFactorXStack">
<rect key="frame" x="0.0" y="442" width="550" height="20"/>
<rect key="frame" x="0.0" y="469" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SensitivityX" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dJh-Ck-ugh" userLabel="sensitivityFactorLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -502,7 +524,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="50h-xK-Lq0" userLabel="sensitivityFactorYStack">
<rect key="frame" x="0.0" y="469" width="550" height="20"/>
<rect key="frame" x="0.0" y="496" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SensitivityY" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="R9C-JW-nkF" userLabel="sensitivityFactorYLabel">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -524,7 +546,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ioa-xW-Qno">
<rect key="frame" x="0.0" y="496" width="550" height="20"/>
<rect key="frame" x="0.0" y="523" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Slide threshold" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6mJ-6V-XcK">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -545,8 +567,30 @@
<constraint firstAttribute="height" constant="20" id="nM3-eU-QtE"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rk5-VT-6j1">
<rect key="frame" x="0.0" y="550" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Walkmode threshold" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Afv-Tt-8Fo">
<rect key="frame" x="0.0" y="0.0" width="200" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="200" id="xso-EE-A5m"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<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="32766" translatesAutoresizingMaskIntoConstraints="NO" id="TC3-lM-oGw">
<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"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="20" id="l9q-SD-fWZ"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="mZ2-SU-Aj2">
<rect key="frame" x="0.0" y="523" width="550" height="20"/>
<rect key="frame" x="0.0" y="577" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Minimum offset" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mxv-HT-xeB">
<rect key="frame" x="0.0" y="0.0" width="200" height="20"/>
@@ -568,7 +612,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XYC-Ug-Pns">
<rect key="frame" x="0.0" y="550" width="550" height="20"/>
<rect key="frame" x="0.0" y="604" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yaw factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kzC-ut-7DI">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -590,7 +634,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gkc-td-lg4">
<rect key="frame" x="0.0" y="577" width="550" height="20"/>
<rect key="frame" x="0.0" y="631" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Pitch factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dEy-ER-Mb3">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -612,7 +656,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7G4-Ms-mkR">
<rect key="frame" x="0.0" y="604" width="550" height="20"/>
<rect key="frame" x="0.0" y="658" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Roll factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BNN-vq-Pve">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -634,7 +678,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3Bf-uN-nLa">
<rect key="frame" x="0.0" y="631" width="550" height="20"/>
<rect key="frame" x="0.0" y="685" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="DecelerationRate" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="znE-Lv-uWV">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -656,7 +700,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gsG-6n-BAb" userLabel="vibrationStyleStack">
<rect key="frame" x="0.0" y="658" width="550" height="20"/>
<rect key="frame" x="0.0" y="712" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Vibration style" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u3w-Se-xzH" userLabel="sensitivityFactorLabel">
<rect key="frame" x="0.0" y="0.0" width="130" height="20"/>
@@ -687,7 +731,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lEZ-1a-89J" userLabel="mouseButtonDownStack">
<rect key="frame" x="0.0" y="685" width="550" height="20"/>
<rect key="frame" x="0.0" y="739" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Button down" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ozU-7C-qKE" userLabel="uilabel">
<rect key="frame" x="0.0" y="0.0" width="120" height="20"/>
@@ -717,7 +761,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jE7-IB-GTS" userLabel="slidableStack">
<rect key="frame" x="0.0" y="712" width="550" height="20"/>
<rect key="frame" x="0.0" y="766" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Button mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="o9I-Gt-YRd" userLabel="uilabel">
<rect key="frame" x="0.0" y="0.0" width="120" height="20"/>
@@ -779,6 +823,9 @@
<outlet property="buttonModeStack" destination="jE7-IB-GTS" id="hKb-gp-eem"/>
<outlet property="chevronImageView" destination="76O-3K-aa8" id="yGv-fM-Ohf"/>
<outlet property="chevronView" destination="Zll-IP-PFt" id="MGR-C0-h57"/>
<outlet property="componentSizeLabel" destination="kcX-kR-3gl" id="FTP-ar-6Uh"/>
<outlet property="componentSizeSlider" destination="hTI-E5-8cp" id="TSO-4T-sF3"/>
<outlet property="componentSizeStack" destination="xNe-VP-2ix" id="zBD-X1-BNH"/>
<outlet property="currentProfileLabel" destination="f46-Pt-0Pv" id="BjA-jF-t86"/>
<outlet property="decelerationRateLabel" destination="znE-Lv-uWV" id="2Ud-O4-DD8"/>
<outlet property="decelerationRateSlider" destination="MFc-8O-wdZ" id="8Sh-vO-fqQ"/>
@@ -815,6 +862,9 @@
<outlet property="undoButton" destination="Pdg-l4-BvF" id="emD-GI-v2v"/>
<outlet property="vibrationStyleSelector" destination="QRV-je-HEZ" id="cEF-HG-B4h"/>
<outlet property="vibrationStyleStack" destination="gsG-6n-BAb" id="etn-BF-xqj"/>
<outlet property="walkModeThresholdLabel" destination="Afv-Tt-8Fo" id="Jbl-aw-U8o"/>
<outlet property="walkModeThresholdSlider" destination="TC3-lM-oGw" id="47m-Mz-1Jd"/>
<outlet property="walkModeThresholdStack" destination="rk5-VT-6j1" id="pUi-mk-N7I"/>
<outlet property="widgetAlphaLabel" destination="qPQ-U2-aSg" id="Lpd-cw-orP"/>
<outlet property="widgetAlphaSlider" destination="8Dt-CC-xry" id="7xH-nT-OPm"/>
<outlet property="widgetBorderWidthLabel" destination="eiL-iX-G3Z" id="K6d-T5-dzm"/>
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "StickWheel.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,34 @@
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" fill="none" viewBox="0 0 120 120">
<g clip-path="url(#a)">
<g filter="url(#b)">
<path fill="#fff" fill-opacity="1"
d="M67.25 10.437c.099.075.215.123.338.142a50 50 0 0 1 27.233 13.54.74.74 0 0 1 .004 1.056l-.776.775a.76.76 0 0 1-1.065.004 47.405 47.405 0 0 0-65.97 0 .76.76 0 0 1-1.064-.004l-.776-.775a.74.74 0 0 1 .004-1.057A50 50 0 0 1 52.41 10.58a.76.76 0 0 0 .339-.142l6.8-5.1a.75.75 0 0 1 .9 0z"/>
</g>
<g filter="url(#c)">
<path fill="#fff" fill-opacity="1"
d="M61.955 6.804c2.487 2.295 5.657 3.663 8.96 4.402a50 50 0 0 1 23.51 12.533c.52.493.52 1.316.013 1.823a1.326 1.326 0 0 1-1.849.013 47.403 47.403 0 0 0-65.179 0 1.326 1.326 0 0 1-1.848-.013 1.27 1.27 0 0 1 .012-1.823 50 50 0 0 1 23.512-12.533c3.302-.739 6.47-2.106 8.958-4.401L60 5z"
/>
</g>
</g>
<defs>
<!-- defs stay the same -->
<filter id="b" width="82.089" height="32.983" x="18.955" y="-.813" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur result="effect1_foregroundBlur_211_1847" stdDeviation="3"/>
</filter>
<filter id="c" width="69.634" height="22.444" x="25.183" y="5" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="1.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_211_1847"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_211_1847" result="shape"/>
</filter>
<clipPath id="a">
<path fill="#fff" d="M0 0h120v120H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+2 -1
View File
@@ -118,12 +118,13 @@ import UIKit
"OSCBACK"
]
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD","LTPAD", "RTPAD", "DS4TOUCH", "MOUSEPAD", "ABSMOUSE", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL", "DPAD", "TRACKBALL", "WASDPAD", "ARROWPAD"]
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "LSWHEEL", "RSWHEEL", "LTPAD", "RTPAD", "DS4TOUCH", "MOUSEPAD", "ABSMOUSE", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL", "DPAD", "TRACKBALL", "WASDPAD", "ARROWPAD"]
@objc public static let mousePadWithButtonActions: [String] = ["MOUSEPAD", "ABSMOUSE"]
@objc public static let mousePad: [String] = ["MOUSEPAD", "ABSMOUSE", "TRACKBALL"]
@objc public static let directionPads: [String] = ["DPAD", "WASDPAD", "ARROWPAD"]
@objc public static let stickTouchPads: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD"]
@objc public static let nonVectorStickPads: [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 inertialTouchPads: [String] = ["LSVPAD", "RSVPAD", "TRACKBALL"]
@objc public static let verticalTouchPads: [String] = ["LTPAD", "RTPAD", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL"]
+3 -3
View File
@@ -1220,9 +1220,9 @@ double rc_expo(double x, double expo) {
CGFloat rightStickYRaw = gamepad.rightThumbstick.yAxis.value * self->stickMaxOffset;
CGVector leftStickOffset = [ControllerUtil compensatedWithOffsetVector:CGVectorMake(leftStickXRaw, leftStickYRaw) withMinOffset:self->_leftStickMinOffset];
CGVector rightStickOffset = [ControllerUtil compensatedWithOffsetVector:CGVectorMake(rightStickXRaw, rightStickYRaw) withMinOffset:self->_rightStickMinOffset];
CGVector leftStickOffset = [ControllerUtil compensatedWithOffsetVector:CGVectorMake(leftStickXRaw, leftStickYRaw) minOffset:self->_leftStickMinOffset circulate:false];
CGVector rightStickOffset = [ControllerUtil compensatedWithOffsetVector:CGVectorMake(rightStickXRaw, rightStickYRaw) minOffset:self->_rightStickMinOffset circulate:false];
leftStickX = self->_controllerMouseEnabledFlag ? 0 : leftStickOffset.dx;
leftStickY = self->_controllerMouseEnabledFlag ? 0 : leftStickOffset.dy;
+21 -4
View File
@@ -192,12 +192,29 @@ import GameController
}
}
@objc static func compensated(offsetVector: CGVector, withMinOffset minOffset: CGFloat) -> CGVector{
@objc static func compensated(offsetVector: CGVector, minOffset: CGFloat, circulate:Bool=false) -> CGVector{
let vectorHypot = hypot(offsetVector.dx, offsetVector.dy)
guard vectorHypot > 0 else {return CGVector(dx: 0, dy: 0)}
let targetHypot = minOffset + (stickMaxOffset-minOffset)*(vectorHypot/stickMaxOffset)
let compensatedX = targetHypot * (offsetVector.dx/vectorHypot)
let compensatedY = targetHypot * (offsetVector.dy/vectorHypot)
return CGVector(dx: compensatedX, dy: compensatedY)
var compensatedX = targetHypot * (offsetVector.dx/vectorHypot)
var compensatedY = targetHypot * (offsetVector.dy/vectorHypot)
if circulate {
return circulated(offsetVector: CGVector(dx: compensatedX, dy: compensatedY))
}
else {
compensatedX = max(min(compensatedX, stickMaxOffset),-stickMaxOffset)
compensatedY = max(min(compensatedY, stickMaxOffset),-stickMaxOffset)
return CGVector(dx: compensatedX, dy: compensatedY)
}
}
@objc static func circulated(offsetVector: CGVector) -> CGVector{
let vectorHypot = hypot(offsetVector.dx, offsetVector.dy)
guard vectorHypot > 0 else {return CGVector(dx: 0, dy: 0)}
let targetHypot = min(vectorHypot, stickMaxOffset)
let circulatedX = targetHypot*(offsetVector.dx/vectorHypot)
let circulatedY = targetHypot*(offsetVector.dy/vectorHypot)
return CGVector(dx: circulatedX, dy: circulatedY)
}
}
+14 -4
View File
@@ -390,11 +390,13 @@ static CGRect layoutViewBounds;
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:widgetView.cmdString buttonType:CustomOnScreenWidget andPosition:normalizedPosition];
buttonState.alias = widgetView.widgetLabel;
buttonState.identifier = widgetView.identifier;
buttonState.widthFactor = [self normalizeSizeWidthFactorWith:widgetView and:buttonState];
buttonState.heightFactor = [self normalizeSizeHeightFactor:widgetView and:buttonState];
buttonState.widthFactor = [self normalizeSizeWidthFactorWith:widgetView];
buttonState.heightFactor = [self normalizeSizeHeightFactorWith:widgetView];
buttonState.componentSizeFactor = [self normalizeComponentSizeFactorWith:widgetView];
buttonState.backgroundAlpha = widgetView.backgroundAlpha;
buttonState.labelAlpha = widgetView.labelAlpha;
buttonState.borderAlpha = widgetView.borderAlpha;
buttonState.highlightAlpha = widgetView.highlightAlpha;
buttonState.borderWidth = widgetView.borderWidth;
buttonState.highlightSizeFactor = widgetView.highlightSizeFactor;
buttonState.autoTapInterval = widgetView.autoTapInterval;
@@ -410,6 +412,7 @@ static CGRect layoutViewBounds;
buttonState.decelerationRateY = widgetView.decelerationRateY;
buttonState.stickIndicatorOffset = widgetView.stickIndicatorOffset;
buttonState.widgetShape = widgetView.shape;
buttonState.walkModeThreshold = widgetView.dWheelWalkModeThreshold;
buttonState.minStickOffset = widgetView.minStickOffset;
buttonState.buttonMode = widgetView.buttonMode;
@@ -430,14 +433,21 @@ static CGRect layoutViewBounds;
return referenceLen;
}
- (CGFloat)normalizeSizeWidthFactorWith:(OnScreenWidgetView* )widget and:(OnScreenButtonState* )buttonstate{
- (CGFloat)normalizeSizeWidthFactorWith:(OnScreenWidgetView* )widget{
return widget.bounds.size.width/[self getReferenceLen] * 10000;
}
- (CGFloat)normalizeSizeHeightFactor:(OnScreenWidgetView* )widget and:(OnScreenButtonState* )buttonstate{
- (CGFloat)normalizeSizeHeightFactorWith:(OnScreenWidgetView* )widget{
return widget.bounds.size.height/[self getReferenceLen] * 10000;
}
- (CGFloat)normalizeComponentSizeFactorWith:(OnScreenWidgetView* )widget{
if(widget.isStickWheel) {
return widget.denormalizedComponentSizeFactor*widget.baselineDiameter/[self getReferenceLen] * 10000;
}
return 1;
}
#pragma mark - Queries
@@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) uint8_t sizeReference;
@property (nonatomic, assign) CGFloat widthFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat heightFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat componentSizeFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat borderWidth; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat highlightSizeFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat sensitivityFactorX; // for OnScreenWidgetView
@@ -43,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) CGFloat decelerationRateX; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat decelerationRateY; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat stickIndicatorOffset; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat walkModeThreshold; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat minStickOffset; // for OnScreenWidgetView
@property NSString* widgetShape; // for OnScreenWidgetView
@@ -50,6 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) CGFloat backgroundAlpha;
@property (nonatomic, assign) CGFloat labelAlpha;
@property (nonatomic, assign) CGFloat borderAlpha;
@property (nonatomic, assign) CGFloat highlightAlpha;
@property (nonatomic, assign) uint8_t vibrationStyle;
@property (nonatomic, assign) uint8_t mouseButtonAction;
@property (nonatomic, assign) uint16_t autoTapInterval;
@@ -44,6 +44,7 @@
[encoder encodeBool:self.isHidden forKey:@"isHidden"];
[encoder encodeFloat:self.widthFactor forKey:@"widthFactor"];
[encoder encodeFloat:self.heightFactor forKey:@"heightFactor"];
[encoder encodeFloat:self.componentSizeFactor forKey:@"componentSizeFactor"];
[encoder encodeFloat:self.sensitivityFactorX forKey:@"sensitivityFactorX"];
[encoder encodeFloat:self.sensitivityFactorY forKey:@"sensitivityFactorY"];
[encoder encodeFloat:self.slideThreshold forKey:@"slideThreshold"];
@@ -57,9 +58,11 @@
[encoder encodeFloat:self.backgroundAlpha forKey:@"backgroundAlpha"];
[encoder encodeFloat:self.labelAlpha forKey:@"labelAlpha"];
[encoder encodeFloat:self.borderAlpha forKey:@"borderAlpha"];
[encoder encodeFloat:self.highlightAlpha forKey:@"highlightAlpha"];
[encoder encodeFloat:self.borderWidth forKey:@"borderWidth"];
[encoder encodeFloat:self.highlightSizeFactor forKey:@"highlightSizeFactor"];
[encoder encodeObject:self.widgetShape forKey:@"widgetShape"];
[encoder encodeFloat:self.walkModeThreshold forKey:@"walkModeThreshold"];
[encoder encodeFloat:self.minStickOffset forKey:@"minStickOffset"];
}
@@ -78,6 +81,7 @@
self.isHidden = [decoder decodeBoolForKey:@"isHidden"];
self.widthFactor = [decoder decodeFloatForKey:@"widthFactor"];
self.heightFactor = [decoder decodeFloatForKey:@"heightFactor"];
self.componentSizeFactor = [decoder containsValueForKey:@"componentSizeFactor"] ? [decoder decodeFloatForKey:@"componentSizeFactor"] : 1.0;
self.sensitivityFactorX = [decoder containsValueForKey:@"sensitivityFactorX"] ? [decoder decodeFloatForKey:@"sensitivityFactorX"] : 1.0;
self.sensitivityFactorY = [decoder containsValueForKey:@"sensitivityFactorY"] ? [decoder decodeFloatForKey:@"sensitivityFactorY"] : 1.0;
self.slideThreshold = [decoder containsValueForKey:@"slideThreshold"] ? [decoder decodeFloatForKey:@"slideThreshold"] : 6.0;
@@ -91,9 +95,11 @@
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"] : 0.19;
self.highlightAlpha = [decoder containsValueForKey:@"highlightAlpha"] ? [decoder decodeFloatForKey:@"highlightAlpha"] : 0.77;
self.borderWidth = [decoder decodeFloatForKey:@"borderWidth"];
self.highlightSizeFactor = [decoder containsValueForKey:@"highlightSizeFactor"] ? [decoder decodeFloatForKey:@"highlightSizeFactor"] : 1.0;
self.widgetShape = [decoder decodeObjectForKey:@"widgetShape"];
self.walkModeThreshold = [decoder containsValueForKey:@"walkModeThreshold"] ? [decoder decodeFloatForKey:@"walkModeThreshold"] : 16383;
self.minStickOffset = [decoder decodeFloatForKey:@"minStickOffset"];
}
return self;
+2 -2
View File
@@ -311,7 +311,7 @@ import CoreMotion
pitch = rightStickTouchInputY + rightStickPhysicalInputY + gyroToStickOffset.dy
pitch = self.clampStickInput(input: pitch)
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: yaw, dy: pitch), withMinOffset: gyroToStickMinOffset)
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: yaw, dy: pitch), minOffset: gyroToStickMinOffset)
self.onScreenControls.sendRightStickTouchPadEvent(offsetVector.dx, offsetVector.dy)
}
@@ -322,7 +322,7 @@ import CoreMotion
let mixedLeftStickOffsetX = self.clampStickInput(input: rollIntegral+leftStickTouchInputX+leftStickPhysicalInputX)
let mixedLeftStickOffsetY = self.clampStickInput(input: leftStickTouchInputY+leftStickPhysicalInputY)
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: mixedLeftStickOffsetX, dy: mixedLeftStickOffsetY), withMinOffset: gyroToStickMinOffset)
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: mixedLeftStickOffsetX, dy: mixedLeftStickOffsetY), minOffset: gyroToStickMinOffset)
self.onScreenControls.sendLeftStickTouchPadEvent(offsetVector.dx, offsetVector.dy)
}
+3
View File
@@ -111,6 +111,9 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) {
+ (NSMutableSet* )touchesCapturedByOnScreenControls;
+ (OnScreenControls* )shared;
+ (void)setShared:(OnScreenControls*)instance;
- (void) sendRightStickTouchPadEvent:(CGFloat) stickX : (CGFloat) stickY;
- (void) clearRightStickTouchPadFlag;
- (void) sendLeftStickTouchPadEvent:(CGFloat) stickX : (CGFloat) stickY;
+10 -1
View File
@@ -24,6 +24,7 @@
(y) ? (buttonFlags | (x)) : (buttonFlags & ~(x)))
static NSMutableSet* touchesCapturedByOnScreenControls;
static OnScreenControls* sharedInstance;
static CGRect standardRoundButtonBounds;
static CGRect standardRectangleButtonBounds;
static CGRect standardStickBounds;
@@ -151,6 +152,14 @@ static float L3_Y;
return touchesCapturedByOnScreenControls;
}
+ (OnScreenControls* )shared{
return sharedInstance;
}
+ (void)setShared:(OnScreenControls*) instance{
sharedInstance = instance;
}
- (void) sendRightStickTouchPadEvent:(CGFloat) stickX : (CGFloat) stickY{
[_controllerSupport updateRightStick:_controller x: stickX y: stickY]; // stick value populated to the controllerSupport here
[_controllerSupport updateFinished:_controller];
@@ -317,7 +326,7 @@ static float L3_Y;
_activeCustomOscButtonPositionDict = [[NSMutableDictionary alloc] init];
touchesCapturedByOnScreenControls = [[NSMutableSet alloc] init];
return self;
}
+382 -75
View File
@@ -7,6 +7,7 @@
//
import UIKit
import SVGKit
@objc class OnScreenWidgetView: UIView, OscInstanceReceiverDelegate {
// receiving the OnScreenControls instance from delegate
@@ -71,18 +72,28 @@ import UIKit
@objc public var logicallyDown: Bool = false
@objc public var widthFactor: CGFloat = 1.0
@objc public var heightFactor: CGFloat = 1.0
@objc public var componentSizeFactor: CGFloat = 2.88
@objc public var buttonMode: Int = 0
@objc private var tapToToggleFlag: Bool = true
@objc public var sizeReference: Int = WidgetSizeReference.longSide.rawValue
@objc public var deNormalizedWidthFactor: CGFloat = 1.0
@objc public var deNormalizedHeightFactor: CGFloat = 1.0
@objc public var baselineDiameter:CGFloat = 0
private var baselineWidth:CGFloat = 0
private var baselineHeight:CGFloat = 0
private var baselineWidthLargeSquare:CGFloat = 0
private var baselineHeightLargeSquare:CGFloat = 0
@objc public var denormalizedWidthFactor: CGFloat = 1.0
@objc public var denormalizedHeightFactor: CGFloat = 1.0
@objc public var denormalizedComponentSizeFactor: CGFloat = 1.0
@objc public var borderWidth: CGFloat = 0.0
@objc public var backgroundAlpha: CGFloat = 0.5
@objc public var componentAlpha: CGFloat = 1
@objc public var labelAlpha: CGFloat = 0.82
@objc public var borderAlpha: CGFloat = 0.19
@objc public var borderAlpha: CGFloat = 0.1
@objc public var highlightAlpha: CGFloat = 0.77
@objc public var vibrationStyle: Int = 6
@objc public var latestTouchLocation: CGPoint
@objc public var selfViewOnTheRight: Bool = false
@@ -110,6 +121,7 @@ import UIKit
// for all touchPad or buttons hybrid with touchPads
@objc public var hasMinStickOffset: Bool = false
@objc public var hasStickIndicator: Bool = false
@objc public var hasComponent: Bool = false
@objc public var hasSensitivityX: Bool = false
@objc public var sensitivityXMin: CGFloat = 0
@objc public var sensitivityXMax: CGFloat = 8
@@ -136,10 +148,13 @@ import UIKit
@objc public var hasHapticFeedback: Bool = false
@objc public var isDirectionPad: Bool = false
@objc public var hasL3R3Indicator: Bool = false
@objc public var isStickWheel: Bool = false
// for all stick pads
@objc public var minStickOffset: CGFloat = 0
public let stickMaxOffset: CGFloat = 0x7FFE
public var stickOffsetVector: CGVector = CGVector(dx: 0, dy: 0)
// for LSVPAD, RSVPAD
@@ -153,6 +168,7 @@ import UIKit
// for LSPAD, RSPAD
@objc public var offSetX: CGFloat
@objc public var offSetY: CGFloat
private var touchCenteredOffset: Bool = false
private let crossMarkColor: CGColor = UIColor(white: 1, alpha: 0.70).cgColor
private let stickBallColor: CGColor = UIColor(white: 1, alpha: 0.75).cgColor
private var stickInputScale: CGFloat = 35
@@ -160,6 +176,12 @@ import UIKit
private let stickBallMaxOffset = 18.0
@objc public var crossMarkLayer = CAShapeLayer()
// LSWHEEL/RSWHEEL
@objc public var stickWheelLayer = CALayer()
@objc public var stickWheelLayerSmall = CALayer()
@objc public var stickWheelAxis = CALayer()
@objc public var dWheelWalkModeThreshold: CGFloat
// this is for all stick pads and mouse Pad
@objc public var sensitivityFactorX: CGFloat = 1.0
@objc public var sensitivityFactorY: CGFloat = 1.0
@@ -198,7 +220,7 @@ import UIKit
private var previousButtonMask = Direction.initialStatus.rawValue
// OnScreenControls instance
private var onScreenControls: OnScreenControls
@objc public var onScreenControls: OnScreenControls
// key / button label
private let label: UILabel
@@ -243,7 +265,7 @@ import UIKit
@objc public let buttonDownVisualEffectLayer = CAShapeLayer()
@objc public var buttonDownVisualEffectStandardWidth: CGFloat
@objc public var highlightSizeFactor: CGFloat = 1.0
@objc static public var isTweakingHighlightSize: Bool = false
@objc static public var isTweakingHighlight: Bool = false
// discreteWheels
private var tickCycle: UInt8 = UIScreen.main.maximumFramesPerSecond > 110 ? 20 : 10
@@ -282,9 +304,9 @@ import UIKit
self.motionControlButtonString = Set(self.comboButtonStrings).intersection(Set(CommandManager.motionControlButtonCmds)).first ?? ""
switch self.cmdString {
case "LSPAD", "LSVPAD":
case "LSPAD", "LSVPAD", "LSWHEEL":
self.comboButtonStrings = ["OSCL3"]
case "RSPAD", "RSVPAD":
case "RSPAD", "RSVPAD", "RSWHEEL":
self.comboButtonStrings = ["OSCR3"]
case "DS4TOUCH":
self.comboButtonStrings = ["DS4TCHBTN"]
@@ -339,6 +361,7 @@ import UIKit
self.oscProfile = oscProfileMan.getSelectedProfile()
self.tempSettings = dataMan.getSettings()
self.inertialScroller = InertialScroller()
dWheelWalkModeThreshold = stickMaxOffset*0.5
super.init(frame: .zero)
// helps widget panel to hide/show stacks
@@ -358,7 +381,26 @@ import UIKit
}
}
self.tweakBorderAlpha(alpha: 0.19) // fix default borderAlpha offset
if self.widgetType == WidgetTypeEnum.touchPad {
if self.isStickWheel {
self.widthFactor = 2
self.heightFactor = 2.6
self.backgroundAlpha = 1
self.componentAlpha = self.backgroundAlpha
self.borderAlpha = 0.05
self.sensitivityFactorX = 0.42
self.sensitivityFactorY = 0.42
self.componentSizeFactor = 2.8
}
if self.isDirectionPad {
self.widthFactor = 2
self.heightFactor = 2
self.sensitivityFactorX = 0
self.sensitivityFactorY = 0
}
}
self.tweakBorderAlpha(alpha: self.borderAlpha) // fix default borderAlpha offset
setupView()
@@ -369,10 +411,11 @@ import UIKit
}
@objc public func accessWidgetAttributes(){
self.hasMinStickOffset = CommandManager.stickTouchPads.contains(self.touchPadString)
self.hasMinStickOffset = (CommandManager.stickTouchPads.contains(self.touchPadString)
|| CommandManager.stickWheels.contains(self.touchPadString))
self.hasStickIndicator = CommandManager.nonVectorStickPads.contains(self.touchPadString) && widgetType == WidgetTypeEnum.touchPad
self.hasSensitivityX = CommandManager.touchPadCmds.contains(self.touchPadString) && !CommandManager.verticalTouchPads.contains(self.touchPadString)
self.hasSensitivityY = CommandManager.touchPadCmds.contains(self.touchPadString)
self.hasSensitivityY = CommandManager.touchPadCmds.contains(self.touchPadString) && !CommandManager.stickWheels.contains(self.touchPadString)
self.hasSlideThreshold = CommandManager.mousePad.contains(self.touchPadString)
if CommandManager.bidirectionalVerticalTouchPads.contains(self.touchPadString){
@@ -395,7 +438,10 @@ import UIKit
self.isFuncationalButton = self.functionalButtonString != ""
self.hasHapticFeedback = !self.comboButtonStrings.isEmpty || CommandManager.directionPads.contains(self.touchPadString)
self.isDirectionPad = self.widgetType == WidgetTypeEnum.touchPad && CommandManager.directionPads.contains(self.touchPadString)
self.hasL3R3Indicator = !self.isDirectionPad && self.widgetType == WidgetTypeEnum.touchPad
self.isStickWheel = self.widgetType == WidgetTypeEnum.touchPad && CommandManager.stickWheels.contains(self.touchPadString)
self.hasComponent = self.isStickWheel
self.hasL3R3Indicator = !self.isStickWheel && !self.isDirectionPad && self.widgetType == WidgetTypeEnum.touchPad
}
// ======================================================================================================
@@ -462,8 +508,20 @@ import UIKit
}
@objc public func adjustTransparency(alpha: CGFloat, tweakBorderAlpha:Bool){
CATransaction.begin()
CATransaction.setDisableActions(true)
self.backgroundAlpha = alpha
self.tweakAlpha(tweakBorderAlpha: tweakBorderAlpha)
if self.hasComponent {
self.componentAlpha = self.backgroundAlpha
self.tweakAlpha(tweakBorderAlpha: false)
if self.isStickWheel {self.setupStickWheelLayers()}
}
else{
self.tweakAlpha(tweakBorderAlpha: tweakBorderAlpha)
}
CATransaction.commit()
}
@objc public func adjustBorder(width: CGFloat){
@@ -475,7 +533,8 @@ import UIKit
@objc public func resizeWidgetView(){
guard let superview = superview else { return }
CATransaction.begin()
CATransaction.setDisableActions(true)
// Deactivate existing constraints if necessary
NSLayoutConstraint.deactivate(self.constraints)
@@ -502,27 +561,50 @@ import UIKit
// Re-setup widgetView style
setupView()
CATransaction.commit()
}
@objc public func resizeComponent(){
CATransaction.begin()
CATransaction.setDisableActions(true)
if widgetType == WidgetTypeEnum.touchPad, CommandManager.stickWheels.contains(touchPadString) {
setupStickWheelLayers()
}
CATransaction.commit()
}
@objc public func tweakLabelAlpha(alpha:CGFloat){
labelAlpha = alpha
label.textColor = UIColor(white: 1.0, alpha: labelAlpha)
// label.textColor = UIColor(white: 1.0, alpha: labelAlpha)
self.setupAtrributedText()
}
@objc public func tweakBorderAlpha(alpha:CGFloat){
borderAlpha = alpha
defaultBorderColor = UIColor(white: 0.2, alpha: borderAlpha).cgColor
defaultBorderColor = UIColor(white: borderAlpha>0 ? 0.1 : 0.9, alpha: abs(borderAlpha)).cgColor
self.layer.borderColor = defaultBorderColor
}
@objc public func tweakHighlightAlpha(alpha:CGFloat){
highlightAlpha = alpha
self.buttonDownVisualEffectLayer.borderColor = UIColor(red: 0.5, green: 0.5, blue: 1.0, alpha: highlightAlpha).cgColor
self.l3r3Indicator.borderColor = self.buttonDownVisualEffectLayer.borderColor
self.lrudIndicatorBall.borderColor = self.buttonDownVisualEffectLayer.borderColor
self.upIndicator.borderColor = self.buttonDownVisualEffectLayer.borderColor
self.downIndicator.borderColor = self.buttonDownVisualEffectLayer.borderColor
self.leftIndicator.borderColor = self.buttonDownVisualEffectLayer.borderColor
self.rightIndicator.borderColor = self.buttonDownVisualEffectLayer.borderColor
}
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
let realBackgroundAlpha = abs(self.backgroundAlpha) - 0.18 // offset to be consistent with legacy onScreen controller layer opacity
self.backgroundColor = UIColor(white:self.backgroundAlpha>0 ? 0.1 : 0.9, alpha: realBackgroundAlpha) // offset to be consistent with legacy onScreen controller layer opacity
if tweakBorderAlpha {
borderAlpha = realBackgroundAlpha * 1.01
defaultBorderColor = UIColor(white: 0.2, alpha: borderAlpha).cgColor
defaultBorderColor = UIColor(white: self.backgroundAlpha>0 ? 0.1 : 0.9, alpha: abs(borderAlpha)).cgColor
self.layer.borderColor = defaultBorderColor
}
@@ -555,45 +637,79 @@ import UIKit
// print("referenceLen \(referenceLen), \(CACurrentMediaTime())")
return nearestEven(sizeFactor/10000*referenceLen);
}
private func changeAndActivateContraints(){
let isNormalizedSizeFactor = self.widthFactor > 6;
let isNormalizedHeightFactor = self.heightFactor > 6;
private func getBaselineLenths(){
let longSideLen = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
let shortSideLen = min(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
let baselineDiameter:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 60 : 60*shortSideLen/longSideLen
print("baselineDiameter \(baselineDiameter), \(CACurrentMediaTime())")
baselineDiameter = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 60 : 60*shortSideLen/longSideLen
let baselineWidth:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 70 : 70*shortSideLen/longSideLen
let baselineHeight:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 65 : 65*shortSideLen/longSideLen
let baselineWidthLargeSquare:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 170 : 170*shortSideLen/longSideLen
let baselineHeightLargeSquare:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 150 : 150*shortSideLen/longSideLen
baselineWidth = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 70 : 70*shortSideLen/longSideLen
baselineHeight = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 65 : 65*shortSideLen/longSideLen
baselineWidthLargeSquare = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 170 : 170*shortSideLen/longSideLen
baselineHeightLargeSquare = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 150 : 150*shortSideLen/longSideLen
}
private func getDiameter(lengthFactor:CGFloat) -> CGFloat {
self.getBaselineLenths()
let isNormalizedSizeFactor = lengthFactor > 6;
return isNormalizedSizeFactor ? denormalizeSize(sizeFactor:lengthFactor) : CGFloat(Int(baselineDiameter * lengthFactor / 2) * 2)
}
private func getRecSize(widthFactor:CGFloat, heightFactor:CGFloat) -> CGSize {
let isNormalizedSizeFactor = widthFactor > 6;
let isNormalizedHeightFactor = heightFactor > 6;
self.getBaselineLenths()
let width = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:widthFactor) : CGFloat(Int(baselineWidth * widthFactor / 2) * 2)
let height = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:heightFactor) : CGFloat(Int(baselineHeight * heightFactor / 2) * 2)
return CGSize(width:width, height: height)
}
private func getLargeRecSize(widthFactor:CGFloat, heightFactor:CGFloat) -> CGSize {
let isNormalizedSizeFactor = self.widthFactor > 6;
let isNormalizedHeightFactor = self.heightFactor > 6;
self.getBaselineLenths()
let width = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineWidthLargeSquare * self.widthFactor / 2) * 2)
let height = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(baselineHeightLargeSquare * self.heightFactor / 2) * 2)
return CGSize(width:width, height: height)
}
private func changeAndActivateContraints(){
if self.shape == "round"{ // we'll make custom osc buttons round & smaller
let diameter = getDiameter(lengthFactor: self.widthFactor)
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineDiameter * self.widthFactor / 2) * 2)),
self.heightAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineDiameter * self.widthFactor / 2) * 2)),])
self.widthAnchor.constraint(equalToConstant: diameter),
self.heightAnchor.constraint(equalToConstant: diameter),])
// 实时调整大小时isNormalized 为 false。加载数据时 isNormalized 为 true
// baselineDiameter 仅在 实时调整大小时生效,从存储恢复时总是会恢复denormalizeSize()尺寸
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineDiameter : self.widthFactor;
self.deNormalizedHeightFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineDiameter : self.widthFactor;
self.denormalizedWidthFactor = diameter/baselineDiameter;
self.denormalizedHeightFactor = diameter/baselineDiameter;
//此处的 deNormalized 用于slider显示值
}
if self.shape == "square" {
let widgetSize = getRecSize(widthFactor: self.widthFactor, heightFactor: self.heightFactor)
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineWidth * self.widthFactor / 2) * 2)),
self.heightAnchor.constraint(equalToConstant: isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(baselineHeight * self.heightFactor / 2) * 2)),])
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineWidth : self.widthFactor;
self.deNormalizedHeightFactor = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor)/baselineHeight : self.heightFactor;
self.widthAnchor.constraint(equalToConstant: widgetSize.width),
self.heightAnchor.constraint(equalToConstant: widgetSize.height),])
self.denormalizedWidthFactor = widgetSize.width/baselineWidth;
self.denormalizedHeightFactor = widgetSize.height/baselineHeight;
}
if self.shape == "largeSquare" { // override all shape strings
let widgetSize = getLargeRecSize(widthFactor: self.widthFactor, heightFactor: self.heightFactor)
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant:isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineWidthLargeSquare * self.widthFactor / 2) * 2)),
self.heightAnchor.constraint(equalToConstant:isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(baselineHeightLargeSquare * self.heightFactor / 2) * 2)),])
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineWidthLargeSquare : self.widthFactor;
self.deNormalizedHeightFactor = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor)/150 : self.heightFactor;
self.widthAnchor.constraint(equalToConstant:widgetSize.width),
self.heightAnchor.constraint(equalToConstant:widgetSize.height),])
self.denormalizedWidthFactor = widgetSize.width/baselineWidthLargeSquare;
self.denormalizedHeightFactor = widgetSize.height/baselineHeightLargeSquare;
}
NSLayoutConstraint.activate([
@@ -612,17 +728,55 @@ import UIKit
self.layer.cornerRadius = shortSideLen/2 < 16 ? shortSideLen/3.2 : 16
}
func containsNonLatin(_ text: String) -> Bool {
for scalar in text.unicodeScalars {
if !(0x0000...0x024F).contains(scalar.value) {
return true
}
}
return false
}
private func setupAtrributedText(){
let text = self.widgetLabel
let attr = NSAttributedString(
string: text,
attributes: [
.foregroundColor: UIColor(white:labelAlpha>0 ? 1.0 : 0, alpha: abs(labelAlpha)), // 填充色
.strokeColor: (labelAlpha>0 ? UIColor.black : UIColor.white).withAlphaComponent(abs(labelAlpha)*0.43), // 描边色
.strokeWidth: containsNonLatin(text) ? -1 : -4 // 负值 = 同时填充
]
)
label.attributedText = attr
}
private func setupView() {
label.text = self.widgetLabel
label.font = UIFont.boldSystemFont(ofSize: 19)
// label.text = self.widgetLabel
// label.font = UIFont.boldSystemFont(ofSize: 19)
// label.font = UIFont.systemFont(ofSize: 19, weight: .medium, design: .rounded)
let baseFont = UIFont.boldSystemFont(ofSize: self.shape == "round" ? 22 : 19)
if #available(iOS 13.0, *) {
if let desc = baseFont.fontDescriptor.withDesign(.rounded) {
label.font = UIFont(descriptor: desc, size: 0)
} else {
label.font = baseFont
}
} else {
label.font = baseFont
}
label.translatesAutoresizingMaskIntoConstraints = false
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.1 // Adjust the scale factor as needed
label.textColor = UIColor(white: 1.0, alpha: labelAlpha)
label.textAlignment = .center
label.shadowColor = .black
label.shadowOffset = CGSize(width: 1, height: 1)
// label.textColor = UIColor(white: 1.0, alpha: labelAlpha)
// label.shadowColor = .black
// label.shadowOffset = CGSize(width: 0, height: 0)
self.setupAtrributedText()
label.translatesAutoresizingMaskIntoConstraints = false // enable auto alignment for the label
self.translatesAutoresizingMaskIntoConstraints = true // this is mandatory to prevent unexpected key view location change
@@ -646,7 +800,8 @@ import UIKit
if(self.borderWidth < 1) {self.layer.borderWidth = 1}
else {self.layer.borderWidth = self.borderWidth}
if OnScreenWidgetView.editMode { //display label in edit mode to make the pad more visible
label.text = self.widgetLabel
// label.text = self.widgetLabel
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
@@ -662,7 +817,6 @@ import UIKit
self.layer.cornerRadius = self.frame.width/2
// self.layer.borderWidth = self.borderWidth
label.minimumScaleFactor = 0.15 // Adjust the scale factor for oscButtons
label.font = UIFont.boldSystemFont(ofSize: 22)
}
if self.shape == "square" || self.shape == "largeSquare" {
//just do nothing here
@@ -689,6 +843,9 @@ import UIKit
if self.crossMarkLayer.superlayer == nil {self.crossMarkLayer = createCrossMark()}
if self.lrudIndicatorBall.superlayer == nil {self.lrudIndicatorBall = createStickBall()}
}
if self.isStickWheel {
self.setupStickWheelLayers()
}
}
@objc public func setupL3R3Indicator() {
@@ -712,7 +869,7 @@ import UIKit
l3r3Indicator.path = path.cgPath
l3r3Indicator.borderColor = voidlinkPurple
self.l3r3Indicator.position = CGPointMake(self.bounds.width/2, self.bounds.height/2)
if !OnScreenWidgetView.isTweakingHighlightSize {l3r3Indicator.isHidden = true}
if !OnScreenWidgetView.isTweakingHighlight {l3r3Indicator.isHidden = true}
if l3r3Indicator.superlayer == nil {
self.layer.addSublayer(l3r3Indicator)
@@ -906,7 +1063,97 @@ import UIKit
}
//================================================================================================
/// stickWheel
private func
setupStickWheelLayers(){
let diameter = self.getDiameter(lengthFactor: self.componentSizeFactor)
self.denormalizedComponentSizeFactor = diameter/baselineDiameter
// let tintColor = UIColor(red: 0.5, green: 0.5, blue: 1.0, alpha: 1)
let tintColor = UIColor(
red: 0x48 / 255.0,
green: 0xF5 / 255.0,
blue: 0xFF / 255.0,
alpha: componentAlpha
)
let axisdiameter = self.getDiameter(lengthFactor: 0.5)
let axisSize = CGSize(width: axisdiameter, height: axisdiameter)
self.stickWheelAxis = GraphicUtils.makeCenteredSVGLayer(from: "StickWheelAxis.svg", in: self.layer, targetSize: axisSize)
self.stickWheelAxis.removeFromSuperlayer()
self.layer.insertSublayer(self.stickWheelAxis, at: 0)
// GraphicUtils.changeColor(layer: self.stickWheelAxis, color: .white.withAlphaComponent(1))
self.stickWheelAxis.isHidden = false
self.stickWheelLayer = GraphicUtils.makeCenteredSVGLayer(from: "StickWheel.svg", in: self.layer, targetSize: CGSize(width: diameter, height: diameter))
self.stickWheelLayer.removeFromSuperlayer()
self.layer.insertSublayer(self.stickWheelLayer, at: 0)
GraphicUtils.changeColor(layer: self.stickWheelLayer, color: tintColor)
self.stickWheelLayer.setAffineTransform(.identity)
self.stickWheelLayer.isHidden = !OnScreenWidgetView.editMode
let smallWheelSize = CGSize(width: diameter*0.56766, height: diameter*0.56766)
self.stickWheelLayerSmall = GraphicUtils.makeCenteredSVGLayer(from: "StickWheelSmall.svg", in: self.layer, targetSize: smallWheelSize)
self.stickWheelLayerSmall.removeFromSuperlayer()
self.layer.insertSublayer(self.stickWheelLayerSmall, below: stickWheelLayer)
GraphicUtils.changeColor(layer: self.stickWheelLayerSmall, color: tintColor)
self.stickWheelLayerSmall.setAffineTransform(.identity)
self.stickWheelLayerSmall.isHidden = !OnScreenWidgetView.editMode
}
private func setHiddenForStickWheelLayer(hidden:Bool){
CATransaction.begin()
CATransaction.setDisableActions(true)
self.stickWheelLayer.isHidden = hidden;
self.stickWheelLayerSmall.isHidden = hidden;
CATransaction.commit()
}
private func handleStickWheelMove(touch:UITouch){
CATransaction.begin()
CATransaction.setDisableActions(true)
let isInWalkMode = hypot(stickOffsetVector.dx, stickOffsetVector.dy) < dWheelWalkModeThreshold
let angle = atan2(offSetY, offSetX) + .pi/2
let transform = CGAffineTransform(rotationAngle: angle)
if isInWalkMode {
self.stickWheelLayerSmall.setAffineTransform(transform)
}
else {
self.stickWheelLayer.setAffineTransform(transform)
}
if touch.phase == .began {
self.stickWheelLayer.isHidden = isInWalkMode
self.stickWheelLayerSmall.isHidden = !isInWalkMode
}
else if self.stickWheelLayer.isHidden != isInWalkMode {
self.stickWheelLayer.isHidden = isInWalkMode
self.stickWheelLayerSmall.isHidden = !isInWalkMode
}
CATransaction.commit()
switch self.touchPadString {
case "LSWHEEL":
DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
self.sendLeftStickTouchPadEvent(weightedTouchX: self.offSetX * self.sensitivityFactorX, weightedTouchY: self.offSetY * self.sensitivityFactorY, circulate: true)
}
case "RSWHEEL":
DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
self.sendRightStickTouchPadEvent(weightedTouchX: self.offSetX * self.sensitivityFactorX, weightedTouchY: self.offSetY * self.sensitivityFactorY, circulate: true)
}
default:
break
}
}
//=====LRUD(left right up & down buttons) touchPad touch =========================================
@@ -941,7 +1188,7 @@ import UIKit
lrudIndicatorBall.shadowRadius = 0;
lrudIndicatorBall.shadowOpacity = 0.8
lrudIndicatorBall.name = "lrudBall"
if !OnScreenWidgetView.isTweakingHighlightSize {lrudIndicatorBall.isHidden = true}
if !OnScreenWidgetView.isTweakingHighlight {lrudIndicatorBall.isHidden = true}
// Set the fill color (inside of the circle)
lrudIndicatorBall.fillColor = stickBallColor // Light fill with some transparency
@@ -967,7 +1214,7 @@ import UIKit
private func showLrudDirectionIndicator(with indicatorLayer:CAShapeLayer){
// show the indicator based on the touchBeganLocation
indicatorLayer.position = touchBeganLocation
indicatorLayer.position = touchCenteredOffset ? touchBeganLocation : CGPoint(x: self.bounds.midX, y: self.bounds.midY)
if indicatorLayer.isHidden {
indicatorLayer.isHidden = false
@@ -984,9 +1231,13 @@ import UIKit
let radians = atan2(-offSetY,offSetX)
let degrees = radians * 180 / .pi
let nearZeroPoint = abs(offSetX) < 16/sensitivityFactorX && abs(offSetY) < 16/sensitivityFactorY
let nearZeroPoint = sensitivityFactorX == 0 || sensitivityFactorY == 0 ? false : abs(offSetX) < 16/sensitivityFactorX && abs(offSetY) < 16/sensitivityFactorY
// NSLog("deltaX: %f, detalY: %f", deltaX, deltaY)
if self.stickWheelAxis.isHidden {
self.stickWheelAxis.isHidden = false
}
var pressedButtonMask = 0;
if abs(degrees) < triggeringAngle {
@@ -1202,7 +1453,7 @@ import UIKit
if OnScreenWidgetView.buttonVisualFeedbackEnabled {
CATransaction.begin()
CATransaction.setDisableActions(true)
if !OnScreenWidgetView.isTweakingHighlightSize {buttonDownVisualEffectLayer.isHidden = true}
if !OnScreenWidgetView.isTweakingHighlight {buttonDownVisualEffectLayer.isHidden = true}
CATransaction.commit()
}
}
@@ -1225,24 +1476,35 @@ import UIKit
CATransaction.begin()
CATransaction.setDisableActions(true)
self.setupLrudBall()
// self.setupLrudBall()
setupLrudDirectionLayer(directionLayer: upIndicator)
upIndicator.anchorPoint = CGPoint(x: 0.5, y: 1)
let offset = upIndicator.borderWidth/(2*upIndicator.bounds.width)
upIndicator.anchorPoint = CGPoint(x: 0.5, y: 1-offset)
setupLrudDirectionLayer(directionLayer: downIndicator)
downIndicator.anchorPoint = CGPoint(x: 0.5, y: 0)
downIndicator.anchorPoint = CGPoint(x: 0.5, y: 0+offset)
setupLrudDirectionLayer(directionLayer: leftIndicator)
leftIndicator.anchorPoint = CGPoint(x: 1, y: 0.5)
leftIndicator.anchorPoint = CGPoint(x: 1-offset, y: 0.5)
setupLrudDirectionLayer(directionLayer: rightIndicator)
rightIndicator.anchorPoint = CGPoint(x: 0, y: 0.5)
rightIndicator.anchorPoint = CGPoint(x: 0+offset, y: 0.5)
if !OnScreenWidgetView.isTweakingHighlightSize {
if !OnScreenWidgetView.isTweakingHighlight {
leftIndicator.isHidden = true
rightIndicator.isHidden = true
upIndicator.isHidden = true
downIndicator.isHidden = true
}
if !touchCenteredOffset {
let axisdiameter = self.getDiameter(lengthFactor: 0.35)
let axisSize = CGSize(width: axisdiameter, height: axisdiameter)
self.stickWheelAxis = GraphicUtils.makeCenteredSVGLayer(from: "StickWheelAxis-0.75.svg", in: self.layer, targetSize: axisSize)
GraphicUtils.changeColor(layer: self.stickWheelAxis, color: UIColor(white: 1, alpha: 0.6))
self.stickWheelAxis.removeFromSuperlayer()
self.layer.addSublayer(self.stickWheelAxis)
self.stickWheelAxis.isHidden = false
}
CATransaction.commit()
}
@@ -1264,7 +1526,7 @@ import UIKit
CATransaction.setDisableActions(true)
self.buttonDownVisualEffectStandardWidth = 8
if self.shape == "round" {
if deNormalizedWidthFactor < 1.3 {self.buttonDownVisualEffectStandardWidth = 15.3} // wider visual effect for osc buttons
if denormalizedWidthFactor < 1.3 {self.buttonDownVisualEffectStandardWidth = 15.3} // wider visual effect for osc buttons
else {self.buttonDownVisualEffectStandardWidth = 9}
}
@@ -1287,7 +1549,7 @@ import UIKit
}
buttonDownVisualEffectLayer.position = CGPointMake(self.bounds.midX, self.bounds.midY)
if !OnScreenWidgetView.isTweakingHighlightSize {buttonDownVisualEffectLayer.isHidden = true}
if !OnScreenWidgetView.isTweakingHighlight {buttonDownVisualEffectLayer.isHidden = true}
CATransaction.commit()
}
@@ -1297,7 +1559,8 @@ import UIKit
//=========================================send on screen controller stick/trigger events
private func weightedTouchInputToStickOffset(input: CGFloat) -> CGFloat{
let target = stickMaxOffset * input / stickInputScale
return fmax(fmin(target, stickMaxOffset),-stickMaxOffset)
// return fmax(fmin(target, stickMaxOffset),-stickMaxOffset)
return target
}
private func stickOffsetToWeightedTouchInput(offset: CGFloat) -> CGFloat {
@@ -1314,7 +1577,7 @@ import UIKit
return input * (18/stickInputScale)
}
private func sendRightStickTouchPadEvent(weightedTouchX: CGFloat, weightedTouchY: CGFloat){
private func sendRightStickTouchPadEvent(weightedTouchX: CGFloat, weightedTouchY: CGFloat, circulate: Bool=false){
let targetX = self.weightedTouchInputToStickOffset(input: weightedTouchX)
let targetY = -self.weightedTouchInputToStickOffset(input: weightedTouchY)
@@ -1322,13 +1585,13 @@ import UIKit
&& oscProfile.yawPitchToRightStick)
if !mixRightStickInputToGyro || (self.motionHandler.gyroMixInputStarted() != true) {
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), withMinOffset: minStickOffset)
self.onScreenControls.sendRightStickTouchPadEvent(offsetVector.dx, offsetVector.dy)
stickOffsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), minOffset: minStickOffset, circulate: circulate)
self.onScreenControls.sendRightStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
}
self.motionHandler.mixOnScreenRightStickAndGyroInput(x: targetX, y: targetY)
}
private func sendLeftStickTouchPadEvent(weightedTouchX: CGFloat, weightedTouchY: CGFloat){
private func sendLeftStickTouchPadEvent(weightedTouchX:CGFloat, weightedTouchY:CGFloat, circulate:Bool=false){
let targetX = self.weightedTouchInputToStickOffset(input: weightedTouchX)
let targetY = -self.weightedTouchInputToStickOffset(input: weightedTouchY)
@@ -1336,8 +1599,8 @@ import UIKit
&& oscProfile.rollToLeftStick)
if !mixLeftStickInputToGyro || (self.motionHandler.gyroMixInputStarted() != true) {
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), withMinOffset: minStickOffset)
self.onScreenControls.sendLeftStickTouchPadEvent(offsetVector.dx, offsetVector.dy)
stickOffsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), minOffset: minStickOffset, circulate: circulate)
self.onScreenControls.sendLeftStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
}
self.motionHandler.mixOnScreenLeftStickAndGyroInput(x: targetX, y: targetY)
}
@@ -1448,7 +1711,10 @@ import UIKit
let touch = touches.first
// get touchBeganLocation
if OnScreenWidgetView.editMode {self.touchBeganLocation = touch!.location(in: superview)}
if OnScreenWidgetView.editMode {
self.touchBeganLocation = touch!.location(in: superview)
self.highlightBorder(highlighted: true)
}
else {
if widgetType == WidgetTypeEnum.button, self.buttonMode == ButtonMode.movable.rawValue {self.touchBeganLocation = touch!.location(in: superview)}
else {self.touchBeganLocation = touch!.location(in: self)}
@@ -1464,6 +1730,12 @@ import UIKit
if !OnScreenWidgetView.editMode {
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":
self.getVector(touch: touches.first!)
self.handleStickWheelMove(touch: touches.first!)
if quickDoubleTapDetected {
self.showl3r3Indicator()
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)}
case "LSPAD","RSPAD":
self.showStickIndicator()
if quickDoubleTapDetected {
@@ -1486,7 +1758,16 @@ import UIKit
self.showl3r3Indicator()
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)}
case "DPAD", "WASDPAD", "ARROWPAD":
if allSpawnedTouchesCount == 1 {showLrudBall(at: touchBeganLocation)}
if allSpawnedTouchesCount == 1 {
// showLrudBall(at: touchBeganLocation)
CATransaction.begin()
CATransaction.setDisableActions(true)
self.stickWheelAxis.position = touchCenteredOffset ? touchBeganLocation : CGPoint(x: self.bounds.midX, y: self.bounds.midY)
self.stickWheelAxis.isHidden = false
CATransaction.commit()
self.getVector(touch: touches.first!)
self.handleLrudTouchMove()
}
if quickDoubleTapDetected {
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)
DispatchQueue.global(qos: .userInteractive).async {
@@ -1732,8 +2013,10 @@ import UIKit
self.inertialScroller.vector = UITouchUtil.vector(of: touch, in: self)
}
self.offSetX = currentTouchLocation.x - self.touchBeganLocation.x
self.offSetY = currentTouchLocation.y - self.touchBeganLocation.y
touchCenteredOffset = (!self.isStickWheel
&& !(self.isDirectionPad && sensitivityFactorX==0 && sensitivityFactorY==0))
self.offSetX = touchCenteredOffset ? currentTouchLocation.x - self.touchBeganLocation.x : currentTouchLocation.x - self.bounds.midX
self.offSetY = touchCenteredOffset ? currentTouchLocation.y - self.touchBeganLocation.y : currentTouchLocation.y - self.bounds.midY
}
private func updateTouchLocation(touch: UITouch){
@@ -1786,6 +2069,8 @@ import UIKit
}
self.updateTouchLocation(touch: touches.first!)
break
case "LSWHEEL", "RSWHEEL":
self.handleStickWheelMove(touch: touches.first!)
case "LSPAD":
DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
@@ -2043,6 +2328,12 @@ import UIKit
// then other types of pads or buttons with touchPad function
if !OnScreenWidgetView.editMode && !self.touchPadString.isEmpty {
switch self.touchPadString{
case "LSWHEEL":
self.clearLeftStickTouchPadFlag()
self.setHiddenForStickWheelLayer(hidden: true)
case "RSWHEEL":
self.clearRightStickTouchPadFlag()
self.setHiddenForStickWheelLayer(hidden: true)
case "LSPAD":
self.clearLeftStickTouchPadFlag()
if widgetType == WidgetTypeEnum.touchPad {self.resetStickBallPositionAndHideIndicator()}
@@ -2104,16 +2395,19 @@ import UIKit
case "RTPAD":
self.onScreenControls.updateRightTrigger(0x00)
case "WASDPAD":
self.stickWheelAxis.isHidden = touchCenteredOffset
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["W"]!,Int8(KEY_ACTION_UP), 0)
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["A"]!,Int8(KEY_ACTION_UP), 0)
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["S"]!,Int8(KEY_ACTION_UP), 0)
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["D"]!,Int8(KEY_ACTION_UP), 0)
case "ARROWPAD":
self.stickWheelAxis.isHidden = touchCenteredOffset
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["LEFT_ARROW"]!,Int8(KEY_ACTION_UP), 0)
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["RIGHT_ARROW"]!,Int8(KEY_ACTION_UP), 0)
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["UP_ARROW"]!,Int8(KEY_ACTION_UP), 0)
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["DOWN_ARROW"]!,Int8(KEY_ACTION_UP), 0)
case "DPAD":
self.stickWheelAxis.isHidden = touchCenteredOffset
self.onScreenControls.releaseControllerButton(LEFT_FLAG)
self.onScreenControls.releaseControllerButton(RIGHT_FLAG)
self.onScreenControls.releaseControllerButton(UP_FLAG)
@@ -2125,7 +2419,7 @@ import UIKit
}
}
if !OnScreenWidgetView.isTweakingHighlightSize {
if !OnScreenWidgetView.isTweakingHighlight {
if CommandManager.stickTouchPads.contains(touchPadString){
self.l3r3Indicator.isHidden = true
}
@@ -2182,6 +2476,8 @@ import UIKit
// Trigger layout update
superview.layoutIfNeeded()
self.highlightBorder(highlighted: false)
setupView(); //re-setup widgetView style
if self.widgetType == WidgetTypeEnum.touchPad{
@@ -2268,6 +2564,17 @@ import UIKit
}
}
private func highlightBorder(highlighted:Bool) {
if highlighted {
self.layer.borderWidth = 2
self.layer.borderColor = voidlinkPurple
}
else {
self.layer.borderWidth = self.borderWidth
self.layer.borderColor = self.defaultBorderColor
}
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
if superview == nil {
+5 -1
View File
@@ -161,6 +161,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
// 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){
@@ -467,7 +468,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
- (void) clearOnScreenWidgets{
OnScreenWidgetView.isTweakingHighlightSize = false;
OnScreenWidgetView.isTweakingHighlight = false;
for (UIView *subview in self->streamFrameTopLayerView.subviews) {
// 检查子视图是否是特定类型的实例
if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
@@ -561,6 +562,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
widgetView.widthFactor = buttonState.widthFactor;
widgetView.heightFactor = buttonState.heightFactor;
widgetView.componentSizeFactor = buttonState.componentSizeFactor;
widgetView.borderWidth = buttonState.borderWidth;
widgetView.highlightSizeFactor = buttonState.highlightSizeFactor;
widgetView.autoTapInterval = buttonState.autoTapInterval;
@@ -576,6 +578,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
widgetView.decelerationRateY = buttonState.decelerationRateY;
widgetView.stickIndicatorOffset = buttonState.stickIndicatorOffset;
widgetView.minStickOffset = buttonState.minStickOffset;
widgetView.dWheelWalkModeThreshold = buttonState.walkModeThreshold;
widgetView.buttonMode = buttonState.buttonMode;
// Add the widgetView to the view controller's view
[self->streamFrameTopLayerView addSubview:widgetView]; // add keyboard button to the stream frame view. must add it to the target view before setting location.
@@ -589,6 +592,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
[widgetView adjustBorderWithWidth:buttonState.borderWidth];
[widgetView tweakLabelAlphaWithAlpha:buttonState.labelAlpha];
[widgetView tweakBorderAlphaWithAlpha:buttonState.borderAlpha];
[widgetView tweakHighlightAlphaWithAlpha:buttonState.highlightAlpha];
[widgetView setupAutoTapTimer];
[widgetView setupInertialScroller];
}
+93 -1
View File
@@ -1284,6 +1284,29 @@
}
}
},
"Component size: %.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"
}
}
}
},
"Connecting" : {
"extractionState" : "manual",
"localizations" : {
@@ -2967,6 +2990,29 @@
}
}
},
"Highlight 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"
}
}
}
},
"Highlight size: %.2f" : {
"extractionState" : "manual",
"localizations" : {
@@ -6010,6 +6056,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"
}
}
}
},
"SensitivityX: %.2f" : {
"extractionState" : "manual",
"localizations" : {
@@ -7240,6 +7309,29 @@
}
}
},
"Walkmode threshold: %.0f " : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "行走模式阈值: %.0f "
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "行走模式閾值: %.0f "
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "行走模式閾值: %.0f "
}
}
}
},
"waterMarkText" : {
"extractionState" : "manual",
"localizations" : {
@@ -7263,7 +7355,7 @@
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "聯絡開發者 True砖家"
}
}
+34
View File
@@ -0,0 +1,34 @@
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" fill="none" viewBox="0 0 120 120">
<g clip-path="url(#a)">
<g filter="url(#b)">
<path fill="#fff" fill-opacity="1"
d="M67.25 10.437c.099.075.215.123.338.142a50 50 0 0 1 27.233 13.54.74.74 0 0 1 .004 1.056l-.776.775a.76.76 0 0 1-1.065.004 47.405 47.405 0 0 0-65.97 0 .76.76 0 0 1-1.064-.004l-.776-.775a.74.74 0 0 1 .004-1.057A50 50 0 0 1 52.41 10.58a.76.76 0 0 0 .339-.142l6.8-5.1a.75.75 0 0 1 .9 0z"/>
</g>
<g filter="url(#c)">
<path fill="#fff" fill-opacity="1"
d="M61.955 6.804c2.487 2.295 5.657 3.663 8.96 4.402a50 50 0 0 1 23.51 12.533c.52.493.52 1.316.013 1.823a1.326 1.326 0 0 1-1.849.013 47.403 47.403 0 0 0-65.179 0 1.326 1.326 0 0 1-1.848-.013 1.27 1.27 0 0 1 .012-1.823 50 50 0 0 1 23.512-12.533c3.302-.739 6.47-2.106 8.958-4.401L60 5z"
/>
</g>
</g>
<defs>
<!-- defs stay the same -->
<filter id="b" width="82.089" height="32.983" x="18.955" y="-.813" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur result="effect1_foregroundBlur_211_1847" stdDeviation="3"/>
</filter>
<filter id="c" width="69.634" height="22.444" x="25.183" y="5" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="1.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_211_1847"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_211_1847" result="shape"/>
</filter>
<clipPath id="a">
<path fill="#fff" d="M0 0h120v120H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+14
View File
@@ -0,0 +1,14 @@
<svg width="860" height="860" viewBox="0 0 860 860" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3_30)">
<path opacity="0.15" d="M430 45.3164C642.136 45.3164 814.471 217.345 814.471 430C814.471 642.656 642.136 814.684 430 814.684C217.864 814.684 45.5294 642.656 45.5294 430C45.5294 217.345 217.864 45.3164 430 45.3164Z" stroke="white" stroke-width="90"/>
<path opacity="0.15" d="M430 122.855L508.859 213.488H351.141L430 122.855Z" fill="#D9D9D9"/>
<path opacity="0.15" d="M430 737.144L351.141 646.512H508.859L430 737.144Z" fill="#D9D9D9"/>
<path opacity="0.15" d="M738.588 430.001L647.529 508.491V351.512L738.588 430.001Z" fill="#D9D9D9"/>
<path opacity="0.15" d="M121.412 430.001L212.471 351.512V508.491L121.412 430.001Z" fill="#D9D9D9"/>
</g>
<defs>
<clipPath id="clip0_3_30">
<rect width="860" height="860" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 879 B

+14
View File
@@ -0,0 +1,14 @@
<svg width="860" height="860" viewBox="0 0 860 860" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3_30)">
<path opacity="0.75" d="M430 45.3164C642.136 45.3164 814.471 217.345 814.471 430C814.471 642.656 642.136 814.684 430 814.684C217.864 814.684 45.5294 642.656 45.5294 430C45.5294 217.345 217.864 45.3164 430 45.3164Z" stroke="white" stroke-width="90"/>
<path opacity="0.75" d="M430 122.855L508.859 213.488H351.141L430 122.855Z" fill="#D9D9D9"/>
<path opacity="0.75" d="M430 737.144L351.141 646.512H508.859L430 737.144Z" fill="#D9D9D9"/>
<path opacity="0.75" d="M738.588 430.001L647.529 508.491V351.512L738.588 430.001Z" fill="#D9D9D9"/>
<path opacity="0.75" d="M121.412 430.001L212.471 351.512V508.491L121.412 430.001Z" fill="#D9D9D9"/>
</g>
<defs>
<clipPath id="clip0_3_30">
<rect width="860" height="860" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 879 B

+14
View File
@@ -0,0 +1,14 @@
<svg width="860" height="860" viewBox="0 0 860 860" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3_30)">
<path opacity="0.25" d="M430 45.3164C642.136 45.3164 814.471 217.345 814.471 430C814.471 642.656 642.136 814.684 430 814.684C217.864 814.684 45.5294 642.656 45.5294 430C45.5294 217.345 217.864 45.3164 430 45.3164Z" stroke="white" stroke-width="90"/>
<path opacity="0.25" d="M430 122.855L508.859 213.488H351.141L430 122.855Z" fill="#D9D9D9"/>
<path opacity="0.25" d="M430 737.144L351.141 646.512H508.859L430 737.144Z" fill="#D9D9D9"/>
<path opacity="0.25" d="M738.588 430.001L647.529 508.491V351.512L738.588 430.001Z" fill="#D9D9D9"/>
<path opacity="0.25" d="M121.412 430.001L212.471 351.512V508.491L121.412 430.001Z" fill="#D9D9D9"/>
</g>
<defs>
<clipPath id="clip0_3_30">
<rect width="860" height="860" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 879 B

+34
View File
@@ -0,0 +1,34 @@
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" fill="none" viewBox="0 0 120 120">
<g clip-path="url(#a)">
<g filter="url(#b)">
<path fill="#fff" fill-opacity="1"
d="M67.25 10.437c.099.075.215.123.338.142a50 50 0 0 1 27.233 13.54.74.74 0 0 1 .004 1.056l-.776.775a.76.76 0 0 1-1.065.004 47.405 47.405 0 0 0-65.97 0 .76.76 0 0 1-1.064-.004l-.776-.775a.74.74 0 0 1 .004-1.057A50 50 0 0 1 52.41 10.58a.76.76 0 0 0 .339-.142l6.8-5.1a.75.75 0 0 1 .9 0z"/>
</g>
<g filter="url(#c)">
<path fill="#fff" fill-opacity="1"
d="M61.955 6.804c2.487 2.295 5.657 3.663 8.96 4.402a50 50 0 0 1 23.51 12.533c.52.493.52 1.316.013 1.823a1.326 1.326 0 0 1-1.849.013 47.403 47.403 0 0 0-65.179 0 1.326 1.326 0 0 1-1.848-.013 1.27 1.27 0 0 1 .012-1.823 50 50 0 0 1 23.512-12.533c3.302-.739 6.47-2.106 8.958-4.401L60 5z"
/>
</g>
</g>
<defs>
<!-- defs stay the same -->
<filter id="b" width="82.089" height="32.983" x="18.955" y="-.813" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur result="effect1_foregroundBlur_211_1847" stdDeviation="3"/>
</filter>
<filter id="c" width="69.634" height="22.444" x="25.183" y="5" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="1.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_211_1847"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_211_1847" result="shape"/>
</filter>
<clipPath id="a">
<path fill="#fff" d="M0 0h120v120H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+107
View File
@@ -0,0 +1,107 @@
//
// GraphicUtils.swift
// VoidLink
//
// Created by True砖家 on 2025/12/24.
// Copyright © 2025 True砖家@Bilibili. All rights reserved.
//
import Foundation
import SVGKit
@objc public class GraphicUtils: NSObject {
@objc public class func makeCenteredSVGLayer(
from file: String,
in container: CALayer,
targetSize: CGSize
) -> CALayer {
guard let svg = SVGKImage(named: file) else {
fatalError("Failed to load SVG \(file)")
}
return _makeCenteredSVGLayer(
from: svg,
in: container,
targetSize: targetSize
)
}
public class func makeCenteredSVGLayer(
from svg: SVGKImage,
in container: CALayer,
targetSize: CGSize
) -> CALayer {
return _makeCenteredSVGLayer(
from: svg,
in: container,
targetSize: targetSize
)
}
@objc public class func _makeCenteredSVGLayer(
from svg: SVGKImage,
in container: CALayer,
targetSize: CGSize,
getWrapperLayer: Bool = true
) -> CALayer {
let svgLayer = svg.caLayerTree!
svgLayer.transform = CATransform3DIdentity
var unionRect = CGRect.null
func accumulateBounds(_ layer: CALayer) {
unionRect = unionRect.union(layer.frame)
layer.sublayers?.forEach { accumulateBounds($0) }
}
accumulateBounds(svgLayer)
svgLayer.setAffineTransform(
CGAffineTransform(
translationX: -unionRect.origin.x,
y: -unionRect.origin.y
)
)
let wrapper = CALayer()
wrapper.bounds = CGRect(origin: .zero, size: unionRect.size)
wrapper.anchorPoint = CGPoint(x: 0.5, y: 0.5)
wrapper.position = CGPoint(
x: container.bounds.midX,
y: container.bounds.midY
)
let scale = min(
targetSize.width / unionRect.width,
targetSize.height / unionRect.height
)
wrapper.setAffineTransform(
CGAffineTransform(scaleX: scale, y: scale)
)
wrapper.addSublayer(svgLayer)
if !getWrapperLayer {
return wrapper
}
let wrappedLayer = CALayer()
wrappedLayer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
wrappedLayer.bounds = CGRect(x: 0, y: 0, width: container.bounds.size.width, height: container.bounds.size.height)
wrappedLayer.position = CGPoint(x: container.bounds.midX, y: container.bounds.midY)
wrappedLayer.insertSublayer(wrapper, at: 0)
return wrappedLayer
}
@objc public class func changeColor(layer: CALayer, color: UIColor) {
if let shape = layer as? CAShapeLayer {
shape.fillColor = color.cgColor
shape.strokeColor = color.cgColor
}
layer.sublayers?.forEach { changeColor(layer: $0, color: color) }
}
}
@@ -121,6 +121,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) IBOutlet UILabel *minStickOffsetLabel;
@property (strong, nonatomic) IBOutlet UISlider *minStickOffsetSlider;
@property (strong, nonatomic) IBOutlet UIStackView *componentSizeStack;
@property (strong, nonatomic) IBOutlet UILabel *componentSizeLabel;
@property (strong, nonatomic) IBOutlet UISlider *componentSizeSlider;
@property (strong, nonatomic) IBOutlet UIStackView *walkModeThresholdStack;
@property (strong, nonatomic) IBOutlet UILabel *walkModeThresholdLabel;
@property (strong, nonatomic) IBOutlet UISlider *walkModeThresholdSlider;
@property (weak, nonatomic) IBOutlet UIStackView *widgetPanelStack;
@@ -12,7 +12,7 @@
#import "LayoutOnScreenControlsViewController.h"
#import "OSCProfilesTableViewController.h"
#import "OnScreenButtonState.h"
//#import "OnScreenControls.h"
#import "OnScreenControls.h"
#import "OSCProfilesManager.h"
#import "LocalizationHelper.h"
#import "VoidLink-Swift.h"
@@ -25,6 +25,7 @@ typedef NS_ENUM(NSUInteger, AlphaSliderMode) {
widgetAlpha,
labelAlpha,
borderAlpha,
highlightAlpha,
AlphaSliderModeCount
};
@@ -87,7 +88,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
- (void) viewWillDisappear:(BOOL)animated{
OnScreenWidgetView.editMode = false;
OnScreenWidgetView.isTweakingHighlightSize = false;
OnScreenWidgetView.isTweakingHighlight = false;
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutCloseNotification" object:self];
}
@@ -125,7 +126,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
- (void)reloadOnScreenWidgetViews{
NSLog(@"reloadOnScreenWidgets %f", CACurrentMediaTime());
OnScreenWidgetView.isTweakingHighlightSize = false;
OnScreenWidgetView.isTweakingHighlight = false;
OnScreenWidgetView.editMode = true;
[self hideStickIndicators];
@@ -153,6 +154,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
widgetView.widthFactor = buttonState.widthFactor;
widgetView.heightFactor = buttonState.heightFactor;
widgetView.componentSizeFactor = buttonState.componentSizeFactor;
widgetView.borderWidth = buttonState.borderWidth;
widgetView.highlightSizeFactor = buttonState.highlightSizeFactor;
widgetView.autoTapInterval = buttonState.autoTapInterval;
@@ -167,6 +169,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
widgetView.decelerationRateX = buttonState.decelerationRateX;
widgetView.decelerationRateY = buttonState.decelerationRateY;
widgetView.stickIndicatorOffset = buttonState.stickIndicatorOffset;
widgetView.dWheelWalkModeThreshold = buttonState.walkModeThreshold;
widgetView.minStickOffset = buttonState.minStickOffset;
widgetView.buttonMode = buttonState.buttonMode;
// Add the widgetView to the view controller's view
@@ -178,6 +181,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha tweakBorderAlpha:NO];
[widgetView tweakLabelAlphaWithAlpha:buttonState.labelAlpha];
[widgetView tweakBorderAlphaWithAlpha:buttonState.borderAlpha];
[widgetView tweakHighlightAlphaWithAlpha:buttonState.highlightAlpha];
[widgetView adjustBorderWithWidth:buttonState.borderWidth];
[self.onScreenWidgetViews addObject:widgetView];
}
@@ -364,24 +368,50 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
- (void)switchAlphaSlider:(UITapGestureRecognizer *)sender {
if(!widgetViewSelected) return;
alphaSliderMode = (alphaSliderMode + 1) % AlphaSliderModeCount;
OnScreenWidgetView.isTweakingHighlight = alphaSliderMode == highlightAlpha || borderWidthSliderMode == hightlightSize;
[self loadWidgetAlphas];
}
- (void)setHiddenForWidgetHighlights{
selectedWidgetView.buttonDownVisualEffectLayer.hidden = !OnScreenWidgetView.isTweakingHighlight;
selectedWidgetView.l3r3Indicator.hidden = !selectedWidgetView.hasL3R3Indicator || !OnScreenWidgetView.isTweakingHighlight;
(selectedWidgetView.lrudIndicatorBall.hidden
= selectedWidgetView.upIndicator.hidden
= selectedWidgetView.downIndicator.hidden
= selectedWidgetView.leftIndicator.hidden
= selectedWidgetView.rightIndicator.hidden
= !selectedWidgetView.isDirectionPad
&& !OnScreenWidgetView.isTweakingHighlight);
}
- (void)loadWidgetAlphas{
if(self->selectedWidgetView != nil && self->widgetViewSelected){
[self setHiddenForWidgetHighlights];
switch(alphaSliderMode){
case widgetAlpha:
[self.widgetAlphaSlider setMaximumValue:1];
[self.widgetAlphaSlider setMinimumValue:-1];
[self.widgetAlphaSlider setValue: self->selectedWidgetView.backgroundAlpha];
[self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Alpha: %.2f", _widgetAlphaSlider.value]];
break;
case labelAlpha:
[self.widgetAlphaSlider setMaximumValue:1];
[self.widgetAlphaSlider setMinimumValue:-1];
[self.widgetAlphaSlider setValue: self->selectedWidgetView.labelAlpha];
[self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Label alpha: %.2f", _widgetAlphaSlider.value]];
break;
case borderAlpha:
[self.widgetAlphaSlider setMaximumValue:1];
[self.widgetAlphaSlider setMinimumValue:-1];
[self.widgetAlphaSlider setValue: self->selectedWidgetView.borderAlpha];
[self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Border alpha: %.2f", _widgetAlphaSlider.value]];
break;
case highlightAlpha:
[self.widgetAlphaSlider setMaximumValue:1];
[self.widgetAlphaSlider setMinimumValue:0];
[self.widgetAlphaSlider setValue: self->selectedWidgetView.highlightAlpha];
[self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Highlight alpha: %.2f", _widgetAlphaSlider.value]];
break;
case AlphaSliderModeCount:
default:
break;
@@ -398,18 +428,20 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
- (void)switchBorderWidthSlider:(UITapGestureRecognizer *)sender {
if(!widgetViewSelected) return;
borderWidthSliderMode = (borderWidthSliderMode + 1) % BorderWidthSliderModeCount;
OnScreenWidgetView.isTweakingHighlightSize = borderWidthSliderMode == hightlightSize;
OnScreenWidgetView.isTweakingHighlight = alphaSliderMode == highlightAlpha || borderWidthSliderMode == hightlightSize;
[self loadWidgetWidths];
}
- (void)loadWidgetWidths{
if(self->selectedWidgetView != nil && self->widgetViewSelected){
[self setHiddenForWidgetHighlights];
switch(borderWidthSliderMode){
case widgetBorderWidth:
[self.widgetBorderWidthSlider setMinimumValue:0];
[self.widgetBorderWidthSlider setMaximumValue:8];
[self.widgetBorderWidthSlider setValue:selectedWidgetView.borderWidth animated:NO];
/*
selectedWidgetView.buttonDownVisualEffectLayer.hidden = true;
selectedWidgetView.l3r3Indicator.hidden = true;
@@ -418,7 +450,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
= selectedWidgetView.downIndicator.hidden
= selectedWidgetView.leftIndicator.hidden
= selectedWidgetView.rightIndicator.hidden
= true);
= true); */
[self.widgetBorderWidthLabel setText:[LocalizationHelper localizedStringForKey:@"Border width: %.2f", _widgetBorderWidthSlider.value]];
break;
@@ -427,15 +459,17 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[self.widgetBorderWidthSlider setMinimumValue:0];
[self.widgetBorderWidthSlider setMaximumValue:2];
[self.widgetBorderWidthSlider setValue:selectedWidgetView.highlightSizeFactor animated:NO];
selectedWidgetView.buttonDownVisualEffectLayer.hidden = selectedWidgetView.widgetType != WidgetTypeEnumButton;
selectedWidgetView.l3r3Indicator.hidden = !selectedWidgetView.hasL3R3Indicator;
/*
selectedWidgetView.buttonDownVisualEffectLayer.hidden = selectedWidgetView.widgetType != WidgetTypeEnumButton && !OnScreenWidgetView.isTweakingHighlight;
selectedWidgetView.l3r3Indicator.hidden = !selectedWidgetView.hasL3R3Indicator && !OnScreenWidgetView.isTweakingHighlight;
(selectedWidgetView.lrudIndicatorBall.hidden
= selectedWidgetView.upIndicator.hidden
= selectedWidgetView.downIndicator.hidden
= selectedWidgetView.leftIndicator.hidden
= selectedWidgetView.rightIndicator.hidden
= !selectedWidgetView.isDirectionPad);
= !selectedWidgetView.isDirectionPad
&& !OnScreenWidgetView.isTweakingHighlight); */
[self.widgetBorderWidthLabel setText:[LocalizationHelper localizedStringForKey:@"Highlight size: %.2f", _widgetBorderWidthSlider.value]];
break;
@@ -493,6 +527,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
#pragma mark - UIButton Actions
- (IBAction) closeTapped:(id)sender {
[self clearSickInput];
[self dismissViewControllerAnimated:YES completion:nil];
}
@@ -736,6 +771,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
newWidget.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
newWidget.widthFactor = widget.widthFactor;
newWidget.heightFactor = widget.heightFactor;
newWidget.componentSizeFactor = widget.componentSizeFactor;
newWidget.borderWidth = widget.borderWidth;
newWidget.highlightSizeFactor = widget.highlightSizeFactor;
newWidget.autoTapInterval = widget.autoTapInterval;
@@ -748,6 +784,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
newWidget.decelerationRateX = widget.decelerationRateX;
newWidget.decelerationRateY = widget.decelerationRateY;
newWidget.stickIndicatorOffset = widget.stickIndicatorOffset;
newWidget.dWheelWalkModeThreshold = widget.dWheelWalkModeThreshold;
newWidget.minStickOffset = widget.minStickOffset;
[newWidget setVibrationWithStyle:widget.vibrationStyle];
newWidget.mouseButtonAction = widget.mouseButtonAction;
@@ -768,6 +805,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[newWidget adjustTransparencyWithAlpha:widget.backgroundAlpha tweakBorderAlpha:NO];
[newWidget tweakLabelAlphaWithAlpha:widget.labelAlpha];
[newWidget tweakBorderAlphaWithAlpha:widget.borderAlpha];
[newWidget tweakHighlightAlphaWithAlpha:widget.highlightAlpha];
[newWidget adjustBorderWithWidth:widget.borderWidth];
[self.onScreenWidgetViews addObject:newWidget];
self->selectedWidgetView = newWidget;
@@ -796,6 +834,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
/* show pop up notification that lets users choose to save the current OSC layout configuration as a profile they can load when they want. User can also choose to cancel out of this pop up */
- (IBAction) saveTapped:(id)sender {
[self clearSickInput];
[OSCProfilesManager setLayoutViewBounds:self.view.bounds];
if([self->profilesManager updateSelectedProfile:self.layoutOSC.OSCButtonLayers]){
@@ -859,6 +898,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[self hideStickIndicators];
[self clearSickInput];
// receive the selected widgetView obj passed from the notification
[self enableCommonWidgetTools];
@@ -893,7 +933,9 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[self.sensitivityXSlider setMinimumValue:selectedWidgetView.sensitivityXMin];
[self.sensitivityXSlider setMaximumValue:selectedWidgetView.sensitivityXMax];
[self.sensitivityXSlider setValue:self->selectedWidgetView.sensitivityFactorX];
[self.sensitivityXLabel setText:[LocalizationHelper localizedStringForKey:@"SensitivityX: %.2f", self->selectedWidgetView.sensitivityFactorX]];
[self.sensitivityXLabel setText:[LocalizationHelper localizedStringForKey:
selectedWidgetView.hasSensitivityY ? @"SensitivityX: %.2f" : @"Sensitivity: %.2f",
self->selectedWidgetView.sensitivityFactorX]];
[self autoFitLabel:self.sensitivityXLabel];
}
@@ -913,6 +955,13 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[self autoFitLabel:self.minStickOffsetLabel];
}
self.walkModeThresholdStack.hidden = !selectedWidgetView.isStickWheel;
if(selectedWidgetView.isStickWheel){
[self.walkModeThresholdSlider setValue:self->selectedWidgetView.dWheelWalkModeThreshold];
[self.walkModeThresholdLabel setText:[LocalizationHelper localizedStringForKey:@"Walkmode threshold: %.0f ", self->selectedWidgetView.dWheelWalkModeThreshold]];
[self autoFitLabel:self.walkModeThresholdLabel];
}
self.slideThresholdStack.hidden = !selectedWidgetView.hasSlideThreshold;
if(selectedWidgetView.hasSlideThreshold){
[self.slideThresholdSlider setMinimumValue:selectedWidgetView.slideThresholdMin];
@@ -964,21 +1013,24 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[self->selectedWidgetView updateStickIndicator];*/
}
[self.widgetSizeSlider setValue: self->selectedWidgetView.deNormalizedWidthFactor];
[self.widgetSizeSlider setValue: self->selectedWidgetView.denormalizedWidthFactor];
[self autoFitLabel:self.widgetSizeLabel];
[self.widgetSizeLabel setText:[LocalizationHelper localizedStringForKey:@"Size: %.2f", self->selectedWidgetView.deNormalizedWidthFactor]];
[self.widgetSizeLabel setText:[LocalizationHelper localizedStringForKey:@"Size: %.2f", self->selectedWidgetView.denormalizedWidthFactor]];
[self.widgetHeightSlider setValue: self->selectedWidgetView.deNormalizedHeightFactor];
[self.widgetHeightSlider setValue: self->selectedWidgetView.denormalizedHeightFactor];
[self autoFitLabel:self.widgetHeightLabel];
[self.widgetHeightLabel setText:[LocalizationHelper localizedStringForKey:@"Height: %.2f", self->selectedWidgetView.deNormalizedHeightFactor]];
[self.widgetHeightLabel setText:[LocalizationHelper localizedStringForKey:@"Height: %.2f", self->selectedWidgetView.denormalizedHeightFactor]];
self.componentSizeStack.hidden = !self->selectedWidgetView.hasComponent;
[self.componentSizeSlider setValue: self->selectedWidgetView.denormalizedComponentSizeFactor];
[self autoFitLabel:self.componentSizeLabel];
[self.componentSizeLabel setText:[LocalizationHelper localizedStringForKey:@"Component size: %.2f ", self->selectedWidgetView.denormalizedComponentSizeFactor]];
[self loadWidgetAlphas];
[self autoFitLabel:self.widgetAlphaLabel];
// [self.widgetBorderWidthSlider setValue:self->selectedWidgetView.borderWidth];
[self loadWidgetWidths];
[self autoFitLabel:self.widgetBorderWidthLabel];
// [self widgetBorderWidthSliderMoved:self.widgetBorderWidthSlider];
self.autoTapStack.hidden = !selectedWidgetView.hasAutoTap;
// [self.autoTapSlider setValue:self->selectedWidgetView.autoTapInterval];
@@ -1085,7 +1137,20 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
}
}
- (void)componentSizeSliderMoved:(UISlider* )sender{
[self.componentSizeLabel setText:[LocalizationHelper localizedStringForKey:@"Component size: %.2f ", sender.value]];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
self->selectedWidgetView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
self->selectedWidgetView.componentSizeFactor = sender.value;
[self->selectedWidgetView resizeWidgetView];
}
}
- (void)widgetAlphaSliderMoved:(UISlider* )sender{
[CATransaction begin];
[CATransaction setDisableActions:YES];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
switch(alphaSliderMode){
case widgetAlpha:
@@ -1097,6 +1162,9 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
case borderAlpha:
[self->selectedWidgetView tweakBorderAlphaWithAlpha:sender.value];
break;
case highlightAlpha:
[self->selectedWidgetView tweakHighlightAlphaWithAlpha:sender.value];
break;
case AlphaSliderModeCount:
default:
break;
@@ -1107,6 +1175,8 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
if(self->selectedControllerLayer != nil && self->controllerLayerSelected){
[self.layoutOSC adjustControllerLayerOpacityWith:self->selectedControllerLayer and:sender.value];
}
[CATransaction commit];
}
- (void)widgetBorderWidthSliderMoved:(UISlider* )sender{
@@ -1171,7 +1241,9 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
}
- (void)sensitivityXSliderMoved:(UISlider* )sender{
[self.sensitivityXLabel setText:[LocalizationHelper localizedStringForKey:@"SensitivityX: %.2f", sender.value]];
[self.sensitivityXLabel setText:[LocalizationHelper localizedStringForKey:
selectedWidgetView.hasSensitivityY ? @"SensitivityX: %.2f" : @"Sensitivity: %.2f",
sender.value]];
[self.sensitivityYLabel setText:[LocalizationHelper localizedStringForKey:@"SensitivityY: %.2f", sender.value]];
[self.sensitivityYSlider setValue:sender.value];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
@@ -1187,9 +1259,41 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
return;
}
- (void)walkModeThresholdSliderMoved:(UISlider* )sender{
[self.walkModeThresholdLabel setText:[LocalizationHelper localizedStringForKey:@"Walkmode threshold: %.0f ", sender.value]];
if(self->selectedWidgetView != nil && self->widgetViewSelected){ self->selectedWidgetView.dWheelWalkModeThreshold = sender.value;
if(!OnScreenControls.shared) return;
if([selectedWidgetView.touchPadString isEqualToString:@"LSWHEEL"]) [OnScreenControls.shared sendLeftStickTouchPadEvent:0 :sender.value];
if([selectedWidgetView.touchPadString isEqualToString:@"RSWHEEL"]) [OnScreenControls.shared sendRightStickTouchPadEvent:0 :sender.value];
}
return;
}
- (void)clearSickInput{
if(self->selectedWidgetView != nil && self->widgetViewSelected){
[OnScreenControls.shared clearLeftStickTouchPadFlag];
[OnScreenControls.shared clearRightStickTouchPadFlag];
}
}
- (void)minStickOffsetSliderMoved:(UISlider* )sender{
[self.minStickOffsetLabel setText:[LocalizationHelper localizedStringForKey:@"Minimum offset: %.0f", sender.value]];
if(self->selectedWidgetView != nil && self->widgetViewSelected) self->selectedWidgetView.minStickOffset = sender.value;
if(self->selectedWidgetView != nil && self->widgetViewSelected){
self->selectedWidgetView.minStickOffset = sender.value;
if(!OnScreenControls.shared) return;
if([selectedWidgetView.touchPadString isEqualToString:@"LSPAD"]
|| [selectedWidgetView.touchPadString isEqualToString:@"LSVPAD"]
|| [selectedWidgetView.touchPadString isEqualToString:@"LSWHEEL"]
){
[OnScreenControls.shared sendLeftStickTouchPadEvent:sender.value :0];
}
if([selectedWidgetView.touchPadString isEqualToString:@"RSPAD"]
|| [selectedWidgetView.touchPadString isEqualToString:@"RSVPAD"]
|| [selectedWidgetView.touchPadString isEqualToString:@"RSWHEEL"]
){
[OnScreenControls.shared sendRightStickTouchPadEvent:sender.value :0];
}
}
return;
}
@@ -1335,6 +1439,10 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[self.widgetHeightSlider addTarget:self action:@selector(widgetHeightSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.widgetHeightLabel.text = [LocalizationHelper localizedStringForKey:@"Height"];
self.widgetHeightStack.hidden = YES;
[self.componentSizeSlider addTarget:self action:@selector(componentSizeSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.componentSizeLabel.text = [LocalizationHelper localizedStringForKey:@"Component size"];
self.componentSizeStack.hidden = YES;
alphaSliderMode = widgetAlpha;
[self.widgetAlphaSlider addTarget:self action:@selector(widgetAlphaSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
@@ -1370,10 +1478,14 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
self.sensitivityYLabel.text = [LocalizationHelper localizedStringForKey:@"SensitivityY"];
self.sensitivityYStack.hidden = YES;
[self.walkModeThresholdSlider addTarget:self action:@selector(walkModeThresholdSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.walkModeThresholdLabel.text = [LocalizationHelper localizedStringForKey:@"Walkmode threshold"];
self.walkModeThresholdStack.hidden = YES;
[self.minStickOffsetSlider addTarget:self action:@selector(minStickOffsetSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.minStickOffsetLabel.text = [LocalizationHelper localizedStringForKey:@"Minimum offset"];
self.minStickOffsetStack.hidden = YES;
[self.slideThresholdSlider addTarget:self action:@selector(slideThresholdSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.slideThresholdLabel.text = [LocalizationHelper localizedStringForKey:@"Slide threshold"];
self.slideThresholdStack.hidden = YES;
@@ -1678,7 +1790,11 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
// UITouch *touch = [touches anyObject]; // Get the first touch in the set
_widgetPanelStack.userInteractionEnabled = true;
if(selectedWidgetView) [self.view insertSubview:selectedWidgetView belowSubview:_widgetPanelStack];
if(selectedWidgetView){
[self.view insertSubview:selectedWidgetView belowSubview:_widgetPanelStack];
if(selectedWidgetView.widgetType == WidgetTypeEnumTouchPad) [self.view sendSubviewToBack:selectedWidgetView];
}
if(!isToolbarHidden && self->selectedWidgetView != nil && [self layerIsOverlappingWithTrashcanButton:selectedWidgetView.layer]){
@@ -546,6 +546,11 @@ BOOL isCustomResolution(int resolutionSelected) {
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
if(OnScreenControls.shared){
[OnScreenControls.shared clearLeftStickTouchPadFlag];
[OnScreenControls.shared clearRightStickTouchPadFlag];
}
else LiSendControllerEvent(0, 0, 0, 0, 0, 0, 0);
}
- (void)viewDidDisappear:(BOOL)animated{
@@ -2610,14 +2615,20 @@ BOOL isCustomResolution(int resolutionSelected) {
- (void)gyroMinStickOffsetSliderMoved:(UISlider* )sender{
[self findDynamicLabelFromStack:_gyroToStickMinOffsetStack].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
if(settingsViewJustExpanded) return;
LiSendControllerEvent(0, 0, 0, _rollToLeftStickSwitch.isOn?sender.value:0, 0, _yawPitchToRightStickSwitch.isOn?sender.value:0, 0);
}
- (void)leftStickMinOffsetSliderMoved:(UISlider* )sender{
[self findDynamicLabelFromStack:_leftStickMinOffsetStack].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
if(settingsViewJustExpanded) return;
LiSendControllerEvent(0, 0, 0, sender.value, 0, 0, 0);
}
- (void)rightStickMinOffsetSliderMoved:(UISlider* )sender{
[self findDynamicLabelFromStack:_rightStickMinOffsetStack].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
if(settingsViewJustExpanded) return;
LiSendControllerEvent(0, 0, 0, 0, 0, sender.value, 0);
}
- (void)invokeOscLayout{
+24
View File
@@ -5305,6 +5305,18 @@
}
}
},
"Wil-pj-Gru.text" : {
"comment" : "Class = \"UILabel\"; text = \"Walkmode threshold\"; ObjectID = \"Wil-pj-Gru\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Walkmode threshold"
}
}
}
},
"x9i-JN-FSn.text" : {
"comment" : "Class = \"UILabel\"; text = \"Roll factor\"; ObjectID = \"x9i-JN-FSn\";",
"extractionState" : "extracted_with_value",
@@ -5359,6 +5371,18 @@
}
}
},
"XMg-F0-m2y.text" : {
"comment" : "Class = \"UILabel\"; text = \"Component Size\"; ObjectID = \"XMg-F0-m2y\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Component Size"
}
}
}
},
"Xnd-C4-8N9.text" : {
"comment" : "Class = \"UILabel\"; text = \"Pointer Velocity\"; ObjectID = \"Xnd-C4-8N9\";",
"extractionState" : "extracted_with_value",
+24
View File
@@ -1219,6 +1219,18 @@
}
}
},
"Afv-Tt-8Fo.text" : {
"comment" : "Class = \"UILabel\"; text = \"Walkmode threshold\"; ObjectID = \"Afv-Tt-8Fo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Walkmode threshold"
}
}
}
},
"AN9-U4-nUG.text" : {
"comment" : "Class = \"UILabel\"; text = \"Yaw&Pitch → Right Stick\"; ObjectID = \"AN9-U4-nUG\";",
"extractionState" : "extracted_with_value",
@@ -2791,6 +2803,18 @@
}
}
},
"kcX-kR-3gl.text" : {
"comment" : "Class = \"UILabel\"; text = \"Component size\"; ObjectID = \"kcX-kR-3gl\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Component size"
}
}
}
},
"kva-gQ-CZh.text" : {
"comment" : "Class = \"UILabel\"; text = \"Size\"; ObjectID = \"kva-gQ-CZh\";",
"extractionState" : "extracted_with_value",