new widget, magnifier

This commit is contained in:
True Zhuanjia
2026-04-29 18:43:06 +08:00
parent 5bf8eeb873
commit cf48d4d7c3
21 changed files with 891 additions and 127 deletions
+48 -13
View File
@@ -1372,13 +1372,13 @@
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="nE1-Al-qRc" userLabel="localMousePointerMode Stack">
<rect key="frame" x="18" y="2848" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Local Mouse Cursor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tAd-bm-2IO">
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Local Mouse Cursor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tAd-bm-2IO">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="4FU-iP-c6T" userLabel="Mouse Mode">
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="4FU-iP-c6T" userLabel="Mouse Mode">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Captured"/>
@@ -2680,7 +2680,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="1310"/>
<rect key="frame" x="325" y="156" width="650" height="1346"/>
<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"/>
@@ -3166,8 +3166,41 @@
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="myx-a8-eVV">
<rect key="frame" x="0.0" y="931" width="650" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Animated" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="T3N-f5-q9Y" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="130" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="130" id="2IR-7C-LYj"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" alpha="0.76999998092651367" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="jfo-6M-aEl">
<rect key="frame" x="130" y="0.0" width="220" height="32"/>
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<segments>
<segment title="no"/>
<segment title="yes"/>
</segments>
<color key="tintColor" systemColor="systemGray3Color"/>
<color key="selectedSegmentTintColor" red="0.23087820410000001" green="0.4576539993" blue="0.51765710119999997" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
</segmentedControl>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IVM-Oh-TXR" userLabel="uiLabel">
<rect key="frame" x="350" y="0.0" width="300" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="300" id="cGC-SJ-7f7"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KSh-xS-xfD">
<rect key="frame" x="0.0" y="931" width="650" height="34"/>
<rect key="frame" x="0.0" y="967" 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="yF0-Tu-L8X">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3189,7 +3222,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wxc-0O-tca">
<rect key="frame" x="0.0" y="970" width="650" height="34"/>
<rect key="frame" x="0.0" y="1006" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Border width" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wTH-1Z-Fgh">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3211,7 +3244,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="O0O-pZ-URe" userLabel="Bulk Label Alpha Stack">
<rect key="frame" x="0.0" y="1009" width="650" height="34"/>
<rect key="frame" x="0.0" y="1045" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kSX-ci-kx5">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3233,7 +3266,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rfr-nL-OCc">
<rect key="frame" x="0.0" y="1048" width="650" height="34"/>
<rect key="frame" x="0.0" y="1084" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Border alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sAF-Vy-ZzK">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3255,7 +3288,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="X7d-dV-lHa">
<rect key="frame" x="0.0" y="1087" width="650" height="34"/>
<rect key="frame" x="0.0" y="1123" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Highlight alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1sF-08-aCr">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3277,7 +3310,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nBA-Ii-jNy">
<rect key="frame" x="0.0" y="1126" width="650" height="34"/>
<rect key="frame" x="0.0" y="1162" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Highlight size" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hKK-ro-C5E">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3299,7 +3332,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ASP-yY-swx">
<rect key="frame" x="0.0" y="1165" width="650" height="34"/>
<rect key="frame" x="0.0" y="1201" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Auto dock timer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KKW-Q7-0tg">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3321,7 +3354,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3dC-9Z-wKV">
<rect key="frame" x="0.0" y="1204" width="650" height="34"/>
<rect key="frame" x="0.0" y="1240" width="650" height="34"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Docked alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qFn-D7-7aD">
<rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
@@ -3343,7 +3376,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FEI-wQ-Q3w">
<rect key="frame" x="0.0" y="1243" width="650" height="31"/>
<rect key="frame" x="0.0" y="1279" width="650" height="31"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Collected widgets " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.20000000000000001" translatesAutoresizingMaskIntoConstraints="NO" id="WLg-7a-5wu" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="130" height="31"/>
@@ -3392,7 +3425,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="K9t-Ky-bWg">
<rect key="frame" x="0.0" y="1279" width="650" height="31"/>
<rect key="frame" x="0.0" y="1315" width="650" height="31"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aBW-x7-cFd">
<rect key="frame" x="0.0" y="0.0" width="330" height="31"/>
@@ -3580,6 +3613,8 @@
<size key="freeformSize" width="1300" height="1500"/>
<connections>
<outlet property="addButton" destination="fKN-ja-TRi" id="R2n-QF-aSj"/>
<outlet property="animatedSelector" destination="jfo-6M-aEl" id="7TR-57-TNW"/>
<outlet property="animatedStack" destination="myx-a8-eVV" id="Yia-h0-vCn"/>
<outlet property="autoDockTimerLabel" destination="KKW-Q7-0tg" id="rBe-Kv-6R8"/>
<outlet property="autoDockTimerSlider" destination="5cO-K4-TQ8" id="bly-fH-LA3"/>
<outlet property="autoDockTimerStack" destination="ASP-yY-swx" id="rpi-Kn-8xH"/>
+63 -25
View File
@@ -151,14 +151,14 @@
<rect key="frame" x="0.0" y="0.0" width="1300" height="1800"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jnu-63-bcf" customClass="ToolBarContainerView">
<rect key="frame" x="0.0" y="96" width="1300" height="45"/>
<view contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jnu-63-bcf" customClass="ToolBarContainerView">
<rect key="frame" x="515" y="190" width="410" height="45"/>
<subviews>
<stackView opaque="NO" contentMode="scaleAspectFill" distribution="fillEqually" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="4he-pe-kYB">
<rect key="frame" x="0.0" y="-2.5" width="1300" height="50"/>
<rect key="frame" x="0.0" y="-2.5" width="410" height="50"/>
<subviews>
<button opaque="NO" tag="40" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="fill" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nHH-6h-4D1" userLabel="Exit">
<rect key="frame" x="0.0" y="9.5" width="177" height="31"/>
<rect key="frame" x="0.0" y="9.5" width="50" height="31"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="sBF-hd-nF8"/>
</constraints>
@@ -174,7 +174,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Pdg-l4-BvF" userLabel="Undo">
<rect key="frame" x="187" y="0.0" width="177.5" height="50"/>
<rect key="frame" x="60" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="7KW-Xe-OEK"/>
<constraint firstAttribute="width" constant="50" id="gHD-A0-AVS"/>
@@ -191,7 +191,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rXW-Ms-2cJ" userLabel="Load">
<rect key="frame" x="374.5" y="0.0" width="177" height="50"/>
<rect key="frame" x="120" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="91g-27-mVH"/>
<constraint firstAttribute="height" constant="50" id="kRj-b6-Bx1"/>
@@ -207,7 +207,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LPA-ea-YHC" userLabel="Save">
<rect key="frame" x="561.5" y="0.0" width="177" height="50"/>
<rect key="frame" x="180" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="Lot-pn-o60"/>
<constraint firstAttribute="height" constant="50" id="uWO-So-qxr"/>
@@ -223,7 +223,7 @@
</connections>
</button>
<button opaque="NO" tag="20" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dhG-Fo-0GK" userLabel="Trash">
<rect key="frame" x="748.5" y="0.0" width="177" height="50"/>
<rect key="frame" x="240" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="0vV-wV-Efz"/>
<constraint firstAttribute="width" constant="50" id="j9W-Ja-bVn"/>
@@ -239,7 +239,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Up4-28-sgF" userLabel="Add">
<rect key="frame" x="935.5" y="0.0" width="177.5" height="50"/>
<rect key="frame" x="300" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="rWU-US-9dl"/>
<constraint firstAttribute="width" constant="50" id="wWj-wB-MRd"/>
@@ -254,7 +254,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4pE-po-Zn1" userLabel="Edit">
<rect key="frame" x="1123" y="0.0" width="177" height="50"/>
<rect key="frame" x="360" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="oFn-jm-orG"/>
<constraint firstAttribute="height" constant="50" id="sls-Vh-uxz"/>
@@ -273,7 +273,7 @@
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zll-IP-PFt" userLabel="Chevron View">
<rect key="frame" x="624" y="45" width="52" height="25"/>
<rect key="frame" x="179" y="45" width="52" height="25"/>
<subviews>
<imageView clipsSubviews="YES" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ChevronCompactUp" translatesAutoresizingMaskIntoConstraints="NO" id="76O-3K-aa8">
<rect key="frame" x="0.0" y="0.0" width="52" height="25"/>
@@ -301,8 +301,8 @@
<constraint firstItem="Zll-IP-PFt" firstAttribute="centerX" secondItem="Jnu-63-bcf" secondAttribute="centerX" id="yvK-OU-Gl6"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="BVp-3O-vZ7" userLabel="widgetPanelStack" customClass="WidgetPanelStackView">
<rect key="frame" x="375" y="132" width="550" height="1110"/>
<stackView opaque="NO" contentMode="scaleToFill" misplaced="YES" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="BVp-3O-vZ7" userLabel="widgetPanelStack" customClass="WidgetPanelStackView">
<rect key="frame" x="445" y="226" width="550" height="1137"/>
<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"/>
@@ -876,8 +876,44 @@
<constraint firstAttribute="height" constant="20" id="Vgj-B6-LEU"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t6L-J9-AMW">
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Lb6-lO-56d">
<rect key="frame" x="0.0" y="847" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Animated" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="o1c-Cn-WwN" userLabel="uilabel">
<rect key="frame" x="0.0" y="0.0" width="120" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="120" id="g2O-tG-h9b"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" alpha="0.76999998092651367" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="4Zz-qG-bsx">
<rect key="frame" x="120" y="0.0" width="170" height="21"/>
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<segments>
<segment title="no"/>
<segment title="yes"/>
</segments>
<color key="tintColor" systemColor="systemGray3Color"/>
<color key="selectedSegmentTintColor" red="0.23087820410000001" green="0.4576539993" blue="0.51765710119999997" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
</segmentedControl>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cSB-7c-iRt" userLabel="uiLabel">
<rect key="frame" x="290" y="0.0" width="260" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="260" id="RLb-7I-fhM"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="20" id="LyG-iv-h7W"/>
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t6L-J9-AMW">
<rect key="frame" x="0.0" y="874" width="550" height="20"/>
<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="MgK-KI-3y7">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -899,7 +935,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eem-2H-ekN">
<rect key="frame" x="0.0" y="874" width="550" height="20"/>
<rect key="frame" x="0.0" y="901" width="550" height="20"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Border width" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TFq-Un-O3H">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -921,7 +957,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YB4-fc-lM6">
<rect key="frame" x="0.0" y="901" width="550" height="20"/>
<rect key="frame" x="0.0" y="928" width="550" height="20"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Dr-3c-z61">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -943,7 +979,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8tb-mS-WEu">
<rect key="frame" x="0.0" y="928" width="550" height="20"/>
<rect key="frame" x="0.0" y="955" width="550" height="20"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Border alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eRy-My-vvU">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -965,7 +1001,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cJk-PA-Lp0">
<rect key="frame" x="0.0" y="955" width="550" height="20"/>
<rect key="frame" x="0.0" y="982" width="550" height="20"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Highlight alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Kd-Cc-aYN">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -987,7 +1023,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Sxm-3C-Jlo">
<rect key="frame" x="0.0" y="982" width="550" height="20"/>
<rect key="frame" x="0.0" y="1009" width="550" height="20"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Highlight size" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hme-2d-8d6">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -1009,7 +1045,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BBR-0E-XE9">
<rect key="frame" x="0.0" y="1009" width="550" height="20"/>
<rect key="frame" x="0.0" y="1036" width="550" height="20"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Auto dock timer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="F8T-uC-SAR">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -1031,7 +1067,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="n71-jv-Ziw">
<rect key="frame" x="0.0" y="1036" width="550" height="20"/>
<rect key="frame" x="0.0" y="1063" width="550" height="20"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Docked alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kxI-bn-pRU">
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
@@ -1054,7 +1090,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="weV-Li-Itz">
<rect key="frame" x="0.0" y="1063" width="550" height="20"/>
<rect key="frame" x="0.0" y="1090" width="550" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Collected Widgets " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000000000001" translatesAutoresizingMaskIntoConstraints="NO" id="kek-77-Kmg" userLabel="uilabel">
<rect key="frame" x="0.0" y="0.0" width="120" height="20"/>
@@ -1103,7 +1139,7 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IWg-XO-cff">
<rect key="frame" x="0.0" y="1090" width="550" height="20"/>
<rect key="frame" x="0.0" y="1117" width="550" height="20"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MZj-th-E9Z">
<rect key="frame" x="0.0" y="0.0" width="284" height="20"/>
@@ -1252,6 +1288,8 @@
</view>
<size key="freeformSize" width="1300" height="1800"/>
<connections>
<outlet property="animatedSelector" destination="4Zz-qG-bsx" id="c9f-xU-3wh"/>
<outlet property="animatedStack" destination="Lb6-lO-56d" id="QMO-UJ-fgf"/>
<outlet property="autoDockTimerLabel" destination="F8T-uC-SAR" id="C8g-rg-Wge"/>
<outlet property="autoDockTimerSlider" destination="6hM-ux-n3H" id="vdp-nI-6LZ"/>
<outlet property="autoDockTimerStack" destination="BBR-0E-XE9" id="L9l-bR-MO4"/>
@@ -1940,13 +1978,13 @@
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="IKt-3O-raJ" userLabel="localMousePointerMode Stack">
<rect key="frame" x="0.0" y="2553" width="380" height="56.5"/>
<subviews>
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Local Mouse Cursor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mdA-jF-9Mf">
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Local Mouse Cursor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mdA-jF-9Mf">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="zLl-8w-K8J" userLabel="Mouse Mode">
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="zLl-8w-K8J" userLabel="Mouse Mode">
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
<segments>
<segment title="Captured"/>
+6 -1
View File
@@ -118,7 +118,7 @@ import UIKit
"OSCBACK"
]
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "LSWHEEL", "RSWHEEL", "LTPAD", "RTPAD", "DS4TOUCH", "MOUSEPAD", "ABSMOUSEPAD", "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", "ABSMOUSEPAD", "ABSMOUSE", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL", "DPAD", "TRACKBALL", "WASDPAD", "ARROWPAD", "MAGNIFIER"]
@objc public static let mousePadWithButtonActions: [String] = ["MOUSEPAD", "ABSMOUSE", "ABSMOUSEPAD"]
@objc public static let mousePads: [String] = ["MOUSEPAD", "ABSMOUSE", "TRACKBALL", "ABSMOUSEPAD"]
@objc public static let directionPads: [String] = ["DPAD", "WASDPAD", "ARROWPAD"]
@@ -152,6 +152,11 @@ import UIKit
"DISABLETOUCH",
"GAMEPADOVERLAY",
]
@objc public static let functionalTouchPadCmds: [String] = [
"MAGNIFIER"
]
@objc public static let pencilProButtonCmds: [String] = [
"PENCILHOVER",
"BRUSH",
+2
View File
@@ -62,6 +62,8 @@ typedef NS_ENUM(NSInteger, PencilHoverMode) {
@property (nonatomic, assign) int controllerGyroSwitchToggle;
@property (nonatomic, assign) CGFloat pointerVelocityModeDivider;
@property (nonatomic, assign) CGFloat touchPointerVelocityFactor;
@property (nonatomic, assign) CGPoint normalizedStreamViewOffset;
@property (nonatomic, assign) CGFloat streamViewScale;
@property (nonatomic, assign) bool gamepadOverlayEnabled;
+7 -1
View File
@@ -55,7 +55,8 @@
[encoder encodeInt:self.controllerGyroSwitchToggle forKey:@"controllerGyroSwitchToggle"];
[encoder encodeFloat:self.pointerVelocityModeDivider forKey:@"pointerVelocityModeDivider"];
[encoder encodeFloat:self.touchPointerVelocityFactor forKey:@"touchPointerVelocityFactor"];
[encoder encodeBool:self.gamepadOverlayEnabled forKey:@"gamepadOverlayEnabled"];
[encoder encodeCGPoint:self.normalizedStreamViewOffset forKey:@"normalizedStreamViewOffset"];
[encoder encodeFloat:self.streamViewScale forKey:@"streamViewScale"];
[encoder encodeObject:self.pressureCurvePoints forKey:@"pressureCurvePoints"];
// [encoder encodeObject:self.initialTouchPressureCurvePoints forKey:@"initialTouchPressureCurvePoints"];
@@ -124,6 +125,9 @@
self.pointerVelocityModeDivider = [decoder containsValueForKey:@"pointerVelocityModeDivider"] ? [decoder decodeFloatForKey:@"pointerVelocityModeDivider"] : 0.5;
self.touchPointerVelocityFactor = [decoder containsValueForKey:@"touchPointerVelocityFactor"] ? [decoder decodeFloatForKey:@"touchPointerVelocityFactor"] : 1.0;
self.normalizedStreamViewOffset = [decoder containsValueForKey:@"normalizedStreamViewOffset"] ? [decoder decodeCGPointForKey:@"normalizedStreamViewOffset"] : CGPointZero;
self.streamViewScale = [decoder containsValueForKey:@"streamViewScale"] ? [decoder decodeFloatForKey:@"streamViewScale"] : 1.0;
self.gamepadOverlayEnabled = [decoder containsValueForKey:@"gamepadOverlayEnabled"] ? [decoder decodeBoolForKey:@"gamepadOverlayEnabled"] : false;
self.pressureCurvePoints =
@@ -227,6 +231,8 @@
copy.controllerGyroSwitchToggle = self.controllerGyroSwitchToggle;
copy.pointerVelocityModeDivider = self.pointerVelocityModeDivider;
copy.touchPointerVelocityFactor = self.touchPointerVelocityFactor;
copy.normalizedStreamViewOffset = self.normalizedStreamViewOffset;
copy.streamViewScale = self.streamViewScale;
copy.gamepadOverlayEnabled = self.gamepadOverlayEnabled;
copy.pressureCurvePoints = [[NSMutableArray alloc] initWithArray:self.pressureCurvePoints copyItems:YES];
// copy.initialTouchPressureCurvePoints = [[NSMutableArray alloc] initWithArray:self.initialTouchPressureCurvePoints copyItems:YES];
@@ -471,6 +471,7 @@ static CGRect layoutViewBounds;
buttonState.autoTapInterval = widgetView.autoTapInterval;
buttonState.vibrationStyle = widgetView.vibrationStyle;
buttonState.mouseButtonAction = widgetView.mouseButtonAction;
buttonState.animatesTransition = widgetView.animatesTransition;
buttonState.sensitivityFactorX = widgetView.sensitivityFactorX;
buttonState.sensitivityFactorY = widgetView.sensitivityFactorY;
buttonState.slideThreshold = widgetView.slideThreshold;
@@ -63,6 +63,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) CGFloat highlightAlpha;
@property (nonatomic, assign) uint8_t vibrationStyle;
@property (nonatomic, assign) uint8_t mouseButtonAction;
@property (nonatomic, assign) bool animatesTransition;
@property (nonatomic, assign) uint16_t autoTapInterval;
@property (nonatomic, assign) uint8_t walkKeyActionType;
@@ -46,6 +46,7 @@
[encoder encodeInt:self.sizeReference forKey:@"sizeReference"];
[encoder encodeInt:self.vibrationStyle forKey:@"vibrationStyle"];
[encoder encodeInt:self.mouseButtonAction forKey:@"mouseButtonAction"];
[encoder encodeBool:self.animatesTransition forKey:@"animatesTransition"];
[encoder encodeInt:self.buttonMode forKey:@"slideMode"]; // buttonMode: previously slideMode, keep it for consistency
[encoder encodeInt:self.autoTapInterval forKey:@"autoTapInterval"];
[encoder encodeCGPoint:self.position forKey:@"position"];
@@ -95,6 +96,7 @@
self.sizeReference = [decoder containsValueForKey:@"sizeReference"] ? [decoder decodeIntForKey:@"sizeReference"] : longSide;
self.vibrationStyle = [decoder containsValueForKey:@"vibrationStyle"] ? [decoder decodeIntForKey:@"vibrationStyle"] : UIImpactFeedbackStyleLight;
self.mouseButtonAction = [decoder decodeIntForKey:@"mouseButtonAction"];
self.animatesTransition = [decoder containsValueForKey:@"animatesTransition"] ? [decoder decodeBoolForKey:@"animatesTransition"] : true;
self.buttonMode = [decoder containsValueForKey:@"slideMode"] ? [decoder decodeIntForKey:@"slideMode"] : 0;
self.autoTapInterval = [decoder containsValueForKey:@"autoTapInterval"] ? [decoder decodeIntForKey:@"autoTapInterval"] : 45;
self.position = [decoder decodeCGPointForKey:@"position"];
+139 -51
View File
@@ -47,8 +47,8 @@ import ObjectiveC.runtime
@objc public var motionHandler: MotionHandler?
@objc public weak var functionalButtonDelegate: OnScreenFunctionalButtonDelegate?
@objc protocol OnScreenFunctionalButtonDelegate: AnyObject {
@objc public weak var functionalWidgetDelegate: OnScreenFunctionalWidgetDelegate?
@objc protocol OnScreenFunctionalWidgetDelegate: AnyObject {
func expandSettingsView()
func disconnectRemoteSession()
func disconnectAndQuitApp()
@@ -67,6 +67,14 @@ import ObjectiveC.runtime
func presentPressureCurveVC()
func toggleTouch(disabled:Bool)
func toggleGamepadOverlay(overlayEnabled:Bool)
@objc(magnifierMoveStreamViewWithTranslation:)
func magnifierMoveStreamView(translation: CGVector)
@objc(magnifierMoveStreamViewWithTranslation:pinchDelta:)
func magnifierMoveStreamView(translation: CGVector, pinchDelta: CGFloat)
func setMagnifierViewportInteractionEnabled(_ enabled: Bool)
func resetMagnifierStreamView(animated:Bool)
@objc(restoreMagnifierStreamViewWithOffset:scale:)
func restoreMagnifierStreamView(offset: CGPoint, scale: CGFloat)
}
@objc enum WidgetTypeEnum: UInt8 {
@@ -145,7 +153,7 @@ import ObjectiveC.runtime
// for movable buttons during streaming
@objc public var relocatedDuringStreaming: Bool = false
@objc static var relocatedDuringStreaming: Bool = false
@objc static var profileChangedDuringStreaming: Bool = false
// for all touchPad or buttons hybrid with touchPads
@objc public var hasMinStickOffset: Bool = false
@@ -185,6 +193,10 @@ import ObjectiveC.runtime
@objc public var containsShortcutAction: Bool = false
@objc public var hasNonEditableLabel: Bool = false
@objc public var isMagnifier: Bool = false
private var isFirstTappingMagnifier: Bool = true
@objc public var animatesTransition: Bool = true
// for all stick pads
@objc public var minStickOffset: CGFloat = 0
public let stickMaxOffset: CGFloat = 0x7FFE
@@ -541,6 +553,8 @@ import ObjectiveC.runtime
self.mouseButtonActionDelay = self.cmdString.contains("ABSMOUSEPAD") ? 0.005 : 0
self.standardFoldingInterval = widgetType == .touchPad ? 0.05 : 0.15;
self.isMagnifier = self.cmdString.contains("MAGNIFIER")
}
// ======================================================================================================
@@ -974,7 +988,6 @@ import ObjectiveC.runtime
if CommandManager.stickTouchPads.contains(touchPadString) {setupL3R3Indicator()}
if CommandManager.verticalTouchPads.contains(touchPadString) {setupL3R3Indicator()}
if CommandManager.mousePadWithButtonActions.contains(self.touchPadString) {setupL3R3Indicator()}
if self.hasTrackPoint {setupTrackPoint()}
if self.hasStickIndicator {
if self.crossMarkLayer.superlayer == nil {self.crossMarkLayer = createCrossMark()}
if self.lrudIndicatorBall.superlayer == nil {self.lrudIndicatorBall = createStickBall()}
@@ -1032,18 +1045,8 @@ import ObjectiveC.runtime
@objc var hasTrackPoint: Bool = false
@objc static var trackPointEnabled: Bool = false
private var trackPoint:CAShapeLayer = CAShapeLayer()
@objc public func setupTrackPoint() {
CATransaction.begin()
CATransaction.setDisableActions(true)
// 1. 创建圆形路径
trackPoint.removeFromSuperlayer()
trackPoint = GraphicUtils.makeTouchTrackpoint(in: self)
CATransaction.commit()
}
private var trackPointMapping: [UITouch:CAShapeLayer] = [:]
private var trackPointPool:Set<CAShapeLayer> = Set()
private func showl3r3Indicator(){
if OnScreenWidgetView.buttonVisualFeedbackEnabled {
@@ -1632,7 +1635,6 @@ import ObjectiveC.runtime
}
}
private func handleFingerUpOrSlideout(leaveFunctionalButtonAlone: Bool = false, event: UIEvent? = nil) {
if autoTapInterval < OnScreenWidgetView.MinAutotapInterval {
handleButtonUp(leaveFunctionalButtonAlone:leaveFunctionalButtonAlone, event:event)
@@ -1986,7 +1988,9 @@ import ObjectiveC.runtime
self.tickFlag = 0
super.touchesBegan(touches, with: event)
self.isMultipleTouchEnabled = self.widgetType == WidgetTypeEnum.button || CommandManager.mousePadWithButtonActions.contains(self.touchPadString);
self.isMultipleTouchEnabled = self.widgetType == WidgetTypeEnum.button
|| CommandManager.mousePadWithButtonActions.contains(self.touchPadString)
|| self.touchPadString == "MAGNIFIER"
if !OnScreenWidgetView.editMode && self.touchPadString == "TRACKBALL" {
stopTrackballMomentum()
@@ -2019,7 +2023,7 @@ import ObjectiveC.runtime
self.latestTouchLocation = touchBeganLocation
}
allSpawnedTouchesCount = self.getAllSpawnedTouchesCount(with: event) // this will counts all valid touches within the self widgetView, and excludes touches in other widgetViews
allSpawnedTouchesCount = UITouchUtil.touches(in: self, from: event).count // this will counts all valid touches within the self widgetView, and excludes touches in other widgetViews
if allSpawnedTouchesCount == 2 {
self.twoTouchesDetected = true
}
@@ -2077,6 +2081,15 @@ import ObjectiveC.runtime
self.showl3r3Indicator()
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)
}
case "MAGNIFIER":
if self.isFirstTappingMagnifier, GenericUtils.isFirstTappingMagnifier() {
self.popMagnifierTip()
}
self.isFirstTappingMagnifier = false
if quickDoubleTapDetected && allSpawnedTouchesCount == 1 {
OnScreenWidgetView.profileChangedDuringStreaming = true
self.functionalWidgetDelegate?.resetMagnifierStreamView(animated: self.animatesTransition)
}
default:
break
}
@@ -2125,7 +2138,20 @@ import ObjectiveC.runtime
if self.hasTrackPoint, OnScreenWidgetView.trackPointEnabled {
CATransaction.begin()
CATransaction.setDisableActions(true)
if let touch = touches.first {
let trackPointGap = allSpawnedTouchesCount - trackPointPool.count
if trackPointGap > 0 {
for _ in 0..<trackPointGap {
trackPointPool.insert(GraphicUtils.makeTouchTrackpoint(in: self))
}
}
var trackPointPoolIterator = trackPointPool.makeIterator()
for touch in touches {
guard var trackPoint = trackPointPoolIterator.next() else {continue}
while trackPointMapping.values.contains(trackPoint) {
guard let newTrackPoint = trackPointPoolIterator.next() else {break}
trackPoint = newTrackPoint
}
trackPointMapping[touch] = trackPoint
trackPoint.isHidden = false
trackPoint.position = touch.location(in: self)
}
@@ -2344,15 +2370,14 @@ import ObjectiveC.runtime
}
if self.hasTrackPoint, OnScreenWidgetView.trackPointEnabled {
if let touch = touches.first {
CATransaction.begin()
CATransaction.setDisableActions(true)
if trackPoint.isHidden {
trackPoint.isHidden = false
CATransaction.begin()
CATransaction.setDisableActions(true)
for touch in touches {
if let trackPoint = trackPointMapping[touch] {
trackPoint.position = touch.location(in: self)
}
trackPoint.position = touch.location(in: self)
CATransaction.commit()
}
CATransaction.commit()
}
}
@@ -2515,6 +2540,45 @@ import ObjectiveC.runtime
if self.widgetType == WidgetTypeEnum.touchPad && self.touchPadString == "DS4TOUCH" {
self.handleControllerTouchesMove(touches: touches)
}
if self.widgetType == WidgetTypeEnum.touchPad && self.touchPadString == "MAGNIFIER" {
OnScreenWidgetView.profileChangedDuringStreaming = true
self.handleMagnifierPadMove(touches: touches, event: event)
}
}
private func handleMagnifierPadMove(touches: Set<UITouch>, event: UIEvent?){
guard let event = event else { return }
let currentTouches = Array(UITouchUtil.touches(in: self, from: event))
self.functionalWidgetDelegate?.setMagnifierViewportInteractionEnabled(true)
switch currentTouches.count {
case 1:
guard let touch = currentTouches.first else { return }
var vector = UITouchUtil.vector(of: touch, in: self)
let moveHorizontally = abs(vector.dx) > abs(vector.dy)
vector = CGVector(dx: moveHorizontally ? vector.dx : 0, dy: moveHorizontally ? 0 : vector.dy)
let translation = CGVector(
dx: vector.dx * self.sensitivityFactorX,
dy: vector.dy * self.sensitivityFactorY
)
self.functionalWidgetDelegate?.magnifierMoveStreamView(translation: translation)
case 2:
let touch1 = currentTouches[0]
let touch2 = currentTouches[1]
let translationVector = UITouchUtil.midPointVector(between: touch1, and: touch2, in: self)
let pinchDelta = (UITouchUtil.distance(between: touch1, and: touch2, in: self)
- UITouchUtil.previousDistance(between: touch1, and: touch2, in: self))
let translation = CGVector(
dx: translationVector.dx * self.sensitivityFactorX,
dy: translationVector.dy * self.sensitivityFactorY
)
self.functionalWidgetDelegate?.magnifierMoveStreamView(
translation: translation,
pinchDelta: pinchDelta * self.sensitivityFactorX
)
default:
break
}
}
private func handleMousePadButtonActionUp(touch:UITouch?=nil){
@@ -2646,13 +2710,13 @@ import ObjectiveC.runtime
case "ABSTCHDRAG":
let mouseButton = CommandManager.mouseButtonMappings[Set(self.comboButtonStrings).intersection(CommandManager.mouseButtonMappings.keys).first ?? "MLEFT"] ?? BUTTON_LEFT
print("mouseButton \(mouseButton)");
self.functionalButtonDelegate?.alterAbsTouchDragWith(mouseButton:mouseButton)
self.functionalWidgetDelegate?.alterAbsTouchDragWith(mouseButton:mouseButton)
case "PENCILHOVER":
if !self.isPencilProEnabled() {break}
self.functionalButtonDelegate?.enablePencilHover()
self.functionalWidgetDelegate?.enablePencilHover()
case "NOSINGLETOUCH":
if !self.isPencilProEnabled() {break}
self.functionalButtonDelegate?.setAllowSingleTouchEnabled(false)
self.functionalWidgetDelegate?.setAllowSingleTouchEnabled(false)
default:
break
}
@@ -2677,7 +2741,7 @@ import ObjectiveC.runtime
case "NOSINGLETOUCH":
if !self.isPencilProEnabled() {break}
singleTouchEnabled = !singleTouchEnabled
self.functionalButtonDelegate?.setAllowSingleTouchEnabled(singleTouchEnabled)
self.functionalWidgetDelegate?.setAllowSingleTouchEnabled(singleTouchEnabled)
return
default:
break
@@ -2691,61 +2755,61 @@ import ObjectiveC.runtime
case "SETTINGS":
temporaryDisableFolderButtonAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.functionalButtonDelegate?.expandSettingsView()
self.functionalWidgetDelegate?.expandSettingsView()
}
case "DISCONNECT":
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.functionalButtonDelegate?.disconnectRemoteSession()
self.functionalWidgetDelegate?.disconnectRemoteSession()
}
case "QUITAPP":
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.functionalButtonDelegate?.disconnectAndQuitApp()
self.functionalWidgetDelegate?.disconnectAndQuitApp()
}
case "TOOLBOX":
self.functionalButtonDelegate?.bringUpToolboxMenu()
self.functionalWidgetDelegate?.bringUpToolboxMenu()
case "PIP":
self.functionalButtonDelegate?.enterPip()
self.functionalWidgetDelegate?.enterPip()
case "WIDGETTOOL":
temporaryDisableFolderButtonAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.functionalButtonDelegate?.openWidgetLayoutTool()
self.functionalWidgetDelegate?.openWidgetLayoutTool()
}
case "PROFILES","WIDGETPROFILES":
temporaryDisableFolderButtonAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.functionalButtonDelegate?.openWidgetProfileTable(pickProfile: false)
self.functionalWidgetDelegate?.openWidgetProfileTable(pickProfile: false)
}
case "PICKPROFILE","PICKPRFL":
temporaryDisableFolderButtonAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.functionalButtonDelegate?.openWidgetProfileTable(pickProfile: true)
self.functionalWidgetDelegate?.openWidgetProfileTable(pickProfile: true)
}
case "SOFTKEYBOARD":
self.functionalButtonDelegate?.bringUpSoftKeyboard()
self.functionalWidgetDelegate?.bringUpSoftKeyboard()
case "ABSTCHDRAG":
self.functionalButtonDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
self.functionalWidgetDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
case "PENCILHOVER":
if !self.isPencilProEnabled() {break}
self.functionalButtonDelegate?.disablePencilHover()
self.functionalWidgetDelegate?.disablePencilHover()
case "NOSINGLETOUCH":
if !self.isPencilProEnabled() {break}
self.functionalButtonDelegate?.setAllowSingleTouchEnabled(true)
self.functionalWidgetDelegate?.setAllowSingleTouchEnabled(true)
case "BRUSH":
if !self.isPencilProEnabled() {break}
var brushShortcut = self.cmdString.replacingOccurrences(of: "BRUSH+", with: "")
brushShortcut = brushShortcut.replacingOccurrences(of: "BRUSH", with: "")
self.functionalButtonDelegate?.replaceBrush(shortcut: brushShortcut)
self.functionalWidgetDelegate?.replaceBrush(shortcut: brushShortcut)
case "ERASER":
if !self.isPencilProEnabled() {break}
var eraserShortcut = self.cmdString.replacingOccurrences(of: "ERASER+", with: "")
eraserShortcut = eraserShortcut.replacingOccurrences(of: "ERASER", with: "")
self.functionalButtonDelegate?.replaceEraser(shortcut: eraserShortcut)
self.functionalWidgetDelegate?.replaceEraser(shortcut: eraserShortcut)
case "PRESSURECURVE":
if ["com.voidlink.iOS"
, "com.voidlinkextreme.iOS"
, "com.voidlink.tf.debug10.iOS"
].contains(Bundle.main.bundleIdentifier) && GenericUtils.isIPad() {
self.functionalButtonDelegate?.presentPressureCurveVC()
self.functionalWidgetDelegate?.presentPressureCurveVC()
}
case "DISABLETOUCH":
self.handleTouchDisableButtonUp()
@@ -2760,7 +2824,7 @@ import ObjectiveC.runtime
private func handleTouchDisableButtonUp(){
touchDisabledFLag = !touchDisabledFLag
self.setupAtrributedText()
self.functionalButtonDelegate?.toggleTouch(disabled: touchDisabledFLag)
self.functionalWidgetDelegate?.toggleTouch(disabled: touchDisabledFLag)
}
@objc static var gamepadOverlayFLag:Bool = false
@@ -2769,7 +2833,7 @@ import ObjectiveC.runtime
OnScreenWidgetView.gamepadOverlayFLag = !OnScreenWidgetView.gamepadOverlayFLag
self.setupAtrributedText()
if #available(iOS 13.0, *) {
self.functionalButtonDelegate?.toggleGamepadOverlay(overlayEnabled: OnScreenWidgetView.gamepadOverlayFLag)
self.functionalWidgetDelegate?.toggleGamepadOverlay(overlayEnabled: OnScreenWidgetView.gamepadOverlayFLag)
}
}
@@ -2920,6 +2984,8 @@ import ObjectiveC.runtime
self.onScreenControls?.releaseControllerButton(DOWN_FLAG)
case "DS4TOUCH":
self.handleControllerTouchesUp(touches: touches)
case "MAGNIFIER":
self.functionalWidgetDelegate?.setMagnifierViewportInteractionEnabled(false)
default:
break
}
@@ -2975,7 +3041,15 @@ import ObjectiveC.runtime
}
if self.hasTrackPoint, OnScreenWidgetView.trackPointEnabled {
trackPoint.isHidden = true
CATransaction.begin()
CATransaction.setDisableActions(true)
for touch in touches {
if let trackPoint = trackPointMapping[touch] {
trackPointMapping.removeValue(forKey: touch)
trackPoint.isHidden = true
}
}
CATransaction.commit()
}
self.temporarilyMovable = false
@@ -3136,6 +3210,18 @@ import ObjectiveC.runtime
return true
}
private func popMagnifierTip() {
AlertControllerUtil.showAlert(
in: self.parentViewController,
title: SwiftLocalizationHelper.localizedString(forKey: "Magnifier"),
message: "\n\(SwiftLocalizationHelper.localizedString(forKey: "magnifierTip"))\n\n\(SwiftLocalizationHelper.localizedString(forKey: "magnifierPersistTip"))",
withCancel: false,
buttonTitle: SwiftLocalizationHelper.localizedString(forKey: "Got it!"),
countdown: 5,
)
}
// MARK: - Auto Dock
private static let autoDockExposedEdgeLength: CGFloat = GenericUtils.isIPhone() ? 90 : 90
private static let autoDockExposedThickness: CGFloat = 22
@@ -3698,10 +3784,12 @@ import ObjectiveC.runtime
if self.widgetType == WidgetTypeEnum.button && !OnScreenWidgetView.editMode {
self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings)
self.functionalButtonDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
self.functionalWidgetDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
}
buttonDownVisualEffectLayer.removeFromSuperlayer()
trackPoint.removeFromSuperlayer()
for trackPoint in trackPointPool {
trackPoint.removeFromSuperlayer()
}
crossMarkLayer.removeFromSuperlayer()
lrudIndicatorBall.removeFromSuperlayer()
l3r3Indicator.removeFromSuperlayer()
+1 -1
View File
@@ -62,7 +62,7 @@
andConfig:(StreamConfiguration*)streamConfig;
- (void) clearOnScreenWidgets;
- (void) reloadGameProfile:(OSCProfile* )profile reloadWidgets:(bool)reloadWidgets;
- (void) saveStreamViewWidgetChanges;
- (void) saveStreamingGameProfileChanges;
- (bool) isOnScreenWidgetEnabled;
- (CGSize) getVideoAreaSize;
+12 -5
View File
@@ -619,7 +619,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
else return longSide;
}
- (void)saveStreamViewWidgetChanges{
- (void)saveStreamingGameProfileChanges{
/*
NSMutableDictionary* relocatedWidgetDict = [NSMutableDictionary dictionary];
@@ -640,7 +640,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
if(!hasFolderStateChanged) hasFolderStateChanged = widget.folded != widget.persistedFolded;
}
if(relocatedWidgetSequences.count == 0 && !hasFolderStateChanged && !OnScreenWidgetView.relocatedDuringStreaming) return;
if(relocatedWidgetSequences.count == 0 && !hasFolderStateChanged && !OnScreenWidgetView.profileChangedDuringStreaming) return;
NSLog(@"relocatedWidgetSequences.count %lu, hasFolderStateChanged %d %F", relocatedWidgetSequences.count, hasFolderStateChanged, CACurrentMediaTime());
oscProfileMan = [OSCProfilesManager sharedManager:self->_streamFrameTopLayerView.bounds];
@@ -660,9 +660,13 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
}
}
StreamFrameViewController* streamFrameVC = (StreamFrameViewController*)_streamFrameVC;
newProfile.unfoldedExclusiveFolderSequence = OnScreenWidgetView.unfoldedExclusiveFolderSequence;
newProfile.postExclusiveUnfoldedSequences = OnScreenWidgetView.postExclusiveUnfoldedSequences;
newProfile.gamepadOverlayEnabled = ((StreamFrameViewController*)_streamFrameVC).virtualGamepadOverlay != nil;
newProfile.gamepadOverlayEnabled = streamFrameVC.virtualGamepadOverlay != nil;
newProfile.normalizedStreamViewOffset = CGPointMake(streamFrameVC.streamViewMagnifierContentOffset.x/self.bounds.size.width, streamFrameVC.streamViewMagnifierContentOffset.y/self.bounds.size.height);
newProfile.streamViewScale = streamFrameVC.streamViewMagnifierZoomScale;
[oscProfileMan replaceSelectedProfileWith:newProfile overwriteDefault:YES];
}
@@ -693,7 +697,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
OnScreenWidgetView.buttonVisualFeedbackEnabled = self->settings.buttonVisualFeedback;
OnScreenWidgetView.gamepadOverlayFLag = profile.gamepadOverlayEnabled;
OnScreenWidgetView.relocatedDuringStreaming = false;
OnScreenWidgetView.profileChangedDuringStreaming = false;
bool hasLegacyWidget = false;
if(reloadWidgets && !OnScreenWidgetView.editMode){
@@ -709,7 +713,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
if(buttonState.widgetType == CustomOnScreenWidget){
OnScreenWidgetView* widgetView = [OnScreenWidgetView widgetWithCmdString:buttonState.name buttonLabel:buttonState.alias shape:buttonState.widgetShape profile:profile]; //reconstruct widgetView
widgetView.functionalButtonDelegate = (id<OnScreenFunctionalButtonDelegate>)self->_streamFrameVC;
widgetView.functionalWidgetDelegate = (id<OnScreenFunctionalWidgetDelegate>)self->_streamFrameVC;
widgetView.motionHandler = motionHandler;
widgetView.sequence = buttonState.sequence == -1 ? i : buttonState.sequence;
@@ -735,6 +739,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
widgetView.autoTapInterval = buttonState.autoTapInterval;
[widgetView setVibrationWithStyle:buttonState.vibrationStyle];
widgetView.mouseButtonAction = buttonState.mouseButtonAction;
widgetView.animatesTransition = buttonState.animatesTransition;
widgetView.sensitivityFactorX = buttonState.sensitivityFactorX;
widgetView.sensitivityFactorY = buttonState.sensitivityFactorY;
widgetView.slideThreshold = buttonState.slideThreshold;
@@ -827,6 +832,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
if(reloadWidgets && !OnScreenWidgetView.editMode){
[PencilHandler.shared setupPressureLUTWithProfile:profile];
}
[(StreamFrameViewController* )self->_streamFrameVC restorePersistedStreamViewOffsetAndScaleWithProfile:profile];
});
}
+82 -1
View File
@@ -7026,7 +7026,7 @@
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "\nVoidLink 桌面模式快捷键:\n\nCtrl + Alt + Shift + D — 断开当前会话\n\nCtrl + Alt + Shift + Q — 断开当前会话并退出当前app\n\nCtrl + Alt + Shift + S — 展开设置菜单\n\nCtrl + Alt + Shift + O — 切换性能信息叠加\n\nCtrl + Alt + Shift + C — 切换鼠标指针可见性\n\n默认状态下鼠标无法在3D游戏中转动视角。如需串流游戏,请断开当前会话,前往设置菜单 -> 外设分区 -> 本地鼠标指针,选择“被窗口捕获”。"
}
},
@@ -7044,6 +7044,87 @@
}
}
},
"Magnifier" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "放大镜"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "放大鏡"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "放大鏡"
}
}
}
},
"magnifierPersistTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stream view offset & scale are saved in the game profile."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流视图的偏移和放大倍数保存在 [游戏配置] 中."
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流視圖的偏移和放大倍率保存在 [遊戲配置] 中。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流視圖的偏移和放大倍率保存在 [遊戲配置] 中。"
}
}
}
},
"magnifierTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Single touch pans stream view; two-finger pinch zooms stream view. Double tap to reset."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "单指平移/竖移串流视图,双指捏合缩放串流视图。双击复原串流视图。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "單指平移/豎移串流視圖,雙指捏合縮放串流視圖。雙擊復原串流視圖。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "單指平移/豎移串流視圖,雙指捏合縮放串流視圖。雙擊復原串流視圖。"
}
}
}
},
"Manual_Add_Host_Fail" : {
"extractionState" : "manual",
"localizations" : {
+12
View File
@@ -88,6 +88,18 @@ import UIKit
}
return false
}
@objc static func isFirstTappingMagnifier() -> Bool {
let key = "hasFirstTappingMagnifier2"
let defaults = UserDefaults.standard
let launchedBefore = defaults.bool(forKey: key)
if !launchedBefore {
defaults.set(true, forKey: key)
return true
}
return false
}
@objc static func isFirstTappingInputAccessoryBar() -> Bool {
let key = "isFirstTappingInputAccessoryBar"
@@ -174,6 +174,9 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
@IBOutlet weak var walkKeyThresholdLabel: UILabel!
@IBOutlet weak var walkKeyThresholdSlider: UISlider!
@IBOutlet weak var animatedStack: UIStackView!
@IBOutlet weak var animatedSelector: UISegmentedControl!
@IBOutlet weak var widgetPanelStack: UIStackView!
@IBOutlet private weak var toolbarTopConstraintiPhone: NSLayoutConstraint!
@@ -278,7 +281,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(legacyOscLayerTapped(_:)), name: Notification.Name("LegacyOscCALayerSelectedNotification"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleProfileTablViewDismiss), name: Notification.Name("OscLayoutTableViewCloseNotification"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(dummytest), name: Notification.Name("OscLayoutProfileSelctedInTableView"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(dummytest), name: Notification.Name("GameProfileSelectedNotification"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(widgetViewTapped(_:)), name: Notification.Name("OnScreenWidgetViewSelected"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(OSCLayoutChanged), name: Notification.Name("OSCLayoutChanged"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleReturnToForeground), name: UIApplication.didBecomeActiveNotification, object: nil)
@@ -312,7 +315,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widget.updateMovementThresholdPreview()
}
super.viewWillDisappear(animated)
NotificationCenter.default.post(name: Notification.Name("OscLayoutCloseNotification"), object: self)
NotificationCenter.default.post(name: Notification.Name("GameProfileSelectorCloseNotification"), object: self)
}
@objc func dummytest() {}
@@ -357,6 +360,8 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
guard let oscProfile = self.profilesManager?.getSelectedProfile() else { return }
NotificationCenter.default.post(name: Notification.Name("GameProfileSelectedNotification"), object: oscProfile)
self.loadWidgets(from: oscProfile)
if !self.quickSwitchEnabled {
@@ -400,6 +405,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widgetView.autoTapInterval = Int(buttonState.autoTapInterval)
widgetView.setVibration(style: Int(buttonState.vibrationStyle))
widgetView.mouseButtonAction = MouseButtonAction(rawValue: Int(buttonState.mouseButtonAction)) ?? .hovering
widgetView.animatesTransition = buttonState.animatesTransition
widgetView.sensitivityFactorX = buttonState.sensitivityFactorX
widgetView.sensitivityFactorY = buttonState.sensitivityFactorY
widgetView.slideThreshold = buttonState.slideThreshold
@@ -957,8 +963,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
mouseDownButtonStack.isHidden = !widgetView.isMousePadWithButtonActions
mouseButtonDownSelector.selectedSegmentIndex = Int(widgetView.mouseButtonAction.rawValue)
animatedStack.isHidden = !widgetView.isMagnifier
animatedSelector.selectedSegmentIndex = widgetView.animatesTransition ? 1 : 0
autoDockTimerStack.isHidden = !(widgetView.isFolder && widgetView.parentSequence == -1);
autoDockTimerSlider.value = Float(widgetView.autoDockIdleDuration)
autoDockTimerSliderMoved(autoDockTimerSlider)
@@ -1217,6 +1225,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
newWidget.minStickOffset = widget.minStickOffset
newWidget.setVibration(style: Int(widget.vibrationStyle))
newWidget.mouseButtonAction = widget.mouseButtonAction
newWidget.animatesTransition = widget.animatesTransition
newWidget.buttonMode = widget.buttonMode
newWidget.sprintKeyActionType = widget.sprintKeyActionType
newWidget.sprintKeyThreshold = widget.sprintKeyThreshold
@@ -1770,6 +1779,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
stickIndicatorOffsetLabel.text = LocalizationHelper.localizedString(forKey: "Indicator offset")
stickIndicatorOffsetStack.isHidden = true
autoDockTimerSlider.addTarget(self, action: #selector(autoDockTimerSliderMoved(_:)), for: .valueChanged)
autoDockTimerLabel.text = LocalizationHelper.localizedString(forKey: "Auto dock")
autoDockTimerStack.isHidden = true;
@@ -1782,6 +1792,11 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
mouseButtonDownSelector.addTarget(self, action: #selector(mouseDownButtonChanged(_:)), for: .valueChanged)
mouseButtonDownSelector.setTitleTextAttributes(whiteAttrs, for: .normal)
mouseDownButtonStack.isHidden = true
animatedSelector.addTarget(self, action: #selector(animationChanged(_:)), for: .valueChanged)
animatedSelector.setTitleTextAttributes(whiteAttrs, for: .normal)
animatedStack.isHidden = true
buttonModeSelector.addTarget(self, action: #selector(buttonModeChanged(_:)), for: .valueChanged)
buttonModeSelector.setTitleTextAttributes(whiteAttrs, for: .normal)
buttonModeStack.isHidden = true
@@ -2105,6 +2120,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
return
}
@objc private func animationChanged(_ sender: UISegmentedControl) {
selectedWidgetView?.animatesTransition = sender.selectedSegmentIndex == 1
}
@objc private func mouseDownButtonChanged(_ sender: UISegmentedControl) {
selectedWidgetView?.mouseButtonAction = MouseButtonAction(rawValue: sender.selectedSegmentIndex) ?? .hovering
}
@@ -254,7 +254,6 @@ final class OSCProfilesTableViewController: UIViewController, UITableViewDelegat
func profileViewRefresh() {
tableView.reloadData()
needToUpdateOscLayoutTVC?()
NotificationCenter.default.post(name: Notification.Name("OscLayoutProfileSelctedInTableView"), object: self)
}
@IBAction func deleteTapped(_ sender: Any?) {
@@ -503,11 +503,11 @@ BOOL isCustomResolution(int resolutionSelected) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadGameProfileConfigs)
name:@"OscLayoutCloseNotification"
name:@"GameProfileSelectorCloseNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadGameProfileConfigs)
name:@"OscLayoutProfileSelctedInTableView"
name:@"GameProfileSelectedNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -28,7 +28,7 @@
@interface StreamFrameViewController : GCEventViewController <ConnectionCallbacks, ControllerSupportDelegate, UserInteractionDelegate, UIScrollViewDelegate, AVPictureInPictureControllerDelegate>
#else
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks, ControllerSupportDelegate, UserInteractionDelegate, UIScrollViewDelegate, ToolboxSpecialEntryDelegate, AVPictureInPictureControllerDelegate, OnScreenFunctionalButtonDelegate, AbstractGamepadOverlayCloseButtonDelegate>
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks, ControllerSupportDelegate, UserInteractionDelegate, UIScrollViewDelegate, ToolboxSpecialEntryDelegate, AVPictureInPictureControllerDelegate, OnScreenFunctionalWidgetDelegate, AbstractGamepadOverlayCloseButtonDelegate>
#endif
@property (nonatomic, strong) StreamManager* streamMan;
@@ -43,6 +43,10 @@
@property (nonatomic, strong) ImGuiRenderer *imguiView;
@property (nonatomic, strong) UIView* virtualGamepadOverlay;
@property (nonatomic, assign) CGPoint streamViewMagnifierContentOffset;
@property (nonatomic, assign) CGFloat streamViewMagnifierZoomScale;
- (void)updatePreferredDisplayMode:(BOOL)streamActive;
- (void)setUserInteractionEnabledForStreamView:(bool)enabled;
@@ -50,5 +54,6 @@
- (void)loadGameProfileConfigs:(OSCProfile* )profile;
- (void)toggleGamepadOverlayWithOverlayEnabled:(BOOL)overlayEnabled API_AVAILABLE(ios(13.0));
- (void)loadAbstractGamepadOverlayIfNeeded API_AVAILABLE(ios(13.0));
- (void)restorePersistedStreamViewOffsetAndScaleWithProfile:(OSCProfile* )profile;
@end
@@ -62,6 +62,7 @@
UIActivityIndicatorView *_spinner;
StreamView *_streamView;
UIScrollView *_scrollView;
BOOL _magnifierViewportInteractionActive;
BOOL _userIsInteracting;
bool viewIsBeingResized;
bool previousOnScreenWidgetEnabled;
@@ -313,9 +314,140 @@
}
- (BOOL)currentProfileContainsMagnifierWidget {
OSCProfilesManager *profileManager = [OSCProfilesManager sharedManager:CGRectZero];
for (NSData *buttonStateEncoded in _oscProfile.buttonStatesEncoded) {
OnScreenButtonState *buttonState = [profileManager unarchiveButtonStateEncoded:buttonStateEncoded];
if (buttonState.widgetType == CustomOnScreenWidget &&
[buttonState.name containsString:@"MAGNIFIER"]) {
return YES;
}
}
return NO;
}
- (BOOL)shouldWrapStreamViewInScrollView {
return YES;
}
- (UIView *)streamContentContainerView {
if (_scrollView && _streamView.superview == _scrollView && _scrollView.superview == self.view) {
return _scrollView;
}
return _streamView;
}
- (void)syncMagnifierStateFromScrollView {
if (!_scrollView) {
_streamViewMagnifierContentOffset = CGPointZero;
_streamViewMagnifierZoomScale = 1.0f;
return;
}
_streamViewMagnifierContentOffset = _scrollView.contentOffset;
_streamViewMagnifierZoomScale = _scrollView.zoomScale;
}
- (UIEdgeInsets)magnifierViewportInsets {
if (!_scrollView) {
return UIEdgeInsetsZero;
}
CGSize contentSize = _scrollView.contentSize;
CGSize boundsSize = _scrollView.bounds.size;
CGFloat insetX = MAX(boundsSize.width - contentSize.width * 0.1f, 0.0f);
CGFloat insetY = MAX(boundsSize.height - contentSize.height * 0.1f, 0.0f);
return UIEdgeInsetsMake(insetY, insetX, insetY, insetX);
}
- (CGPoint)clampedMagnifierContentOffset:(CGPoint)candidateOffset {
if (!_scrollView) {
return CGPointZero;
}
UIEdgeInsets insets = _scrollView.contentInset;
CGFloat minOffsetX = -insets.left;
CGFloat minOffsetY = -insets.top;
CGFloat maxOffsetX = MAX(_scrollView.contentSize.width - CGRectGetWidth(_scrollView.bounds) + insets.right, minOffsetX);
CGFloat maxOffsetY = MAX(_scrollView.contentSize.height - CGRectGetHeight(_scrollView.bounds) + insets.bottom, minOffsetY);
candidateOffset.x = MIN(MAX(candidateOffset.x, minOffsetX), maxOffsetX);
candidateOffset.y = MIN(MAX(candidateOffset.y, minOffsetY), maxOffsetY);
return candidateOffset;
}
- (void)updateMagnifierViewportMetrics {
if (!_scrollView) {
return;
}
_scrollView.contentInset = [self magnifierViewportInsets];
_scrollView.contentOffset = [self clampedMagnifierContentOffset:_scrollView.contentOffset];
}
- (void)updateScrollViewInteractionState {
if (!_scrollView) {
return;
}
BOOL interactionEnabled = _magnifierViewportInteractionActive;
_scrollView.scrollEnabled = interactionEnabled;
_scrollView.panGestureRecognizer.enabled = interactionEnabled;
_scrollView.pinchGestureRecognizer.enabled = interactionEnabled;
}
- (void)resetMagnifierTransformState {
if (_scrollView) {
[_scrollView setZoomScale:1.0f animated:NO];
_scrollView.contentOffset = CGPointZero;
}
_streamViewMagnifierContentOffset = CGPointZero;
_streamViewMagnifierZoomScale = 1.0f;
_magnifierViewportInteractionActive = NO;
}
- (void)applyMagnifierTranslation:(CGVector)translation pinchDelta:(CGFloat)pinchDelta {
if (![NSThread isMainThread]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self applyMagnifierTranslation:translation pinchDelta:pinchDelta];
});
return;
}
if (!_scrollView || _streamView.superview != _scrollView) {
return;
}
CGFloat previousZoomScale = MAX(_scrollView.zoomScale, _scrollView.minimumZoomScale);
CGPoint visibleCenter = CGPointMake(_scrollView.contentOffset.x + CGRectGetWidth(_scrollView.bounds) * 0.5f,
_scrollView.contentOffset.y + CGRectGetHeight(_scrollView.bounds) * 0.5f);
CGFloat targetZoomScale = previousZoomScale;
if (fabs(pinchDelta) > 0.0001f) {
targetZoomScale += pinchDelta / 240.0f;
targetZoomScale = MIN(MAX(targetZoomScale, _scrollView.minimumZoomScale), _scrollView.maximumZoomScale);
}
if (fabs(targetZoomScale - previousZoomScale) > 0.0001f) {
CGFloat zoomRatio = targetZoomScale / previousZoomScale;
[_scrollView setZoomScale:targetZoomScale animated:NO];
visibleCenter = CGPointMake(visibleCenter.x * zoomRatio, visibleCenter.y * zoomRatio);
}
CGPoint targetOffset = CGPointMake(visibleCenter.x - CGRectGetWidth(_scrollView.bounds) * 0.5f - translation.dx,
visibleCenter.y - CGRectGetHeight(_scrollView.bounds) * 0.5f - translation.dy);
[self updateMagnifierViewportMetrics];
_scrollView.contentOffset = [self clampedMagnifierContentOffset:targetOffset];
[self syncMagnifierStateFromScrollView];
}
- (void)configZoomGestureAndAddStreamView{
if (_settings.touchMode.intValue == AbsoluteTouch && !_settings.passthroughGestures) {
BOOL shouldWrapInScrollView = [self shouldWrapStreamViewInScrollView];
if (shouldWrapInScrollView) {
if(!_scrollView) _scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
_scrollView.frame = self.view.bounds;
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
#if !TARGET_OS_TV
[_scrollView.panGestureRecognizer setMinimumNumberOfTouches:2];
[_scrollView.panGestureRecognizer setMaximumNumberOfTouches:2]; // reduce competing with keyboardToggleRecognizer in StreamView.
@@ -323,22 +455,37 @@
[_scrollView setShowsHorizontalScrollIndicator:NO];
[_scrollView setShowsVerticalScrollIndicator:NO];
[_scrollView setDelegate:self];
[_scrollView setMaximumZoomScale:_settings.passthroughGestures ? 1.0 : 10.0f];
[_scrollView setBackgroundColor:UIColor.blackColor];
[_scrollView setClipsToBounds:YES];
[_scrollView setBouncesZoom:NO];
[_scrollView setMinimumZoomScale:0.1f];
[_scrollView setMaximumZoomScale:10.0f];
if(!_mainFrameViewcontroller.settingsExpandedInStreamView){
// Add StreamView inside a UIScrollView for absolute mode
[_scrollView addSubview:_streamView];
// Insert at index 0 to ensure it doesn't cover OSC controls (CALayers)
[self.view insertSubview:_scrollView atIndex:0];
if (_streamView.superview != _scrollView) {
[_streamView removeFromSuperview];
_streamView.frame = _scrollView.bounds;
[_scrollView addSubview:_streamView];
}
if (_scrollView.superview != self.view) {
[self.view insertSubview:_scrollView atIndex:0];
} else {
[self.view sendSubviewToBack:_scrollView];
}
}
_scrollView.panGestureRecognizer.enabled = !_settings.passthroughGestures;
if (_streamViewMagnifierZoomScale < _scrollView.minimumZoomScale) {
_streamViewMagnifierZoomScale = 1.0f;
}
[_scrollView setZoomScale:_streamViewMagnifierZoomScale animated:NO];
_scrollView.contentOffset = _streamViewMagnifierContentOffset;
[self updateMagnifierViewportMetrics];
[self syncMagnifierStateFromScrollView];
}
else{
// Add streamView directly to self.view in other touch modes
// Insert at index 0 to ensure it doesn't cover OSC controls (CALayers)
if([_streamView.superview isKindOfClass:[UIScrollView class]]){
[self resetMagnifierTransformState];
[_streamView removeFromSuperview];
}
[_scrollView removeFromSuperview];
[self.view insertSubview:_streamView atIndex:0];
}
}
@@ -436,7 +583,7 @@
}
// StreamView should also be at the back so OSC CALayers on self.view show
if (self->_streamView && self->_streamView.superview) {
[self.view sendSubviewToBack:self->_streamView];
[self.view sendSubviewToBack:[self streamContentContainerView]];
}
// ImGui view should be on top for debug graphs
if (self.imguiView && self.imguiView.mtkView.superview) {
@@ -463,6 +610,8 @@
TouchPadGestureHandler.scrollSensitivity = _settings.scrollSensitivity.floatValue;
TouchPadGestureHandler.pinchSensitivity = _settings.pinchSensitivity.floatValue;
TouchPadGestureHandler.displayLinkRate = _settings.framerate.intValue;
[self setMagnifierViewportInteractionEnabled:_settings.touchMode.intValue == AbsoluteTouch && !_settings.passthroughGestures];
NSLog(@"frameview gestures: %d", (uint32_t)[self.view.gestureRecognizers count]);
NSLog(@"streamview gestures: %d", (uint32_t)[_streamView.gestureRecognizers count]);
@@ -524,6 +673,14 @@
#if !TARGET_OS_TV
[[self revealViewController] setPrimaryViewController:self];
[self restorePersistedStreamViewOffsetAndScaleWithProfile:_oscProfile];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateContentOffsetAndScale:)
name:@"GameProfileSelectedNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reConfigStreamViewRealtime) // reconfig streamview when settings view is closed in stream view
name:@"SettingsViewClosedNotification"
@@ -560,6 +717,7 @@
object:nil];
[safeTimer start];
#endif
}
@@ -608,6 +766,8 @@
{
_viewJustLoaded = true;
viewIsBeingResized = false;
_magnifierViewportInteractionActive = false;
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES animated:YES];
@@ -642,6 +802,9 @@
_inactivityTimer = nil;
_streamView = [[StreamView alloc] initWithFrame:self.view.frame];
_streamViewMagnifierContentOffset = CGPointZero;
_streamViewMagnifierZoomScale = 1.0f;
_magnifierViewportInteractionActive = NO;
toolBoxViewController = [[ToolboxViewController alloc] init];
toolBoxViewController.specialEntryDelegate = self;
@@ -722,8 +885,8 @@
object: nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(oscLayoutClosed)
name:@"OscLayoutCloseNotification"
selector:@selector(gameProfileSelectorClosed)
name:@"GameProfileSelectorCloseNotification"
object:nil];
#if 0
@@ -792,7 +955,7 @@
}
- (void)openWidgetLayoutTool{
[_streamView saveStreamViewWidgetChanges];
[_streamView saveStreamingGameProfileChanges];
_streamView.widgetToolOpened = true;
[self->_streamView disableOnScreenControls];
[self->_streamView clearOnScreenWidgets]; // clear all onScreenKeyboardButtons before entering edit mode
@@ -803,7 +966,7 @@
}
- (void)openWidgetProfileTableWithPickProfile:(BOOL)pickProfile{
[_streamView saveStreamViewWidgetChanges];
[_streamView saveStreamingGameProfileChanges];
_streamView.widgetToolOpened = true;
[self->_streamView disableOnScreenControls];
[self->_streamView clearOnScreenWidgets]; // clear all onScreenKeyboardButtons before entering edit mode
@@ -828,7 +991,79 @@
[_streamView alterAbsTouchDragWith:mouseButton];
}
- (void)oscLayoutClosed{
- (void)magnifierMoveStreamViewWithTranslation:(CGVector)translation {
_magnifierViewportInteractionActive = YES;
[self updateScrollViewInteractionState];
[self applyMagnifierTranslation:translation pinchDelta:0.0f];
}
- (void)magnifierMoveStreamViewWithTranslation:(CGVector)translation pinchDelta:(CGFloat)pinchDelta {
_magnifierViewportInteractionActive = YES;
[self updateScrollViewInteractionState];
[self applyMagnifierTranslation:translation pinchDelta:pinchDelta];
}
- (void)setMagnifierViewportInteractionEnabled:(BOOL)enabled {
_magnifierViewportInteractionActive = enabled;
[self updateScrollViewInteractionState];
}
- (void)updateContentOffsetAndScale:(NSNotification*)notification {
OSCProfile* profile = (OSCProfile* ) notification.object;
[self restorePersistedStreamViewOffsetAndScaleWithProfile:profile];
}
- (void)restorePersistedStreamViewOffsetAndScaleWithProfile:(OSCProfile* )profile {
if(!profile){
profile = [OSCProfilesManager sharedManager:CGRectZero].getSelectedProfile;
}
[self setMagnifierViewportInteractionEnabled:true];
CGPoint streamViewOffset = CGPointMake(profile.normalizedStreamViewOffset.x*self.view.bounds.size.width, profile.normalizedStreamViewOffset.y*self.view.bounds.size.height);
[self restoreMagnifierStreamViewWithOffset:streamViewOffset scale:profile.streamViewScale animated:YES];
[self setMagnifierViewportInteractionEnabled:_settings.touchMode.intValue == AbsoluteTouch && !_settings.passthroughGestures];
}
- (void)restoreMagnifierStreamViewWithOffset:(CGPoint)offset scale:(CGFloat)scale {
[self restoreMagnifierStreamViewWithOffset:offset scale:scale animated:NO];
}
- (void)restoreMagnifierStreamViewWithOffset:(CGPoint)offset scale:(CGFloat)scale animated:(BOOL)animated {
if (![NSThread isMainThread]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self restoreMagnifierStreamViewWithOffset:offset scale:scale animated:animated];
});
return;
}
if (!_scrollView || _streamView.superview != _scrollView) {
return;
}
CGFloat targetScale = MIN(MAX(scale, _scrollView.minimumZoomScale), _scrollView.maximumZoomScale);
[_scrollView setZoomScale:targetScale animated:animated];
[self updateMagnifierViewportMetrics];
CGPoint clampedOffset = [self clampedMagnifierContentOffset:offset];
if (animated) {
[UIView animateWithDuration:0.1
animations:^{
self->_scrollView.contentOffset = clampedOffset;
}
completion:^(__unused BOOL finished) {
[self syncMagnifierStateFromScrollView];
}];
}
else {
_scrollView.contentOffset = clampedOffset;
[self syncMagnifierStateFromScrollView];
}
}
- (void)resetMagnifierStreamViewWithAnimated:(BOOL)animated {
[self restoreMagnifierStreamViewWithOffset:CGPointZero scale:1.0f animated:animated];
}
- (void)gameProfileSelectorClosed{
// Handle the callback
_streamView.widgetToolOpened = false;
[self->_streamView disableOnScreenControls]; // add this to get realtime back menu working.
@@ -850,6 +1085,19 @@
return _streamView;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == _scrollView) {
[self syncMagnifierStateFromScrollView];
}
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
if (scrollView == _scrollView) {
[self updateMagnifierViewportMetrics];
[self syncMagnifierStateFromScrollView];
}
}
- (void)willMoveToParentViewController:(UIViewController *)parent {
// Only cleanup when we're being destroyed
if (parent == nil) {
@@ -978,7 +1226,7 @@
}
- (void) returnToMainFrame {
[_streamView saveStreamViewWidgetChanges];
[_streamView saveStreamingGameProfileChanges];
[_streamView clearOnScreenWidgets];
if(micHandler) [micHandler clean];
PencilHandler.shared = nil;
@@ -1104,7 +1352,7 @@
appDidEnterBackgroundWithoutPip = true;
NSLog(@"applicationWillResignActive %f", CACurrentMediaTime());
[_streamView saveStreamViewWidgetChanges];
[_streamView saveStreamingGameProfileChanges];
#if !TARGET_OS_TV
#endif
@@ -1194,7 +1442,7 @@
- (void)expandSettingsView{
self.mainFrameViewcontroller.settingsExpandedInStreamView = true; //notify mainFrameViewContorller that this is a setting expansion in stream view, some settings shall be disabled.
[_streamView saveStreamViewWidgetChanges];
[_streamView saveStreamingGameProfileChanges];
[self.mainFrameViewcontroller expandSettingsView];
}
@@ -1236,8 +1484,9 @@
[self.view sendSubviewToBack:self.metalViewController.view];
}
// For AVSB renderer, ensure streamView is at the back so OSC layers show
if (self->_streamView && self->_streamView.superview) {
[self.view sendSubviewToBack:self->_streamView];
UIView *streamContainerView = [self streamContentContainerView];
if (streamContainerView && streamContainerView.superview) {
[self.view sendSubviewToBack:streamContainerView];
}
// [self->_streamView showOnScreenControls];
@@ -1822,7 +2071,7 @@
- (void)toggleGamepadOverlayWithOverlayEnabled:(BOOL)overlayEnabled API_AVAILABLE(ios(13.0)){
OnScreenWidgetView.gamepadOverlayFLag = overlayEnabled;
OnScreenWidgetView.relocatedDuringStreaming = true;
OnScreenWidgetView.profileChangedDuringStreaming = true;
if(overlayEnabled) [self loadAbstractGamepadOverlayIfNeeded];
else {
+102
View File
@@ -3638,6 +3638,18 @@
}
}
},
"IVM-Oh-TXR.text" : {
"comment" : "Class = \"UILabel\"; text = \" \"; ObjectID = \"IVM-Oh-TXR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : " "
}
}
}
},
"iZc-Xt-NaK.text" : {
"comment" : "Class = \"UILabel\"; text = \"Yaw factor\"; ObjectID = \"iZc-Xt-NaK\";",
"extractionState" : "extracted_with_value",
@@ -3944,6 +3956,66 @@
}
}
},
"jfo-6M-aEl.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; jfo-6M-aEl.segmentTitles[0] = \"no\"; ObjectID = \"jfo-6M-aEl\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "no"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
}
}
},
"jfo-6M-aEl.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; jfo-6M-aEl.segmentTitles[1] = \"yes\"; ObjectID = \"jfo-6M-aEl\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "yes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "开启"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "啟用"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "啟用"
}
}
}
},
"JTl-un-QJJ.text" : {
"comment" : "Class = \"UILabel\"; text = \"Emulated Controller Type\"; ObjectID = \"JTl-un-QJJ\";",
"extractionState" : "extracted_with_value",
@@ -5944,6 +6016,36 @@
}
}
},
"T3N-f5-q9Y.text" : {
"comment" : "Class = \"UILabel\"; text = \"Animated\"; ObjectID = \"T3N-f5-q9Y\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Animated"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "动画效果"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "動畫效果"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "動畫效果"
}
}
}
},
"t7a-18-5wz.text" : {
"comment" : "Class = \"UILabel\"; text = \"Performance Graphs \"; ObjectID = \"t7a-18-5wz\";",
"extractionState" : "extracted_with_value",
+102
View File
@@ -313,6 +313,66 @@
}
}
},
"4Zz-qG-bsx.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; 4Zz-qG-bsx.segmentTitles[0] = \"no\"; ObjectID = \"4Zz-qG-bsx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "no"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "關閉"
}
}
}
},
"4Zz-qG-bsx.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; 4Zz-qG-bsx.segmentTitles[1] = \"yes\"; ObjectID = \"4Zz-qG-bsx\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "yes"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "开启"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "啟用"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "啟用"
}
}
}
},
"5JB-m0-nUF.text" : {
"comment" : "Class = \"UILabel\"; text = \"YUV 4:4:4\"; ObjectID = \"5JB-m0-nUF\";",
"extractionState" : "extracted_with_value",
@@ -1891,6 +1951,18 @@
}
}
},
"cSB-7c-iRt.text" : {
"comment" : "Class = \"UILabel\"; text = \" \"; ObjectID = \"cSB-7c-iRt\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : " "
}
}
}
},
"cti-T5-cSE.text" : {
"comment" : "Class = \"UILabel\"; text = \"Gesture Slide Distance\"; ObjectID = \"cti-T5-cSE\";",
"extractionState" : "extracted_with_value",
@@ -4087,6 +4159,36 @@
}
}
},
"o1c-Cn-WwN.text" : {
"comment" : "Class = \"UILabel\"; text = \"Animated\"; ObjectID = \"o1c-Cn-WwN\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Animated"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "动画效果"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "動畫效果"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "動畫效果"
}
}
}
},
"o9I-Gt-YRd.text" : {
"comment" : "Class = \"UILabel\"; text = \"Button mode\"; ObjectID = \"o9I-Gt-YRd\";",
"extractionState" : "extracted_with_value",
+10
View File
@@ -659,6 +659,16 @@ struct WidgetPickerView: View {
allowsShortcutCombo: false,
forcedComboMode: .skill
),
FunctionalButtonOption(
label: SwiftLocalizationHelper.localizedString(forKey: "Magnifier"),
cmd: "MAGNIFIER",
tip: SwiftLocalizationHelper.localizedString(forKey: "magnifierTip"),
allowsKeyboardCombination: false,
allowsGamepadCombination: false,
allowsSkillCombo: false,
allowsShortcutCombo: false,
forcedComboMode: .skill
),
]
private var defaultTipMessage: String {