- 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:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 |
@@ -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"]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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砖家"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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;
|
||||
|
||||
|
||||
|
||||
+82
-9
@@ -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{
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user