- feat: yaw & pitch factor for each on-screen "gyro" button for seamlessly toggling among different level of gyro sensitivities.

This commit is contained in:
TrueZhuanjia
2025-10-14 01:37:22 +08:00
parent 8cee8b679c
commit 11b79dda5b
14 changed files with 518 additions and 131 deletions
+52 -8
View File
@@ -1360,16 +1360,16 @@
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Oyk-L5-WTt" userLabel="singleTapSensitivityStack">
<rect key="frame" x="440" y="307" width="432" height="55.5"/>
<rect key="frame" x="440" y="307" width="436" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Single Tap Sensitivity" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SuN-S2-8hj">
<rect key="frame" x="0.0" y="0.0" width="432" height="20.5"/>
<rect key="frame" x="0.0" y="0.0" width="436" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="2" minValue="0.0" maxValue="5" minimumValueImage="0.square" catalog="system" maximumValueImage="5.square" translatesAutoresizingMaskIntoConstraints="NO" id="j4n-De-TRX" userLabel="Single Tap Sensitivity Slider">
<rect key="frame" x="-2" y="25.5" width="436" height="31"/>
<rect key="frame" x="-2" y="25.5" width="440" height="31"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="qOF-42-hPO"/>
</constraints>
@@ -1825,7 +1825,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="549"/>
<rect key="frame" x="325" y="156" width="650" height="619"/>
<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"/>
@@ -2011,8 +2011,46 @@
</slider>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KXB-uJ-onx" userLabel="decelerationRateStack">
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2KY-v5-YJv" userLabel="yawFactorStack">
<rect key="frame" x="0.0" y="447" width="650" height="30"/>
<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="30"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="djE-lq-f5f"/>
</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="8" translatesAutoresizingMaskIntoConstraints="NO" id="jwv-o3-ded">
<rect key="frame" x="158" y="0.0" width="494" height="31"/>
<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="JNt-eT-HCs" userLabel="pitchFactorStack">
<rect key="frame" x="0.0" y="482" width="650" height="30"/>
<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="30"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="Fo8-W2-oa5"/>
</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="8" translatesAutoresizingMaskIntoConstraints="NO" id="4NQ-cL-QH0">
<rect key="frame" x="158" y="0.0" width="494" height="31"/>
<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="KXB-uJ-onx" userLabel="decelerationRateStack">
<rect key="frame" x="0.0" y="517" width="650" height="30"/>
<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="30"/>
@@ -2031,7 +2069,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GMQ-EQ-Hum" userLabel="mouseDownButtonStack">
<rect key="frame" x="0.0" y="482" width="650" height="31"/>
<rect key="frame" x="0.0" y="552" 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"/>
@@ -2058,7 +2096,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LGW-oJ-5Zf" userLabel="triggerModeStack">
<rect key="frame" x="0.0" y="518" width="650" height="31"/>
<rect key="frame" x="0.0" y="588" 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"/>
@@ -2129,6 +2167,9 @@
<outlet property="loadButton" destination="OId-gk-Wkg" id="adP-54-1ir"/>
<outlet property="mouseButtonDownSelector" destination="H8S-aI-EBo" id="em1-fK-Cpb"/>
<outlet property="mouseDownButtonStack" destination="GMQ-EQ-Hum" id="sxb-40-3NI"/>
<outlet property="pitchFactorLabel" destination="fq3-ie-8by" id="dpT-7M-rIg"/>
<outlet property="pitchFactorSlider" destination="4NQ-cL-QH0" id="VxC-yb-L1u"/>
<outlet property="pitchFactorStack" destination="JNt-eT-HCs" id="iHx-Nk-Oko"/>
<outlet property="saveButton" destination="uda-zt-xrG" id="FyB-WY-rri"/>
<outlet property="sensitivityXLabel" destination="vJs-pg-hHe" id="RRw-Zq-LUa"/>
<outlet property="sensitivityXSlider" destination="DiG-XX-r8c" id="fz5-Et-1WV"/>
@@ -2157,11 +2198,14 @@
<outlet property="widgetSizeLabel" destination="ZuV-4A-0Zb" id="Nr8-Wg-POM"/>
<outlet property="widgetSizeSlider" destination="Xzq-VC-hP3" id="lW5-0R-s5U"/>
<outlet property="widgetSizeStack" destination="GOp-1e-oUF" id="v7q-w3-Tls"/>
<outlet property="yawFactorLabel" destination="iZc-Xt-NaK" id="SYz-OJ-C8A"/>
<outlet property="yawFactorSlider" destination="jwv-o3-ded" id="9c4-KB-Ozu"/>
<outlet property="yawFactorStack" destination="2KY-v5-YJv" id="MrM-mV-rOv"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dev-Ck-vTF" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2530" y="958"/>
<point key="canvasLocation" x="2529.4964028776981" y="957.52066115702485"/>
</scene>
<!--Profiles Table View Controller-->
<scene sceneID="W0E-wz-n2b">
+58 -8
View File
@@ -315,7 +315,7 @@
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="BVp-3O-vZ7" userLabel="widgetPanelStack" customClass="WidgetPanelStackView">
<rect key="frame" x="375" y="132" width="550" height="597"/>
<rect key="frame" x="375" y="132" width="550" height="651"/>
<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"/>
@@ -522,8 +522,52 @@
<constraint firstAttribute="height" constant="20" id="0xk-WB-usH"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3Bf-uN-nLa">
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XYC-Ug-Pns">
<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="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"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="BP6-ya-coy"/>
</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="8" translatesAutoresizingMaskIntoConstraints="NO" id="Gj9-qp-dlk">
<rect key="frame" x="158" y="0.0" width="394" height="21"/>
<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="6y6-JF-8Vk"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gkc-td-lg4">
<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="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"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="Dee-98-wHT"/>
</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="8" translatesAutoresizingMaskIntoConstraints="NO" id="ol0-mA-VxW">
<rect key="frame" x="158" y="0.0" width="394" height="21"/>
<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="Zq1-ux-ep3"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3Bf-uN-nLa">
<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="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"/>
@@ -545,7 +589,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gsG-6n-BAb" userLabel="vibrationStyleStack">
<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="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"/>
@@ -576,7 +620,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lEZ-1a-89J" userLabel="mouseButtonDownStack">
<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="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"/>
@@ -606,7 +650,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jE7-IB-GTS" userLabel="slidableStack">
<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="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"/>
@@ -674,6 +718,9 @@
<outlet property="decelerationRateStack" destination="3Bf-uN-nLa" id="WaW-YW-Q7p"/>
<outlet property="mouseButtonDownSelector" destination="tE5-Bm-4OB" id="9fh-99-8pu"/>
<outlet property="mouseDownButtonStack" destination="lEZ-1a-89J" id="R6t-gC-kcD"/>
<outlet property="pitchFactorLabel" destination="dEy-ER-Mb3" id="0or-ME-7P1"/>
<outlet property="pitchFactorSlider" destination="ol0-mA-VxW" id="bmd-0a-O4H"/>
<outlet property="pitchFactorStack" destination="gkc-td-lg4" id="gI0-q7-tO2"/>
<outlet property="sensitivityXLabel" destination="dJh-Ck-ugh" id="vso-QW-vxX"/>
<outlet property="sensitivityXSlider" destination="Vqk-gH-0xO" id="CVC-XX-0LQ"/>
<outlet property="sensitivityXStack" destination="fem-TG-vr3" id="O9M-Ip-ZlT"/>
@@ -703,6 +750,9 @@
<outlet property="widgetSizeLabel" destination="kva-gQ-CZh" id="1ND-rE-i8n"/>
<outlet property="widgetSizeSlider" destination="Eke-rc-DVp" id="avT-94-lV4"/>
<outlet property="widgetSizeStack" destination="xoH-wS-SS1" id="iwh-3g-Qde"/>
<outlet property="yawFactorLabel" destination="kzC-ut-7DI" id="uKe-bg-Wtx"/>
<outlet property="yawFactorSlider" destination="Gj9-qp-dlk" id="mN4-7n-kYY"/>
<outlet property="yawFactorStack" destination="XYC-Ug-Pns" id="Cbi-zd-xfv"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ORo-HP-JDj" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
@@ -1704,16 +1754,16 @@
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="N0i-z6-WgC" userLabel="singleTapSensitivityStack">
<rect key="frame" x="410" y="2455" width="464" height="55.5"/>
<rect key="frame" x="410" y="2455" width="468" height="55.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Single Tap Sensitivity" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WzD-wo-Wum">
<rect key="frame" x="0.0" y="0.0" width="464" height="20.5"/>
<rect key="frame" x="0.0" y="0.0" width="468" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="2" minValue="0.0" maxValue="5" minimumValueImage="0.square" catalog="system" maximumValueImage="5.square" translatesAutoresizingMaskIntoConstraints="NO" id="uCa-Oa-7mv" userLabel="Single Tap Sensitivity Slider">
<rect key="frame" x="-2" y="25.5" width="468" height="31"/>
<rect key="frame" x="-2" y="25.5" width="472" height="31"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="XXP-GP-uhn"/>
</constraints>
@@ -392,6 +392,8 @@ static CGRect layoutViewBounds;
buttonState.mouseButtonAction = widgetView.mouseButtonAction;
buttonState.sensitivityFactorX = widgetView.sensitivityFactorX;
buttonState.sensitivityFactorY = widgetView.sensitivityFactorY;
buttonState.yawFactor = widgetView.yawFactor;
buttonState.pitchFactor = widgetView.pitchFactor;
buttonState.decelerationRate = widgetView.trackballDecelerationRate;
buttonState.stickIndicatorOffset = widgetView.stickIndicatorOffset;
buttonState.widgetShape = widgetView.shape;
@@ -35,6 +35,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) CGFloat borderWidth; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat sensitivityFactorX; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat sensitivityFactorY; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat yawFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat pitchFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat decelerationRate; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat stickIndicatorOffset; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat minStickOffset; // for OnScreenWidgetView
@@ -46,6 +46,8 @@
[encoder encodeFloat:self.heightFactor forKey:@"heightFactor"];
[encoder encodeFloat:self.sensitivityFactorX forKey:@"sensitivityFactorX"];
[encoder encodeFloat:self.sensitivityFactorY forKey:@"sensitivityFactorY"];
[encoder encodeFloat:self.yawFactor forKey:@"yawFactor"];
[encoder encodeFloat:self.pitchFactor forKey:@"pitchFactor"];
[encoder encodeFloat:self.decelerationRate forKey:@"decelerationRate"];
[encoder encodeFloat:self.stickIndicatorOffset forKey:@"stickIndicatorOffset"];
[encoder encodeFloat:self.oscLayerSizeFactor forKey:@"oscLayerSizeFactor"];
@@ -72,6 +74,8 @@
self.heightFactor = [decoder decodeFloatForKey:@"heightFactor"];
self.sensitivityFactorX = [decoder containsValueForKey:@"sensitivityFactorX"] ? [decoder decodeFloatForKey:@"sensitivityFactorX"] : 1.0;
self.sensitivityFactorY = [decoder containsValueForKey:@"sensitivityFactorY"] ? [decoder decodeFloatForKey:@"sensitivityFactorY"] : 1.0;
self.yawFactor = [decoder containsValueForKey:@"yawFactor"] ? [decoder decodeFloatForKey:@"yawFactor"] : 1.0;
self.pitchFactor = [decoder containsValueForKey:@"pitchFactor"] ? [decoder decodeFloatForKey:@"pitchFactor"] : 1.0;
self.decelerationRate = [decoder decodeFloatForKey:@"decelerationRate"];
self.stickIndicatorOffset = [decoder decodeFloatForKey:@"stickIndicatorOffset"];
self.oscLayerSizeFactor = [decoder decodeFloatForKey:@"oscLayerSizeFactor"];
+48 -23
View File
@@ -16,17 +16,17 @@ import CoreMotion
}
@objc class MotionHandler: NSObject, OscInstanceReceiverDelegate, OnScreenWidgetStickMixedInputDelegate{
func mixRightStickAndGyroInput(x: CGFloat, y: CGFloat) {
public func mixRightStickAndGyroInput(x: CGFloat, y: CGFloat) {
rightStickTouchInputX = x
rightStickTouchInputY = y
}
func mixLeftStickAndGyroInput(x: CGFloat, y: CGFloat) {
public func mixLeftStickAndGyroInput(x: CGFloat, y: CGFloat) {
leftStickTouchInputX = x
leftStickTouchInputY = y
}
func gyroMixInputStarted() -> Bool {
public func gyroMixInputStarted() -> Bool {
return gyroIsWorking
}
@@ -54,13 +54,20 @@ import CoreMotion
private var oscProfileMan: OSCProfilesManager
private var oscProfile: OSCProfile
private var gyroControlStarted: Bool = false
@objc public var gyroControlStarted: Bool = false
private var gyroIsWorking: Bool = false
private var accelControlStarted: Bool = false
private let motionManager = CMMotionManager()
public var sensitvityYaw:CGFloat = 1.0
public var sensitvityPitch:CGFloat = 1.0
public var sensitvityRoll:CGFloat = 1.0
@objc public var widgetYawFactor:CGFloat = 1.0
@objc public var widgetPitchFactor:CGFloat = 1.0
@objc public var widgetRollFactor:CGFloat = 1.0
@objc public var previousWidgetYawFactor:CGFloat = 1.0
@objc public var previousWidgetPitchFactor:CGFloat = 1.0
@objc public var previousWidgetRollFactor:CGFloat = 1.0
public var gyroStarter:Any?
private var windowScene: Any?
private var onScreenControls: OnScreenControls = OnScreenControls.init()
@@ -110,17 +117,36 @@ import CoreMotion
motionManager.gyroUpdateInterval = updateInterval
}
public func startGyroByOnScreenButton(_ sender: OnScreenWidgetView, yawFactor:CGFloat, pitchFactor:CGFloat, rollFactor:CGFloat){
self.previousWidgetYawFactor = self.widgetYawFactor
self.previousWidgetPitchFactor = self.widgetPitchFactor
self.previousWidgetRollFactor = self.widgetRollFactor
self.widgetYawFactor = yawFactor
self.widgetPitchFactor = pitchFactor
self.widgetRollFactor = rollFactor
if self.gyroStarter == nil {
self.gyroStarter = sender
if sender.motionControlButtonString != "GYROPAUSE" {self.startGyroUpdate()}
}
else if sender.motionControlButtonString == "GYROPAUSE" {
self.startGyroUpdate()
}
}
/// 启动传感器数据更新
@objc public func startGyroUpdate() {
gyroControlStarted = true
if motionManager.isGyroAvailable {
motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in
guard let self = self, let data = gyroData else { return }
self.handleGyroData(x: data.rotationRate.x,
y: data.rotationRate.y,
z: data.rotationRate.z)
if !gyroControlStarted {
gyroControlStarted = true
if motionManager.isGyroAvailable {
motionManager.startGyroUpdates(to: .main) { [weak self] gyroData, _ in
guard let self = self, let data = gyroData else { return }
self.handleGyroData(x: data.rotationRate.x,
y: data.rotationRate.y,
z: data.rotationRate.z)
}
}
}
else {return}
}
@objc public func startAccelUpdate() {
@@ -136,16 +162,15 @@ import CoreMotion
}
/// 停止更新
private var needInterruption:Bool = false
private var interruptTouchInput:Bool = false
@objc public func stopGyroUpdate(interruption:Bool=false) {
@objc public func stopGyroUpdate(interruptTouchInput:Bool=false) {
gyroControlStarted = false
gyroIsWorking = false
needInterruption = interruption
if motionManager.isGyroActive{
motionManager.stopGyroUpdates()
}
self.clearGyroInput(interruption: needInterruption)
self.clearGyroInput(interruptTouchInput: interruptTouchInput)
}
@objc public func stopAccelUpdate() {
@@ -232,7 +257,7 @@ import CoreMotion
}
if !gyroControlStarted {
self.clearGyroInput(interruption: needInterruption)
self.clearGyroInput(interruptTouchInput: interruptTouchInput)
print("Gyro: stopped")
return
}
@@ -240,25 +265,25 @@ import CoreMotion
gyroIsWorking = true
if oscProfile.mapGyroTo == MapGyroTo.mapGyroToMouse {
yaw = yawSource*sensitvityYaw*30
pitch = pitchSource*sensitvityPitch*30
yaw = yawSource*sensitvityYaw*widgetYawFactor*30
pitch = pitchSource*sensitvityPitch*widgetPitchFactor*30
LiSendMouseMoveEvent(Int16(yaw),Int16(pitch))
}
if oscProfile.mapGyroTo == MapGyroTo.mapGyroToControllerStick {
if oscProfile.yawPitchToRightStick {
yaw = rightStickTouchInputX + gyroInputToStickInput(input:yawSource*sensitvityYaw*10)
yaw = rightStickTouchInputX + gyroInputToStickInput(input:yawSource*sensitvityYaw*widgetYawFactor*10)
yaw = self.clampStickInput(input: yaw)
yaw = (yaw >= 0 ? 1.0 : -1.0) * gyroToStickMinOffset + (self.stickMaxOffset - gyroToStickMinOffset) * (yaw/self.stickMaxOffset)
pitch = rightStickTouchInputY - gyroInputToStickInput(input:pitchSource*sensitvityPitch*10)
pitch = rightStickTouchInputY - gyroInputToStickInput(input:pitchSource*sensitvityPitch*widgetPitchFactor*10)
pitch = self.clampStickInput(input: pitch)
pitch = (pitch >= 0 ? 1.0 : -1.0) * gyroToStickMinOffset + (self.stickMaxOffset - gyroToStickMinOffset) * (pitch/self.stickMaxOffset)
self.onScreenControls.sendRightStickTouchPadEvent(yaw, pitch)
}
if oscProfile.rollToLeftStick {
roll = leftStickTouchInputX + gyroInputToStickInput(input:rollSource*sensitvityRoll*10)
roll = leftStickTouchInputX + gyroInputToStickInput(input:rollSource*sensitvityRoll*widgetRollFactor*10)
roll = self.clampStickInput(input: roll)
roll = (roll >= 0 ? 1.0 : -1.0) * gyroToStickMinOffset + (self.stickMaxOffset - gyroToStickMinOffset) * (roll/self.stickMaxOffset)
@@ -267,14 +292,14 @@ import CoreMotion
}
}
private func clearGyroInput(interruption:Bool){
private func clearGyroInput(interruptTouchInput:Bool){
if oscProfile.yawPitchToRightStick{
self.onScreenControls.sendRightStickTouchPadEvent(rightStickTouchInputX-yawBias, rightStickTouchInputY-pitchBias)
}
if oscProfile.rollToLeftStick{
self.onScreenControls.sendLeftStickTouchPadEvent(leftStickTouchInputX-rollBias, leftStickTouchInputY)
}
if(interruption){
if(interruptTouchInput){
self.onScreenControls.clearLeftStickTouchPadFlag()
self.onScreenControls.clearRightStickTouchPadFlag()
}
+126 -82
View File
@@ -24,19 +24,10 @@ import UIKit
func updateGuidelinesForOnScreenWidget(_ sender: Any)
}
@objc public weak var mixInputDelegate: OnScreenWidgetStickMixedInputDelegate?
@objc protocol OnScreenWidgetStickMixedInputDelegate: AnyObject {
func mixRightStickAndGyroInput(x: CGFloat, y: CGFloat)
func mixLeftStickAndGyroInput(x: CGFloat, y: CGFloat)
func gyroMixInputStarted()->Bool
}
@objc public var motionHandler: MotionHandler = MotionHandler.shared
@objc public weak var functionalButtonDelegate: OnScreenFunctionalButtonDelegate?
@objc protocol OnScreenFunctionalButtonDelegate: AnyObject {
func startGyroUpdate()
func startAccelUpdate()
func stopGyroUpdate(interruption:Bool)
func stopAccelUpdate(interruption:Bool)
func openWidgetLayoutTool()
func switchWidgetProfile()
func bringUpSoftKeyboard()
@@ -63,13 +54,14 @@ import UIKit
@objc public var identifier: String = ""
private var buttonString: String = ""
private var functionalButtonString: String = ""
private var motionControlButtonString: String = ""
public var motionControlButtonString: String = ""
private var touchPadString: String = ""
// super combo key string set
@objc public var comboButtonStrings: [String] = []
private var comboKeyTimeIntervalMs: UInt32 = 0
@objc public var pressed: Bool
@objc public var logicallyDown: Bool = false
@objc public var widthFactor: CGFloat = 1.0
@objc public var heightFactor: CGFloat = 1.0
@@ -107,10 +99,17 @@ import UIKit
@objc public var hasStickIndicator: Bool = false
@objc public var hasSensitivityX: Bool = false
@objc public var sensitivityXMin: CGFloat = 0
@objc public var sensitivityXMAX: CGFloat = 8
@objc public var sensitivityXMax: CGFloat = 8
@objc public var hasSensitivityY: Bool = false
@objc public var sensitivityYMin: CGFloat = 0
@objc public var sensitivityYMAX: CGFloat = 8
@objc public var sensitivityYMax: CGFloat = 8
@objc public var hasYawFactor: Bool = false
@objc public var yawFactorMin: CGFloat = 0
@objc public var yawFactorMax: CGFloat = 1
@objc public var hasPitchFactor: Bool = false
@objc public var pitchFactorMin: CGFloat = 0
@objc public var pitchFactorMax: CGFloat = 1
@objc public var hasAutoTap: Bool = false
@objc public var isMousePad: Bool = false
@objc public var hasTrackBall: Bool = false
@@ -140,7 +139,11 @@ import UIKit
// this is for all stick pads and mouse Pad
@objc public var sensitivityFactorX: CGFloat = 1.0
@objc public var sensitivityFactorY: CGFloat = 1.0
@objc public var yawFactor: CGFloat = 1.0
@objc public var pitchFactor: CGFloat = 1.0
@objc public var rollFactor: CGFloat = 1.0
private var gyroControlPreviousStatus: NSMutableDictionary = NSMutableDictionary()
// check quick double tap:
private var quickDoubleTapDetected: Bool
private var touchTapTimeInterval: TimeInterval
@@ -338,10 +341,19 @@ import UIKit
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)
if CommandManager.bidirectionalVerticalTouchPads.contains(self.touchPadString){
self.sensitivityYMin = -4
self.sensitivityYMAX = 4
self.sensitivityYMin = -4.0
self.sensitivityYMax = 4.0
}
self.hasYawFactor = self.motionControlButtonString == "GYRO" && (oscProfile.mapGyroTo == MapGyroTo.mapGyroToMouse || oscProfile.yawPitchToRightStick)
self.hasPitchFactor = self.hasYawFactor
self.yawFactorMin = 0
self.yawFactorMax = 1.0
self.pitchFactorMin = 0
self.pitchFactorMax = 1.0
self.hasAutoTap = self.widgetType == WidgetTypeEnum.button && self.functionalButtonString == "" && self.motionControlButtonString == ""
self.isMousePad = self.touchPadString == "MOUSEPAD" && widgetType == WidgetTypeEnum.touchPad
self.hasTrackBall = self.touchPadString == "TRACKBALL"
@@ -1120,20 +1132,33 @@ import UIKit
if !OnScreenWidgetView.editMode, !self.motionControlButtonString.isEmpty {self.handleMotionControlButtonDown()}
// sadflkasdfl;
print("666 buttonDownVisualEffectLayer.borderColor: \(CACurrentMediaTime())")
if OnScreenWidgetView.buttonVisualFeedbackEnabled {
CATransaction.begin()
CATransaction.setDisableActions(true)
// self.layer.borderWidth = 0
buttonDownVisualEffectLayer.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) // update position every time we press down the button
buttonDownVisualEffectLayer.borderWidth = self.buttonDownVisualEffectWidth // this will show the visual effect
// buttonDownVisualEffectLayer.borderWidth = self.buttonDownVisualEffectWidth // this will show the visual effect
buttonDownVisualEffectLayer.borderColor = voidlinkPurple
logicallyDown = true
CATransaction.commit()
}
if vibrationOn {
vibrationGenerator.prepare()
vibrationGenerator.impactOccurred()
// print("vibrationInstance: \(vibrationGenerator)")
}
}
private func buttonUpVisualEffect(){
if OnScreenWidgetView.buttonVisualFeedbackEnabled {
CATransaction.begin()
CATransaction.setDisableActions(true)
// self.layer.borderWidth = 1
// buttonDownVisualEffectLayer.borderWidth = 0
buttonDownVisualEffectLayer.borderColor = UIColor.clear.cgColor
logicallyDown = false
CATransaction.commit()
}
}
@@ -1148,14 +1173,7 @@ import UIKit
self.handleFunctionalButtonUp()
}
if OnScreenWidgetView.buttonVisualFeedbackEnabled {
CATransaction.begin()
CATransaction.setDisableActions(true)
// self.layer.borderWidth = 1
buttonDownVisualEffectLayer.borderWidth = 0
buttonDownVisualEffectLayer.borderColor = defaultBorderColor
CATransaction.commit()
}
self.buttonUpVisualEffect()
}
private func setupLrudDirectionIndicatorlayers() {
@@ -1180,7 +1198,8 @@ import UIKit
if self.motionControlButtonString != "" {self.buttonDownVisualEffectWidth = 3}
// Set the frame to be larger than the view to expand outward
buttonDownVisualEffectLayer.borderWidth = 0 // set this 0 to hide the visual effect first
buttonDownVisualEffectLayer.borderWidth = self.buttonDownVisualEffectWidth // set this 0 to hide the visual effect first
buttonDownVisualEffectLayer.borderColor = UIColor.clear.cgColor
buttonDownVisualEffectLayer.frame = self.bounds.insetBy(dx: -self.buttonDownVisualEffectWidth, dy: -self.buttonDownVisualEffectWidth) // Adjust the inset as needed
buttonDownVisualEffectLayer.cornerRadius = self.layer.cornerRadius + self.buttonDownVisualEffectWidth
buttonDownVisualEffectLayer.backgroundColor = UIColor.clear.cgColor;
@@ -1223,12 +1242,12 @@ import UIKit
let mixRightStickInputToGyro = (oscProfile.mapGyroTo == MapGyroTo.mapGyroToControllerStick
&& oscProfile.yawPitchToRightStick)
if !mixRightStickInputToGyro || (self.mixInputDelegate?.gyroMixInputStarted() != true) {
if !mixRightStickInputToGyro || (self.motionHandler.gyroMixInputStarted() != true) {
targetX = (targetX >= 0 ? 1.0 : -1.0) * self.minStickOffset + (self.stickMaxOffset - self.minStickOffset) * (targetX/self.stickMaxOffset)
targetY = (targetY >= 0 ? 1.0 : -1.0) * self.minStickOffset + (self.stickMaxOffset - self.minStickOffset) * (targetY/self.stickMaxOffset)
self.onScreenControls.sendRightStickTouchPadEvent(targetX, targetY)
}
self.mixInputDelegate?.mixRightStickAndGyroInput(x: targetX, y: targetY)
self.motionHandler.mixRightStickAndGyroInput(x: targetX, y: targetY)
}
private func sendLeftStickTouchPadEvent(inputX: CGFloat, inputY: CGFloat){
@@ -1239,10 +1258,10 @@ import UIKit
let mixLeftStickInputToGyro = (oscProfile.mapGyroTo == MapGyroTo.mapGyroToControllerStick
&& oscProfile.rollToLeftStick)
if !mixLeftStickInputToGyro || (self.mixInputDelegate?.gyroMixInputStarted() != true) {
if !mixLeftStickInputToGyro || (self.motionHandler.gyroMixInputStarted() != true) {
self.onScreenControls.sendLeftStickTouchPadEvent(targetX, targetY)
}
self.mixInputDelegate?.mixLeftStickAndGyroInput(x: targetX, y: targetY)
self.motionHandler.mixLeftStickAndGyroInput(x: targetX, y: targetY)
}
private func sendLeftTriggerTouchPadEvent(inputY: CGFloat){
@@ -1534,42 +1553,49 @@ import UIKit
}
}
}
private func forEachWidget(_ action: (OnScreenWidgetView) -> Void) {
// 遍历 superview 的 subviews,如果 superview 为 nil,则遍历空数组
for subview in self.superview?.subviews ?? [] {
if let widget = subview as? OnScreenWidgetView {
action(widget)
}
}
}
private func handleButtonSliding(touches: Set<UITouch>) {
for touch in touches {
let locationInSuperView = touch.location(in: self.superview)
for subview in self.superview?.subviews ?? [] {
if let widget = subview as? OnScreenWidgetView{
if widget.widgetType != WidgetTypeEnum.button {continue}
let isSlidableButton = widget.buttonMode == ButtonMode.slideToToggle.rawValue || widget.buttonMode == ButtonMode.slideAndHold.rawValue
let pointInSubview = widget.convert(locationInSuperView, from: self.superview)
if widget.bounds.contains(pointInSubview){
self.forEachWidget{ widget in
if widget.widgetType != WidgetTypeEnum.button {return}
let isSlidableButton = widget.buttonMode == ButtonMode.slideToToggle.rawValue || widget.buttonMode == ButtonMode.slideAndHold.rawValue
let pointInSubview = widget.convert(locationInSuperView, from: self.superview)
if widget.bounds.contains(pointInSubview){
setLock.lock()
let captured = widget.capturedTouches.contains(touch)
setLock.unlock()
if captured || !isSlidableButton
{return}
setLock.lock()
widget.capturedTouches.add(touch)
setLock.unlock()
widget.handleTapDownOrSlidein()
// print("UIButton: \(widget.buttonLabel) in, \(widget.touchPadString), \(CACurrentMediaTime())")
}
else{
setLock.lock()
let captured = widget.capturedTouches.contains(touch)
setLock.unlock()
if !captured || !isSlidableButton {return}
// print("UIButton: \(widget.buttonLabel) out test, \(widget.touchPadString), \(CACurrentMediaTime())")
if(widget.buttonMode == ButtonMode.slideToToggle.rawValue){
widget.handleFingerUpOrSlideout()
setLock.lock()
let captured = widget.capturedTouches.contains(touch)
widget.capturedTouches.remove(touch)
setLock.unlock()
if captured || !isSlidableButton
{continue}
setLock.lock()
widget.capturedTouches.add(touch)
setLock.unlock()
widget.handleTapDownOrSlidein()
// print("UIButton: \(widget.buttonLabel) in, \(widget.touchPadString), \(CACurrentMediaTime())")
}
else{
setLock.lock()
let captured = widget.capturedTouches.contains(touch)
setLock.unlock()
if !captured || !isSlidableButton {continue}
// print("UIButton: \(widget.buttonLabel) out test, \(widget.touchPadString), \(CACurrentMediaTime())")
if(widget.buttonMode == ButtonMode.slideToToggle.rawValue){
widget.handleFingerUpOrSlideout()
setLock.lock()
widget.capturedTouches.remove(touch)
setLock.unlock()
}
if(widget.buttonMode == ButtonMode.slideAndHold.rawValue){
// do nothing here
}
if(widget.buttonMode == ButtonMode.slideAndHold.rawValue){
// do nothing here
}
}
}
@@ -1694,14 +1720,14 @@ import UIKit
private func handleMotionControlButtonDown(){
switch self.motionControlButtonString {
case "GYRO":
self.functionalButtonDelegate?.startGyroUpdate()
self.motionHandler.startGyroByOnScreenButton(self, yawFactor: yawFactor, pitchFactor: pitchFactor, rollFactor: rollFactor)
case "GYROPAUSE":
self.functionalButtonDelegate?.stopGyroUpdate(interruption:false)
self.motionHandler.stopGyroUpdate(interruptTouchInput:false)
break
case "ACCEL":
self.functionalButtonDelegate?.startAccelUpdate()
break
case "MOTION":
self.functionalButtonDelegate?.startGyroUpdate()
self.functionalButtonDelegate?.startAccelUpdate()
break
default:
break
}
@@ -1710,14 +1736,32 @@ import UIKit
private func handleMotionControlButtonUp(){
switch self.motionControlButtonString {
case "GYRO":
self.functionalButtonDelegate?.stopGyroUpdate(interruption: false)
if let gyroStarter = motionHandler.gyroStarter as? OnScreenWidgetView, self === gyroStarter {
self.forEachWidget{ widget in
if widget.motionControlButtonString != "GYRO" || widget === self {return}
if(widget.buttonMode == ButtonMode.tapToToggle.rawValue && widget.logicallyDown) {
widget.buttonUpVisualEffect()
widget.tapToToggleFlag = !widget.tapToToggleFlag
}
}
self.motionHandler.stopGyroUpdate(interruptTouchInput: false)
self.motionHandler.gyroStarter = nil
}
else {
if self.motionHandler.gyroStarter != nil {
if let gyroStarter = motionHandler.gyroStarter as? OnScreenWidgetView {
self.motionHandler.startGyroByOnScreenButton(self, yawFactor: gyroStarter.yawFactor, pitchFactor: gyroStarter.pitchFactor, rollFactor: gyroStarter.rollFactor)
}
}
}
case "GYROPAUSE":
self.functionalButtonDelegate?.startGyroUpdate()
if self.motionHandler.gyroStarter != nil {
self.motionHandler.startGyroByOnScreenButton(self, yawFactor: motionHandler.widgetYawFactor, pitchFactor: motionHandler.widgetPitchFactor, rollFactor: motionHandler.widgetRollFactor)
}
case "ACCEL":
self.functionalButtonDelegate?.stopAccelUpdate(interruption: false)
break
case "MOTION":
self.functionalButtonDelegate?.stopGyroUpdate(interruption: false)
self.functionalButtonDelegate?.stopAccelUpdate(interruption: false)
break
default:
break
}
@@ -1738,19 +1782,19 @@ import UIKit
private func clearRightStickTouchPadFlag(){
let mixRightStickInputToGyro = (oscProfile.mapGyroTo == MapGyroTo.mapGyroToControllerStick
&& oscProfile.yawPitchToRightStick)
if !mixRightStickInputToGyro || self.mixInputDelegate?.gyroMixInputStarted() != true {
if !mixRightStickInputToGyro || self.motionHandler.gyroMixInputStarted() != true {
self.onScreenControls.clearRightStickTouchPadFlag()
}
self.mixInputDelegate?.mixRightStickAndGyroInput(x: 0, y: 0)
self.motionHandler.mixRightStickAndGyroInput(x: 0, y: 0)
}
private func clearLeftStickTouchPadFlag(){
let mixLeftStickInputToGyro = (oscProfile.mapGyroTo == MapGyroTo.mapGyroToControllerStick
&& oscProfile.rollToLeftStick)
if !mixLeftStickInputToGyro || self.mixInputDelegate?.gyroMixInputStarted() != true {
if !mixLeftStickInputToGyro || self.motionHandler.gyroMixInputStarted() != true {
self.onScreenControls.clearLeftStickTouchPadFlag()
}
self.mixInputDelegate?.mixLeftStickAndGyroInput(x: 0, y: 0)
self.motionHandler.mixLeftStickAndGyroInput(x: 0, y: 0)
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
@@ -1916,14 +1960,14 @@ import UIKit
override func didMoveToSuperview() {
super.didMoveToSuperview()
if superview == nil {
if self.functionalButtonString == "GYRO" {self.functionalButtonDelegate?.stopGyroUpdate(interruption: true)}
if self.functionalButtonString == "ACCEL" {self.functionalButtonDelegate?.stopAccelUpdate(interruption: true)}
if self.functionalButtonString == "MOTION" {
self.functionalButtonDelegate?.stopGyroUpdate(interruption: true)
self.functionalButtonDelegate?.stopAccelUpdate(interruption: true)
if self.motionControlButtonString == "GYRO" {
self.motionHandler.stopGyroUpdate(interruptTouchInput: true)
self.motionHandler.gyroStarter = nil
}
buttonDownVisualEffectLayer.borderWidth = 0
buttonDownVisualEffectLayer.borderColor = defaultBorderColor
if self.motionControlButtonString == "ACCEL" {}
if self.motionControlButtonString == "MOTION" {}
buttonDownVisualEffectLayer.borderColor = UIColor.clear.cgColor
buttonDownVisualEffectLayer.removeFromSuperlayer()
crossMarkLayer.removeFromSuperlayer()
stickBallLayer.removeFromSuperlayer()
}
+3 -1
View File
@@ -548,7 +548,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
//--------------------------------------------------
widgetView.functionalButtonDelegate = (id<OnScreenFunctionalButtonDelegate>)streamFrameVC;
widgetView.mixInputDelegate = (id<OnScreenWidgetStickMixedInputDelegate>)motionHandler;
widgetView.motionHandler = motionHandler;
widgetView.identifier = buttonState.identifier;
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
@@ -560,6 +560,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
widgetView.mouseButtonAction = buttonState.mouseButtonAction;
widgetView.sensitivityFactorX = buttonState.sensitivityFactorX;
widgetView.sensitivityFactorY = buttonState.sensitivityFactorY;
widgetView.yawFactor = buttonState.yawFactor;
widgetView.pitchFactor = buttonState.pitchFactor;
widgetView.trackballDecelerationRate = buttonState.decelerationRate;
widgetView.stickIndicatorOffset = buttonState.stickIndicatorOffset;
widgetView.minStickOffset = buttonState.minStickOffset;
@@ -3958,6 +3958,29 @@
}
}
},
"Pitch factor: %.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"
}
}
}
},
"Place the device flat on a surface and keep it still, then tap ‘Start’." : {
"extractionState" : "manual",
"localizations" : {
@@ -6053,6 +6076,29 @@
}
}
},
"Yaw factor: %.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"
}
}
}
},
"Your network connection isn't performing well. Reduce your video bitrate setting or try a faster connection." : {
"extractionState" : "manual",
"localizations" : {
@@ -78,6 +78,14 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) IBOutlet UISlider *sensitivityYSlider;
@property (strong, nonatomic) IBOutlet UIStackView *sensitivityYStack;
@property (strong, nonatomic) IBOutlet UILabel *yawFactorLabel;
@property (strong, nonatomic) IBOutlet UISlider *yawFactorSlider;
@property (strong, nonatomic) IBOutlet UIStackView *yawFactorStack;
@property (strong, nonatomic) IBOutlet UILabel *pitchFactorLabel;
@property (strong, nonatomic) IBOutlet UISlider *pitchFactorSlider;
@property (strong, nonatomic) IBOutlet UIStackView *pitchFactorStack;
@property (strong, nonatomic) IBOutlet UIStackView *decelerationRateStack;
@property (strong, nonatomic) IBOutlet UILabel *decelerationRateLabel;
@property (strong, nonatomic) IBOutlet UISlider *decelerationRateSlider;
@@ -139,6 +139,8 @@
widgetView.mouseButtonAction = buttonState.mouseButtonAction;
widgetView.sensitivityFactorX = buttonState.sensitivityFactorX;
widgetView.sensitivityFactorY = buttonState.sensitivityFactorY;
widgetView.yawFactor = buttonState.yawFactor;
widgetView.pitchFactor = buttonState.pitchFactor;
widgetView.trackballDecelerationRate = buttonState.decelerationRate;
widgetView.stickIndicatorOffset = buttonState.stickIndicatorOffset;
widgetView.minStickOffset = buttonState.minStickOffset;
@@ -646,6 +648,8 @@
newWidget.autoTapInterval = widget.autoTapInterval;
newWidget.sensitivityFactorX = widget.sensitivityFactorX;
newWidget.sensitivityFactorY = widget.sensitivityFactorY;
newWidget.yawFactor = widget.yawFactor;
newWidget.pitchFactor = widget.pitchFactor;
newWidget.trackballDecelerationRate = widget.trackballDecelerationRate;
newWidget.stickIndicatorOffset = widget.stickIndicatorOffset;
newWidget.minStickOffset = [widgetInitParams[@"minStickOffsetString"] floatValue];
@@ -776,21 +780,40 @@
self.sensitivityXStack.hidden = !selectedWidgetView.hasSensitivityX;
if(selectedWidgetView.hasSensitivityX){
[self.sensitivityXSlider setMinimumValue:selectedWidgetView.sensitivityXMin];
[self.sensitivityXSlider setMaximumValue:selectedWidgetView.sensitivityXMAX];
[self.sensitivityXSlider setMaximumValue:selectedWidgetView.sensitivityXMax];
[self.sensitivityXSlider setValue:self->selectedWidgetView.sensitivityFactorX];
[self.sensitivityXLabel setText:[LocalizationHelper localizedStringForKey:@"SensitivityX: %.2f", self->selectedWidgetView.sensitivityFactorX]];
[self autoFitLabel:self.sensitivityXLabel];
}
self.sensitivityYStack.hidden = !selectedWidgetView.hasSensitivityY;
if(selectedWidgetView.hasSensitivityY){
[self.sensitivityYSlider setMinimumValue:selectedWidgetView.sensitivityYMin];
[self.sensitivityYSlider setMaximumValue:selectedWidgetView.sensitivityYMAX];
[self.sensitivityXLabel setText:[LocalizationHelper localizedStringForKey:@"SensitivityX: %.2f", self->selectedWidgetView.sensitivityFactorX]];
[self autoFitLabel:self.sensitivityYLabel];
[self.sensitivityYSlider setMaximumValue:selectedWidgetView.sensitivityYMax];
[self.sensitivityYSlider setValue:self->selectedWidgetView.sensitivityFactorY];
[self.sensitivityYLabel setText:[LocalizationHelper localizedStringForKey:@"SensitivityY: %.2f", self->selectedWidgetView.sensitivityFactorY]];
[self autoFitLabel:self.sensitivityYLabel];
}
self.yawFactorStack.hidden = !selectedWidgetView.hasYawFactor;
if(selectedWidgetView.hasYawFactor){
[self.yawFactorSlider setMinimumValue:selectedWidgetView.yawFactorMin];
[self.yawFactorSlider setMaximumValue:selectedWidgetView.yawFactorMax];
[self.yawFactorSlider setValue:self->selectedWidgetView.yawFactor];
[self.yawFactorLabel setText:[LocalizationHelper localizedStringForKey:@"Yaw factor: %.2f", self->selectedWidgetView.yawFactor]];
[self autoFitLabel:self.yawFactorLabel];
}
self.pitchFactorStack.hidden = !selectedWidgetView.hasPitchFactor;
if(selectedWidgetView.hasPitchFactor){
[self.pitchFactorSlider setMinimumValue:selectedWidgetView.pitchFactorMin];
[self.pitchFactorSlider setMaximumValue:selectedWidgetView.pitchFactorMax];
[self.pitchFactorSlider setValue:self->selectedWidgetView.pitchFactor];
[self.pitchFactorLabel setText:[LocalizationHelper localizedStringForKey:@"Pitch factor: %.2f", self->selectedWidgetView.pitchFactor]];
[self autoFitLabel:self.pitchFactorLabel];
}
self.stickIndicatorOffsetStack.hidden = !selectedWidgetView.hasStickIndicator;
if(selectedWidgetView.hasStickIndicator){
// illustrating the indicator offset,
@@ -946,7 +969,6 @@
return;
}
- (void)mouseDownButtonChanged:(UISegmentedControl* )sender{
if(self->selectedWidgetView != nil && self->widgetViewSelected){
selectedWidgetView.mouseButtonAction = _mouseButtonDownSelector.selectedSegmentIndex;
@@ -997,6 +1019,24 @@
return;
}
- (void)yawFactorSliderMoved:(UISlider* )sender{;
[self.yawFactorLabel setText:[LocalizationHelper localizedStringForKey:@"Yaw factor: %.2f", sender.value]];
[self.pitchFactorLabel setText:[LocalizationHelper localizedStringForKey:@"Pitch factor: %.2f", sender.value]];
[self.pitchFactorSlider setValue:sender.value];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
self->selectedWidgetView.yawFactor = sender.value;
self->selectedWidgetView.pitchFactor = sender.value;
}
return;
}
- (void)pitchFactorSliderMoved:(UISlider* )sender{
[self.pitchFactorLabel setText:[LocalizationHelper localizedStringForKey:@"Pitch factor: %.2f", sender.value]];
if(self->selectedWidgetView != nil && self->widgetViewSelected) self->selectedWidgetView.pitchFactor = sender.value;
return;
}
- (void)decelerationRateSliderMoved:(UISlider* )sender{
[self.decelerationRateLabel setText:[LocalizationHelper localizedStringForKey:@"Deceleration Rate: %.3f ", sender.value]];
if(self->selectedWidgetView != nil && self->widgetViewSelected) self->selectedWidgetView.trackballDecelerationRate = sender.value;
@@ -1114,7 +1154,14 @@
[self.sensitivityYSlider addTarget:self action:@selector(sensitivityYSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.sensitivityYLabel.text = [LocalizationHelper localizedStringForKey:@"SensitivityY"];
self.sensitivityYStack.hidden = YES;
[self.yawFactorSlider addTarget:self action:@selector(yawFactorSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.yawFactorLabel.text = [LocalizationHelper localizedStringForKey:@"SensitivityYaw"];
self.yawFactorStack.hidden = YES;
[self.pitchFactorSlider addTarget:self action:@selector(pitchFactorSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.pitchFactorLabel.text = [LocalizationHelper localizedStringForKey:@"SensitivityPitch"];
self.pitchFactorStack.hidden = YES;
[self.decelerationRateSlider addTarget:self action:@selector(decelerationRateSliderMoved:) forControlEvents:(UIControlEventValueChanged)];
self.decelerationRateLabel.text = [LocalizationHelper localizedStringForKey:@"Deceleration Rate"];
@@ -1524,16 +1524,45 @@
[self reConfigStreamViewRealtime];
}
- (void)startGyroUpdate{
- (NSMutableDictionary *)startGyroUpdate:(OnScreenWidgetView *)sender yawFactor:(CGFloat)yawFactor pitchFactor:(CGFloat)pitchFactor rollFactor:(CGFloat)rollFactor{
NSMutableDictionary* gyroControlPreviousStatus = [NSMutableDictionary dictionary];
if(!_motionHandler.gyroControlStarted) [gyroControlPreviousStatus setObject:sender forKey:@"gyroControlStarter"];
[gyroControlPreviousStatus setObject:@(_motionHandler.widgetYawFactor) forKey:@"previousYawFactor"];
[gyroControlPreviousStatus setObject:@(_motionHandler.widgetPitchFactor) forKey:@"previousPitchFactor"];
[gyroControlPreviousStatus setObject:@(_motionHandler.widgetRollFactor) forKey:@"previousRollFactor"];
_motionHandler.widgetYawFactor = yawFactor;
_motionHandler.widgetPitchFactor = pitchFactor;
_motionHandler.widgetRollFactor = rollFactor;
[_motionHandler startGyroUpdate];
return gyroControlPreviousStatus;
}
- (NSMutableDictionary*)start:(CGFloat)yawFactor pitchFactor:(CGFloat)pitchFactor rollFactor:(CGFloat)rollFactor{
NSMutableDictionary* gyroControlPreviousStatus = [NSMutableDictionary dictionary];
if(!_motionHandler.gyroControlStarted){
[gyroControlPreviousStatus setObject:@(_motionHandler.gyroControlStarted) forKey:@"gyroStarted"];
}
[gyroControlPreviousStatus setObject:@(_motionHandler.widgetYawFactor) forKey:@"previousYawFactor"];
[gyroControlPreviousStatus setObject:@(_motionHandler.widgetPitchFactor) forKey:@"previousPitchFactor"];
[gyroControlPreviousStatus setObject:@(_motionHandler.widgetRollFactor) forKey:@"previousRollFactor"];
_motionHandler.widgetYawFactor = yawFactor;
_motionHandler.widgetPitchFactor = pitchFactor;
_motionHandler.widgetRollFactor = rollFactor;
[_motionHandler startGyroUpdate];
return gyroControlPreviousStatus;
}
- (void)startAccelUpdate{
[_motionHandler startAccelUpdate];
}
- (void)stopGyroUpdateWithInterruption:(BOOL)interruption{
[_motionHandler stopGyroUpdateWithInterruption:interruption];
- (void)stopGyroUpdateWithInterruptTouchInput:(BOOL)interruption{
[_motionHandler stopGyroUpdateWithInterruptTouchInput:interruption];
}
- (void)stopAccelUpdate{
+60
View File
@@ -1867,6 +1867,36 @@
}
}
},
"fq3-ie-8by.text" : {
"comment" : "Class = \"UILabel\"; text = \"Pitch factor\"; ObjectID = \"fq3-ie-8by\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Pitch factor"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "俯仰系数"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "俯仰係數"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "俯仰係數"
}
}
}
},
"FwK-oG-vuz.text" : {
"comment" : "Class = \"UILabel\"; text = \"Physical Mouse Wheel Scroll\"; ObjectID = \"FwK-oG-vuz\";",
"extractionState" : "extracted_with_value",
@@ -2329,6 +2359,36 @@
}
}
},
"iZc-Xt-NaK.text" : {
"comment" : "Class = \"UILabel\"; text = \"Yaw factor\"; ObjectID = \"iZc-Xt-NaK\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Yaw factor"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航系数"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航係數"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "偏航係數"
}
}
}
},
"iZL-dA-jk9.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; iZL-dA-jk9.segmentTitles[0] = \"Stereo\"; ObjectID = \"iZL-dA-jk9\";",
"extractionState" : "extracted_with_value",
+24
View File
@@ -1603,6 +1603,18 @@
}
}
},
"dEy-ER-Mb3.text" : {
"comment" : "Class = \"UILabel\"; text = \"Pitch factor\"; ObjectID = \"dEy-ER-Mb3\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Pitch factor"
}
}
}
},
"dJh-Ck-ugh.text" : {
"comment" : "Class = \"UILabel\"; text = \"SensitivityX\"; ObjectID = \"dJh-Ck-ugh\";",
"extractionState" : "extracted_with_value",
@@ -2299,6 +2311,18 @@
}
}
},
"kzC-ut-7DI.text" : {
"comment" : "Class = \"UILabel\"; text = \"Yaw factor\"; ObjectID = \"kzC-ut-7DI\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Yaw factor"
}
}
}
},
"Ldr-kv-d7n.text" : {
"comment" : "Class = \"UILabel\"; text = \"Haptic Engine\"; ObjectID = \"Ldr-kv-d7n\";",
"extractionState" : "extracted_with_value",