- feat: new on-screen widget lsWheel/rsWheel, direction wheel for RPG games.

- feat: direct walkmode test for lsWheel/rsWheel
- feat: direction minimum offset test for all on-screen widgets, gyro->stick mapping & physical controller.
This commit is contained in:
TrueZhuanjia
2025-12-26 16:17:55 +08:00
parent 2912a3a5cb
commit d8528fdc81
28 changed files with 977 additions and 102 deletions
+36 -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 */; };
@@ -182,6 +185,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>"; };
@@ -401,11 +405,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 */,
@@ -650,6 +660,7 @@
1888C1912E24C33100108730 /* AboutViewController.swift */,
FB89463719F6473800339C8A /* Launch Screen.xib */,
FB290D0819B2C406004C83CF /* Images.xcassets */,
18A0EE282EFBCBFB00BA853A /* SVGs */,
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */,
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */,
FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */,
@@ -764,6 +775,7 @@
isa = PBXGroup;
children = (
18729EDD2E8BD68800101194 /* UUIDHelper.swift */,
18A0EE2B2EFBCCFD00BA853A /* GraphicUtils.swift */,
97E20DD42E2164A9000D5DCA /* BandwidthTracker.h */,
97E20DD52E2164A9000D5DCA /* BandwidthTracker.m */,
97E20DD62E2164A9000D5DCA /* FloatBuffer.h */,
@@ -925,6 +937,9 @@
dependencies = (
98AB2E861CAD468B0089BB98 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
18A0EE282EFBCBFB00BA853A /* SVGs */,
);
name = VoidLink;
productName = Limelight;
productReference = FB290CEE19B2C406004C83CF /* VoidLink.app */;
@@ -960,6 +975,7 @@
packageReferences = (
F74BEF9A2C1A705600224667 /* XCRemoteSwiftPackageReference "OpenSSL-Package" */,
182760F52E83E2EA00EC1C5C /* XCRemoteSwiftPackageReference "swift-collections" */,
18A0EE232EFB9B5A00BA853A /* XCRemoteSwiftPackageReference "SVGKit" */,
);
productRefGroup = FB290CEF19B2C406004C83CF /* Products */;
projectDirPath = "";
@@ -1047,6 +1063,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 */,
@@ -1445,6 +1462,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";
@@ -1471,6 +1496,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
@@ -2353,7 +2353,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"/>
@@ -2447,8 +2447,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"/>
@@ -2484,7 +2503,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"/>
@@ -2503,7 +2522,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"/>
@@ -2522,7 +2541,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"/>
@@ -2541,7 +2560,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"/>
@@ -2559,8 +2578,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"/>
@@ -2579,7 +2617,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"/>
@@ -2598,7 +2636,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"/>
@@ -2617,7 +2655,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"/>
@@ -2636,7 +2674,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"/>
@@ -2655,7 +2693,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"/>
@@ -2682,7 +2720,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"/>
@@ -2744,6 +2782,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"/>
@@ -2782,6 +2823,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"/>
@@ -2896,7 +2940,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"/>
@@ -2905,13 +2949,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)
}
}
+13 -4
View File
@@ -390,8 +390,9 @@ 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;
@@ -410,6 +411,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 +432,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
@@ -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"];
@@ -60,6 +61,7 @@
[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 +80,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;
@@ -94,6 +97,7 @@
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;
}
+247 -44
View File
@@ -7,6 +7,7 @@
//
import UIKit
import SVGKit
@objc class OnScreenWidgetView: UIView, OscInstanceReceiverDelegate {
// receiving the OnScreenControls instance from delegate
@@ -68,18 +69,27 @@ 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 vibrationStyle: Int = 6
@objc public var latestTouchLocation: CGPoint
@objc public var selfViewOnTheRight: Bool = false
@@ -107,6 +117,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
@@ -133,10 +144,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
@@ -157,6 +171,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
@@ -195,7 +215,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
@@ -336,6 +356,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
@@ -354,7 +375,20 @@ 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
}
}
self.tweakBorderAlpha(alpha: self.borderAlpha) // fix default borderAlpha offset
setupView()
@@ -365,10 +399,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){
@@ -391,7 +426,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
}
// ======================================================================================================
@@ -458,8 +496,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){
@@ -471,7 +521,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)
@@ -498,6 +549,17 @@ 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){
@@ -551,45 +613,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([
@@ -643,6 +739,7 @@ import UIKit
else {self.layer.borderWidth = self.borderWidth}
if OnScreenWidgetView.editMode { //display label in edit mode to make the pad more visible
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
@@ -685,6 +782,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() {
@@ -902,7 +1002,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 =========================================
@@ -1260,7 +1450,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}
}
@@ -1293,7 +1483,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 {
@@ -1310,7 +1501,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)
@@ -1318,13 +1509,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)
@@ -1332,8 +1523,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)
}
@@ -1460,6 +1651,9 @@ 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!)
case "LSPAD","RSPAD":
self.showStickIndicator()
if quickDoubleTapDetected {
@@ -1728,8 +1922,9 @@ 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
let touchCentered = !self.isStickWheel
self.offSetX = touchCentered ? currentTouchLocation.x - self.touchBeganLocation.x : currentTouchLocation.x - self.bounds.midX
self.offSetY = touchCentered ? currentTouchLocation.y - self.touchBeganLocation.y : currentTouchLocation.y - self.bounds.midY
}
private func updateTouchLocation(touch: UITouch){
@@ -1782,6 +1977,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
@@ -2035,6 +2232,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()}
+3
View File
@@ -157,6 +157,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){
@@ -557,6 +558,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;
@@ -572,6 +574,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.
+70 -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" : {
@@ -5987,6 +6010,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" : {
@@ -7217,6 +7263,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" : {
@@ -7240,7 +7309,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.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"
@@ -153,6 +153,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 +168,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
@@ -493,6 +495,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
#pragma mark - UIButton Actions
- (IBAction) closeTapped:(id)sender {
[self clearSickInput];
[self dismissViewControllerAnimated:YES completion:nil];
}
@@ -736,6 +739,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 +752,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;
@@ -796,6 +801,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 +865,7 @@ typedef NS_ENUM(NSUInteger, DecelerationRateSliderMode) {
[self hideStickIndicators];
[self clearSickInput];
// receive the selected widgetView obj passed from the notification
[self enableCommonWidgetTools];
@@ -893,7 +900,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 +922,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,13 +980,18 @@ 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];
@@ -1085,6 +1106,16 @@ 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{
if(self->selectedWidgetView != nil && self->widgetViewSelected){
switch(alphaSliderMode){
@@ -1171,7 +1202,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 +1220,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 +1400,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 +1439,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;
@@ -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{
@@ -2587,14 +2592,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
@@ -5257,6 +5257,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",
@@ -5299,6 +5311,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",