game profile system & selector
This commit is contained in:
@@ -38,6 +38,8 @@
|
||||
2AAA4E822F7666C5001E20DC /* ControllerUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A765BC2ECD51FB004784AA /* ControllerUtil.swift */; };
|
||||
2AAA4E842F7666EE001E20DC /* SwiftLocalizationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E1CDF92C4FE83400547904 /* SwiftLocalizationHelper.swift */; };
|
||||
2AC1E3832F507D80004F76C0 /* GenericUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AC1E3822F507D80004F76C0 /* GenericUtils.swift */; };
|
||||
2AC1EAFB2F92260F004EDA80 /* UIStackExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AC1EAFA2F922602004EDA80 /* UIStackExtension.swift */; };
|
||||
2AC1EAFC2F922889004EDA80 /* UIStackExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AC1EAFA2F922602004EDA80 /* UIStackExtension.swift */; };
|
||||
3A4A3A112F0C000100000001 /* OSCProfilesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4A3A102F0C000100000001 /* OSCProfilesTableViewController.swift */; };
|
||||
3A4A3A132F0C000100000003 /* LayoutOnScreenControlsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4A3A122F0C000100000002 /* LayoutOnScreenControlsViewController.swift */; };
|
||||
840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
|
||||
@@ -204,6 +206,7 @@
|
||||
2A039E562F72892B00546768 /* VoidLinkPreview.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoidLinkPreview.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2A7113FC2F5A6C65001D852D /* ThemeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = "<group>"; };
|
||||
2AC1E3822F507D80004F76C0 /* GenericUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericUtils.swift; sourceTree = "<group>"; };
|
||||
2AC1EAFA2F922602004EDA80 /* UIStackExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackExtension.swift; sourceTree = "<group>"; };
|
||||
3A4A3A102F0C000100000001 /* OSCProfilesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSCProfilesTableViewController.swift; sourceTree = "<group>"; };
|
||||
3A4A3A122F0C000100000002 /* LayoutOnScreenControlsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutOnScreenControlsViewController.swift; sourceTree = "<group>"; };
|
||||
693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
|
||||
@@ -852,6 +855,7 @@
|
||||
FB89462719F646E200339C8A /* StreamFrameViewController.m */,
|
||||
FBD3494E19FF2174002D2A60 /* SettingsViewController.h */,
|
||||
FBD3494F19FF2174002D2A60 /* SettingsViewController.m */,
|
||||
2AC1EAFA2F922602004EDA80 /* UIStackExtension.swift */,
|
||||
FB4A23B61A9D3637004D2EF2 /* LoadingFrameViewController.h */,
|
||||
FB4A23B71A9D3637004D2EF2 /* LoadingFrameViewController.m */,
|
||||
84E1CDEE2C4F688E00547904 /* ToolboxViewController.swift */,
|
||||
@@ -1109,6 +1113,7 @@
|
||||
files = (
|
||||
2AAA4E842F7666EE001E20DC /* SwiftLocalizationHelper.swift in Sources */,
|
||||
2AAA4E822F7666C5001E20DC /* ControllerUtil.swift in Sources */,
|
||||
2AC1EAFB2F92260F004EDA80 /* UIStackExtension.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1214,6 +1219,7 @@
|
||||
FBD349621A0089F6002D2A60 /* DataManager.m in Sources */,
|
||||
97E20DE72E216510000D5DCA /* ImGuiRenderer.mm in Sources */,
|
||||
18B317032EE67A3A009B62C2 /* InertialScroller.swift in Sources */,
|
||||
2AC1EAFC2F922889004EDA80 /* UIStackExtension.swift in Sources */,
|
||||
FB4A23B81A9D3637004D2EF2 /* LoadingFrameViewController.m in Sources */,
|
||||
FB9AFD3A1A7E05CE00872C98 /* ServerInfoResponse.m in Sources */,
|
||||
3A4A3A132F0C000100000003 /* LayoutOnScreenControlsViewController.swift in Sources */,
|
||||
|
||||
@@ -38,11 +38,15 @@
|
||||
</connections>
|
||||
</collectionView>
|
||||
<navigationItem key="navigationItem" id="pSu-bl-gL9">
|
||||
<barButtonItem key="leftBarButtonItem" title="Settings" id="mSL-ru-nRm"/>
|
||||
<leftBarButtonItems>
|
||||
<barButtonItem title="Settings" id="mSL-ru-nRm"/>
|
||||
<barButtonItem title="Profiles" id="Agc-qg-YgU"/>
|
||||
</leftBarButtonItems>
|
||||
<barButtonItem key="rightBarButtonItem" id="KDy-JC-2sU"/>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="navigationItem" destination="pSu-bl-gL9" id="Xni-ne-p40"/>
|
||||
<outlet property="profilesButton" destination="Agc-qg-YgU" id="7qg-yi-h8U"/>
|
||||
<outlet property="settingsButton" destination="mSL-ru-nRm" id="NRf-lv-vlh"/>
|
||||
<outlet property="upButton" destination="KDy-JC-2sU" id="tXB-Rc-IvJ"/>
|
||||
<segue destination="OIm-0n-i9v" kind="push" identifier="createStreamFrame" id="7gN-E7-Ips"/>
|
||||
@@ -50,7 +54,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="608.59375" y="172.8515625"/>
|
||||
<point key="canvasLocation" x="481" y="102"/>
|
||||
</scene>
|
||||
<!--Settings View Controller-->
|
||||
<scene sceneID="tWo-uo-hHg">
|
||||
@@ -1877,7 +1881,7 @@
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="8eE-nU-sk5" userLabel="gyroToStickStack">
|
||||
<rect key="frame" x="23" y="3111" width="336" height="67"/>
|
||||
<subviews>
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="RJa-fo-81z" userLabel="substack1">
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="RJa-fo-81z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="336" height="31"/>
|
||||
<subviews>
|
||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yaw&Pitch → Right Stick" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XU0-qu-2p4" userLabel="uiLabel">
|
||||
@@ -2028,16 +2032,16 @@
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="1yf-rP-jgt">
|
||||
<rect key="frame" x="20" y="3530" width="346" height="31"/>
|
||||
<rect key="frame" x="20" y="3530" width="345.5" height="31"/>
|
||||
<subviews>
|
||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Synth Physical Stick Input" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uFg-dv-6nT" userLabel="uiLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="196" height="31"/>
|
||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Blend Physical Stick Input" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uFg-dv-6nT" userLabel="uiLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="195.5" height="31"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ixf-14-Du8">
|
||||
<rect key="frame" x="216" y="0.0" width="132" height="31"/>
|
||||
<rect key="frame" x="215.5" y="0.0" width="132" height="31"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="130" id="Nie-vj-Gbe"/>
|
||||
</constraints>
|
||||
@@ -2280,6 +2284,7 @@
|
||||
<outlet property="rightStickMinOffsetStack" destination="yl0-WY-ZqV" id="hRP-Rc-60s"/>
|
||||
<outlet property="rollSensitivitySlider" destination="P7t-Q3-rrN" id="pEv-Be-Dxe"/>
|
||||
<outlet property="rollSensitivityStack" destination="iey-Nn-eFG" id="aco-Lz-SzN"/>
|
||||
<outlet property="rollToLeftStickStack" destination="fPh-yy-10O" id="xvW-U3-3id"/>
|
||||
<outlet property="rollToLeftStickSwitch" destination="Jr5-es-If6" id="uQS-Rf-ETV"/>
|
||||
<outlet property="scrollSensitivitySlider" destination="6Pz-di-F4h" id="PUc-gr-gEt"/>
|
||||
<outlet property="scrollSensitivityStack" destination="aEs-8U-RwE" id="XPK-Al-tBx"/>
|
||||
@@ -2330,6 +2335,7 @@
|
||||
<outlet property="useBuiltinMicStack" destination="jCF-si-KLC" id="AnY-Ob-jE9"/>
|
||||
<outlet property="useBuiltinMicSwitch" destination="H3f-qy-ySA" id="O76-df-ich"/>
|
||||
<outlet property="yawPitchSensitivityStack" destination="9Cg-zf-Fjl" id="Iym-a8-nGn"/>
|
||||
<outlet property="yawPitchToRightStickStack" destination="RJa-fo-81z" id="bEy-yc-4LZ"/>
|
||||
<outlet property="yawPitchToRightStickSwitch" destination="tDm-kN-h78" id="v97-60-O35"/>
|
||||
<outlet property="yawSensitivitySlider" destination="vdl-D4-5vn" id="DqE-G7-9eQ"/>
|
||||
<outlet property="yawSensitivityStack" destination="4Ee-fb-lEr" id="47a-rU-LQn"/>
|
||||
|
||||
@@ -41,11 +41,15 @@
|
||||
</collectionView>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" id="pSu-bl-gL9">
|
||||
<barButtonItem key="leftBarButtonItem" title="Settings" id="mSL-ru-nRm"/>
|
||||
<leftBarButtonItems>
|
||||
<barButtonItem title="Settings" id="mSL-ru-nRm"/>
|
||||
<barButtonItem title="Profiles" id="cnk-5b-LLX"/>
|
||||
</leftBarButtonItems>
|
||||
<barButtonItem key="rightBarButtonItem" id="KDy-JC-2sU"/>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="navigationItem" destination="pSu-bl-gL9" id="bvt-g6-wbk"/>
|
||||
<outlet property="profilesButton" destination="cnk-5b-LLX" id="R8P-PB-chp"/>
|
||||
<outlet property="settingsButton" destination="mSL-ru-nRm" id="6mC-zU-buT"/>
|
||||
<outlet property="upButton" destination="KDy-JC-2sU" id="tXB-Rc-IvJ"/>
|
||||
<segue destination="mI3-9F-XwU" kind="push" identifier="createStreamFrame" id="NuQ-Ez-IEX"/>
|
||||
@@ -2610,7 +2614,7 @@
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="xMx-7R-pmH" userLabel="gyroToStickStack">
|
||||
<rect key="frame" x="3" y="2738" width="336" height="67"/>
|
||||
<subviews>
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="68R-uR-4PI" userLabel="substack1">
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="68R-uR-4PI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="336" height="31"/>
|
||||
<subviews>
|
||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yaw&Pitch → Right Stick" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AN9-U4-nUG" userLabel="uiLabel">
|
||||
@@ -2628,9 +2632,10 @@
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="31" id="8bw-pt-rsb"/>
|
||||
<constraint firstAttribute="width" constant="336" id="Oti-eo-Hbw"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="tvL-sE-fGi" userLabel="substack2">
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="tvL-sE-fGi">
|
||||
<rect key="frame" x="0.0" y="36" width="336" height="31"/>
|
||||
<subviews>
|
||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Roll → Left Stick" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3LT-qb-ZEB" userLabel="uiLabel">
|
||||
@@ -3165,16 +3170,16 @@
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="gkU-Rq-gB0">
|
||||
<rect key="frame" x="5" y="3124" width="346" height="31"/>
|
||||
<rect key="frame" x="5" y="3124" width="345.5" height="31"/>
|
||||
<subviews>
|
||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Synth Physical Stick Input" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Bx3-CM-wet" userLabel="uiLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="196" height="31"/>
|
||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Blend Physical Stick Input" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Bx3-CM-wet" userLabel="uiLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="195.5" height="31"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HUF-g8-GD3">
|
||||
<rect key="frame" x="216" y="0.0" width="132" height="31"/>
|
||||
<rect key="frame" x="215.5" y="0.0" width="132" height="31"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="130" id="b8v-mZ-1xt"/>
|
||||
</constraints>
|
||||
@@ -3477,6 +3482,7 @@
|
||||
<outlet property="rightStickMinOffsetStack" destination="aQs-Ww-sPZ" id="UAl-aP-7p8"/>
|
||||
<outlet property="rollSensitivitySlider" destination="SQ5-oO-S7X" id="UTL-nv-UwL"/>
|
||||
<outlet property="rollSensitivityStack" destination="5Zq-ch-iZ4" id="zYv-nH-Ut1"/>
|
||||
<outlet property="rollToLeftStickStack" destination="tvL-sE-fGi" id="Uor-Bf-9DL"/>
|
||||
<outlet property="rollToLeftStickSwitch" destination="caz-QH-4dS" id="XPR-l0-M1L"/>
|
||||
<outlet property="scrollSensitivitySlider" destination="Iha-ti-PtK" id="60F-wE-tB0"/>
|
||||
<outlet property="scrollSensitivityStack" destination="1fy-XH-ApD" id="Utf-HX-rrg"/>
|
||||
@@ -3524,6 +3530,7 @@
|
||||
<outlet property="useBuiltinMicStack" destination="lbL-2m-AO2" id="ZDm-aL-1cC"/>
|
||||
<outlet property="useBuiltinMicSwitch" destination="YR4-0Z-D5Z" id="rMI-TK-FGJ"/>
|
||||
<outlet property="yawPitchSensitivityStack" destination="1z6-G8-X45" id="9M6-Kg-Ms1"/>
|
||||
<outlet property="yawPitchToRightStickStack" destination="68R-uR-4PI" id="w08-1G-ku8"/>
|
||||
<outlet property="yawPitchToRightStickSwitch" destination="npQ-yh-2MA" id="u31-YT-yXS"/>
|
||||
<outlet property="yawSensitivitySlider" destination="JBP-uF-88R" id="57t-bo-3Y4"/>
|
||||
<outlet property="yawSensitivityStack" destination="pyS-Cc-IC3" id="4Vr-ks-9hk"/>
|
||||
@@ -3549,19 +3556,19 @@
|
||||
<image name="trash.fill" catalog="system" width="117" height="128"/>
|
||||
<image name="tray.full.fill" catalog="system" width="128" height="88"/>
|
||||
<systemColor name="linkColor">
|
||||
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBrownColor">
|
||||
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.67450980392156867" green="0.49803921568627452" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGray2Color">
|
||||
<color red="0.68235294120000001" green="0.68235294120000001" blue="0.69803921570000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.68235294117647061" green="0.68235294117647061" blue="0.69803921568627447" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGray3Color">
|
||||
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.7803921568627451" green="0.7803921568627451" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemTealColor">
|
||||
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.0" green="0.76470588235294112" blue="0.81568627450980391" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -513,7 +513,7 @@ static const float REFRESH_CYCLE = 2.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"hostCard update loop %f", CACurrentMediaTime());
|
||||
// NSLog(@"hostCard update loop %f", CACurrentMediaTime());
|
||||
|
||||
[self updateContentsForHost:_host];
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
-(void) rumbleTriggers:(uint16_t)controllerNumber leftTrigger:(uint16_t)leftTrigger rightTrigger:(uint16_t)rightTrigger;
|
||||
-(void) setMotionEventState:(uint16_t)controllerNumber motionType:(uint8_t)motionType reportRateHz:(uint16_t)reportRateHz;
|
||||
-(void) setControllerLed:(uint16_t)controllerNumber r:(uint8_t)r g:(uint8_t)g b:(uint8_t)b;
|
||||
-(void) updateTimerStateForOsc;
|
||||
|
||||
-(uint16_t) getActiveGamepadMask;
|
||||
|
||||
|
||||
@@ -1819,7 +1819,7 @@ double rc_expo(double x, double expo) {
|
||||
NSLog(@"controller obj in dict: %@", controller);
|
||||
}
|
||||
|
||||
[self updateFinished:_oscController];
|
||||
if([self gamepadGyroEnabledInSetting]) [self updateFinished:_oscController];
|
||||
}
|
||||
|
||||
-(id)initWithConfig:(StreamConfiguration*)streamConfig delegate:(id<ControllerSupportDelegate>)delegate
|
||||
@@ -2003,13 +2003,18 @@ double rc_expo(double x, double expo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
-(bool)gamepadGyroEnabledInSetting {
|
||||
return (tempSettings.emulatedControllerType.intValue == LI_CTYPE_PS && tempSettings.gyroMode.intValue != GyroModeOff);
|
||||
}
|
||||
|
||||
-(void)connectionEstablished {
|
||||
for (VoidController* voidController in _voidControllers.allValues) {
|
||||
[self updateFinished:voidController];
|
||||
if(voidController.playerIndex != 0) [self updateFinished:voidController];
|
||||
}
|
||||
|
||||
if (_oscEnabled) {
|
||||
|
||||
//if (_oscEnabled
|
||||
// || (tempSettings.emulatedControllerType.intValue == LI_CTYPE_PS && tempSettings.gyroMode != GyroModeOff)) {
|
||||
if ([self gamepadGyroEnabledInSetting]) {
|
||||
[self setButtonFlag:self->_oscController flags:A_FLAG];
|
||||
[self updateFinished:self->_oscController];
|
||||
[self clearButtonFlag:self->_oscController flags:A_FLAG];
|
||||
@@ -2074,6 +2079,9 @@ double rc_expo(double x, double expo) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateTimerStateForOsc{
|
||||
[self updateTimerStateForController:self->_oscController];
|
||||
}
|
||||
|
||||
-(void) cleanup
|
||||
{
|
||||
|
||||
@@ -58,6 +58,8 @@ typedef NS_ENUM(NSInteger, PencilHoverMode) {
|
||||
@property (nonatomic, assign) bool reverseGyroHoldButton;
|
||||
@property (nonatomic, assign) int controllerGyroSwitchHold;
|
||||
@property (nonatomic, assign) int controllerGyroSwitchToggle;
|
||||
@property (nonatomic, assign) CGFloat pointerVelocityModeDivider;
|
||||
@property (nonatomic, assign) CGFloat touchPointerVelocityFactor;
|
||||
|
||||
@property (nonatomic, assign) bool gamepadOverlayEnabled;
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
[encoder encodeBool:self.reverseGyroHoldButton forKey:@"reverseGyroHoldButton"];
|
||||
[encoder encodeInt:self.controllerGyroSwitchHold forKey:@"controllerGyroSwitchHold"];
|
||||
[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 encodeObject:self.pressureCurvePoints forKey:@"pressureCurvePoints"];
|
||||
@@ -114,6 +116,10 @@
|
||||
self.reverseGyroHoldButton = [decoder containsValueForKey:@"reverseGyroHoldButton"] ? [decoder decodeBoolForKey:@"reverseGyroHoldButton"] : false;
|
||||
self.controllerGyroSwitchHold = [decoder containsValueForKey:@"controllerGyroSwitchHold"] ? [decoder decodeIntForKey:@"controllerGyroSwitchHold"] : ControllerButtonNull;
|
||||
self.controllerGyroSwitchToggle = [decoder containsValueForKey:@"controllerGyroSwitchToggle"] ? [decoder decodeIntForKey:@"controllerGyroSwitchToggle"] : ControllerButtonNull;
|
||||
|
||||
self.pointerVelocityModeDivider = [decoder containsValueForKey:@"pointerVelocityModeDivider"] ? [decoder decodeFloatForKey:@"pointerVelocityModeDivider"] : 0.5;
|
||||
self.touchPointerVelocityFactor = [decoder containsValueForKey:@"touchPointerVelocityFactor"] ? [decoder decodeFloatForKey:@"touchPointerVelocityFactor"] : 1.0;
|
||||
|
||||
self.gamepadOverlayEnabled = [decoder containsValueForKey:@"gamepadOverlayEnabled"] ? [decoder decodeBoolForKey:@"gamepadOverlayEnabled"] : false;
|
||||
|
||||
self.pressureCurvePoints =
|
||||
@@ -212,6 +218,8 @@
|
||||
copy.reverseGyroHoldButton = self.reverseGyroHoldButton;
|
||||
copy.controllerGyroSwitchHold = self.controllerGyroSwitchHold;
|
||||
copy.controllerGyroSwitchToggle = self.controllerGyroSwitchToggle;
|
||||
copy.pointerVelocityModeDivider = self.pointerVelocityModeDivider;
|
||||
copy.touchPointerVelocityFactor = self.touchPointerVelocityFactor;
|
||||
copy.gamepadOverlayEnabled = self.gamepadOverlayEnabled;
|
||||
copy.pressureCurvePoints = [[NSMutableArray alloc] initWithArray:self.pressureCurvePoints copyItems:YES];
|
||||
// copy.initialTouchPressureCurvePoints = [[NSMutableArray alloc] initWithArray:self.initialTouchPressureCurvePoints copyItems:YES];
|
||||
|
||||
@@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@property (nonatomic, assign) NSMutableSet<UITouch *>* touchesCapturedByOnScreenButtons;
|
||||
|
||||
- (id)initWithView:(StreamView* )view andSettings:(TemporarySettings*)settings;
|
||||
- (id)initWithView:(StreamView*)view settings:(TemporarySettings*)settings profile:(OSCProfile* )profile;
|
||||
- (void)setAllowSingleTouchEnabled:(BOOL)enabled;
|
||||
|
||||
@end
|
||||
|
||||
@@ -48,10 +48,10 @@
|
||||
int64_t moveEventIntervalNSec;
|
||||
}
|
||||
|
||||
- (id)initWithView:(StreamView*)view andSettings:(TemporarySettings*)settings{
|
||||
- (id)initWithView:(StreamView*)view settings:(TemporarySettings*)settings profile:(OSCProfile* )profile{
|
||||
self = [super init];
|
||||
self->streamView = view;
|
||||
self->activateCoordSelector = settings.pointerVelocityModeDivider.floatValue != 1.0;
|
||||
self->activateCoordSelector = profile.pointerVelocityModeDivider != 1.0;
|
||||
self->moveEventIntervalNSec = (int64_t)(settings.touchMoveEventInterval.intValue * 1000);;
|
||||
self->streamViewBounds = view.bounds;
|
||||
|
||||
@@ -95,9 +95,9 @@
|
||||
slideGestureVerticalThreshold = CGRectGetHeight([[UIScreen mainScreen] bounds]) * 0.4;
|
||||
screenWidthWithThreshold = CGRectGetWidth([[UIScreen mainScreen] bounds]) - _edgeTolerance;
|
||||
|
||||
self->pointerVelocityDividerLocationByPoints = self->streamView.bounds.size.width * settings.pointerVelocityModeDivider.floatValue;
|
||||
self->pointerVelocityDividerLocationByPoints = self->streamView.bounds.size.width * profile.pointerVelocityModeDivider;
|
||||
|
||||
[NativeTouchPointer initContextWithView:self->streamView andSettings:settings];
|
||||
[NativeTouchPointer initContextWithView:self->streamView profile:profile];
|
||||
//_touchesCapturedByOnScreenButtons = [[NSMutableSet alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (nonatomic, assign) bool useRelativeCoords;
|
||||
|
||||
|
||||
+ (void)initContextWithView:(StreamView*)view andSettings:(TemporarySettings*)settings;
|
||||
+ (void)initContextWithView:(StreamView*)view profile:(OSCProfile*)profile;
|
||||
+ (void)cleanUpContext;
|
||||
|
||||
- (bool)doesNeedResetCoords;
|
||||
|
||||
@@ -53,13 +53,13 @@ static StreamView* streamView;
|
||||
_latestRelativePoint.y = _previousRelativePoint.y + pointerVelocityFactor * (_latestPoint.y - _previousPoint.y);
|
||||
}
|
||||
|
||||
+ (void)initContextWithView:(StreamView*)view andSettings:(TemporarySettings*)settings {
|
||||
+ (void)initContextWithView:(StreamView*)view profile:(OSCProfile*)profile {
|
||||
streamView = view;
|
||||
streamViewWidth = streamView.frame.size.width;
|
||||
fixedResetCoordX = streamViewWidth * 0.3;
|
||||
streamViewHeight = streamView.frame.size.height;
|
||||
fixedResetCoordY = streamViewHeight * 0.4;
|
||||
pointerVelocityFactor = settings.touchPointerVelocityFactor.floatValue;
|
||||
pointerVelocityFactor = profile.touchPointerVelocityFactor;
|
||||
NSLog(@"stream wdith %f, stream height %f", streamViewWidth, streamViewHeight);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ static NSSet *validPositionButtonNames;
|
||||
BOOL _swapABXY;
|
||||
BOOL _visualFeedbackEnabled;
|
||||
BOOL _largerStickLR1;
|
||||
BOOL _firstTapFromOsc;
|
||||
CGFloat _oscTapExlusionAreaSizeFactor;
|
||||
OSCProfilesManager *profilesManager;
|
||||
NSMutableDictionary *_activeCustomOscButtonPositionDict;
|
||||
@@ -187,6 +188,10 @@ static float L3_Y;
|
||||
- (void) pressDownControllerButton: (int)flag{
|
||||
[_controllerSupport setButtonFlag:_controller flags:flag];
|
||||
[_controllerSupport updateFinished:_controller];
|
||||
if(_firstTapFromOsc){
|
||||
_firstTapFromOsc = false;
|
||||
[_controllerSupport updateTimerStateForOsc];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) releaseControllerButton: (int)flag{
|
||||
@@ -300,6 +305,7 @@ static float L3_Y;
|
||||
|
||||
_activeCustomOscButtonPositionDict = [[NSMutableDictionary alloc] init];
|
||||
touchesCapturedByOnScreenControls = [[NSMutableSet alloc] init];
|
||||
_firstTapFromOsc = true;
|
||||
|
||||
if(![self isKindOfClass:[LayoutOnScreenControls class]]) OnScreenControls.shared = self;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@interface PureNativeTouchHandler : UIResponder
|
||||
|
||||
|
||||
- (id)initWithView:(StreamView*)view andSettings:(TemporarySettings*)settings;
|
||||
- (id)initWithView:(StreamView*)view settings:(TemporarySettings*)settings profile:(OSCProfile *)profile;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
int64_t moveEventIntervalNSec;
|
||||
}
|
||||
|
||||
- (id)initWithView:(StreamView*)view andSettings:(TemporarySettings*)settings{
|
||||
- (id)initWithView:(StreamView*)view settings:(TemporarySettings*)settings profile:(OSCProfile *)profile{
|
||||
self = [super init];
|
||||
self->streamView = view;
|
||||
|
||||
self->activateCoordSelector = settings.pointerVelocityModeDivider.floatValue != 1.0;
|
||||
self->activateCoordSelector = profile.pointerVelocityModeDivider != 1.0;
|
||||
self->moveEventIntervalNSec = (int64_t)(settings.touchMoveEventInterval.intValue * 1000);;
|
||||
self->streamViewBounds = view.bounds;
|
||||
|
||||
@@ -94,9 +94,9 @@
|
||||
slideGestureVerticalThreshold = CGRectGetHeight([[UIScreen mainScreen] bounds]) * 0.4;
|
||||
screenWidthWithThreshold = CGRectGetWidth([[UIScreen mainScreen] bounds]) - _edgeTolerance;
|
||||
|
||||
self->pointerVelocityDividerLocationByPoints = self->streamView.bounds.size.width * settings.pointerVelocityModeDivider.floatValue;
|
||||
self->pointerVelocityDividerLocationByPoints = self->streamView.bounds.size.width * profile.pointerVelocityModeDivider;
|
||||
|
||||
[NativeTouchPointer initContextWithView:self->streamView andSettings:settings];
|
||||
[NativeTouchPointer initContextWithView:self->streamView profile:profile];
|
||||
//_touchesCapturedByOnScreenButtons = [[NSMutableSet alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -43,10 +43,11 @@
|
||||
@property (weak, nonatomic) PencilHandler* pencilHandler;
|
||||
@property (weak, nonatomic) UIViewController* streamFrameVC;
|
||||
|
||||
- (void) setupStreamView:(ControllerSupport*)controllerSupport
|
||||
interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate
|
||||
config:(StreamConfiguration*)streamConfig
|
||||
streamFrameTopLayerView:(UIView* )topLayerView
|
||||
- (void) setupStreamViewWithControllerSupport:(ControllerSupport*)controllerSupport
|
||||
interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate
|
||||
streamConfig:(StreamConfiguration*)streamConfig
|
||||
gameProfile:(OSCProfile* )profile
|
||||
streamFrameTopLayerView:(UIView* )topLayerView
|
||||
;
|
||||
|
||||
- (void)cleanUp;
|
||||
@@ -54,12 +55,12 @@
|
||||
- (void) reloadLegacyWidgets:(OSCProfile* )profile;
|
||||
- (void) setOnScreenControls;
|
||||
- (void) disableOnScreenControls;
|
||||
- (void) reloadOnScreenControlsRealtimeWith:(ControllerSupport*)controllerSupport
|
||||
andConfig:(StreamConfiguration*)streamConfig;
|
||||
- (void) reloadOnScreenControlsRealtimeWithControllerSupport:(ControllerSupport*)controllerSupport
|
||||
streamConfig:(StreamConfiguration*)streamConfig;
|
||||
- (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport
|
||||
andConfig:(StreamConfiguration*)streamConfig;
|
||||
- (void) clearOnScreenWidgets;
|
||||
- (void) reloadOnScreenWidgetViews:(bool)reload;
|
||||
- (void) reloadGameProfile:(OSCProfile* )profile reloadWidgets:(bool)reloadWidgets;
|
||||
- (void) saveStreamViewWidgetChanges;
|
||||
- (bool) isOnScreenWidgetEnabled;
|
||||
|
||||
|
||||
+32
-25
@@ -85,9 +85,10 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
OSCProfilesManager* oscProfileMan;
|
||||
}
|
||||
|
||||
- (void) setupStreamView:(ControllerSupport*)controllerSupport
|
||||
- (void) setupStreamViewWithControllerSupport:(ControllerSupport*)controllerSupport
|
||||
interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate
|
||||
config:(StreamConfiguration*)streamConfig
|
||||
streamConfig:(StreamConfiguration*)streamConfig
|
||||
gameProfile:(OSCProfile* )profile
|
||||
streamFrameTopLayerView:(UIView* )topLayerView{
|
||||
self->comboKeyModifierFlags = (UIKeyModifierControl|UIKeyModifierAlternate|UIKeyModifierShift);
|
||||
|
||||
@@ -144,11 +145,12 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
switch (touchMode) {
|
||||
case NativeTouch:
|
||||
keyboardToggleRecognizer.immediateTriggering = false;
|
||||
self->touchHandler = [[NativeTouchHandler alloc] initWithView:self andSettings:settings];
|
||||
self->touchHandler = [[NativeTouchHandler alloc] initWithView:self settings:settings profile:profile];
|
||||
break;
|
||||
case NativeTouchOnly:
|
||||
keyboardToggleRecognizer.immediateTriggering = false;
|
||||
self->touchHandler = [[PureNativeTouchHandler alloc] initWithView:self andSettings:settings];break;
|
||||
self->touchHandler = [[PureNativeTouchHandler alloc] initWithView:self settings:settings profile:profile];
|
||||
break;
|
||||
case RelativeTouch:
|
||||
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self andSettings:settings];
|
||||
keyboardToggleRecognizer.immediateTriggering = false;
|
||||
@@ -528,8 +530,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
return [self isOscEnabled] && settings.onscreenControls.intValue == OnScreenControlsLevelCustom;
|
||||
}
|
||||
|
||||
- (void) reloadOnScreenControlsRealtimeWith:(ControllerSupport*)controllerSupport
|
||||
andConfig:(StreamConfiguration*)streamConfig {
|
||||
- (void) reloadOnScreenControlsRealtimeWithControllerSupport:(ControllerSupport*)controllerSupport
|
||||
streamConfig:(StreamConfiguration*)streamConfig {
|
||||
[self reloadOnScreenControlsWith:controllerSupport andConfig:streamConfig];
|
||||
/*
|
||||
StreamFrameViewController* vc = (StreamFrameViewController* )_streamFrameVC;
|
||||
@@ -630,13 +632,17 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
[oscProfileMan replaceSelectedProfileWith:newProfile overwriteDefault:YES];
|
||||
}
|
||||
|
||||
- (void) reloadOnScreenWidgetViews:(bool)reload{
|
||||
NSLog(@"reloadOnScreenWidgets in streamview %f", CACurrentMediaTime());
|
||||
- (void) reloadGameProfile:(OSCProfile* )profile reloadWidgets:(bool)reloadWidgets{
|
||||
|
||||
self->oscProfileMan = [OSCProfilesManager sharedManager:self->_streamFrameTopLayerView.bounds];
|
||||
|
||||
if(!profile){
|
||||
NSLog(@"reloadOnScreenWidgets in streamview %d", reloadWidgets);
|
||||
profile = [self->oscProfileMan getSelectedProfile]; //returns the currently selected OSCProfile
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if(!self->oscProfileMan) self->oscProfileMan = [OSCProfilesManager sharedManager:self->_streamFrameTopLayerView.bounds];
|
||||
OSCProfile *oscProfile = [self->oscProfileMan getSelectedProfile]; //returns the currently selected OSCProfile
|
||||
MotionHandler* motionHandler = [MotionHandler sharedWithProfile:oscProfile];
|
||||
MotionHandler* motionHandler = [MotionHandler sharedWithProfile:profile];
|
||||
|
||||
// get streamFrameVC
|
||||
if(!self->_streamFrameVC) self->_streamFrameVC = [self parentViewController];
|
||||
@@ -648,24 +654,25 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
|
||||
// bool customOscEnabled = [self isOscEnabled] && settings.onscreenControls.intValue == OnScreenControlsLevelCustom;
|
||||
|
||||
if(![self isOnScreenWidgetEnabled]) return;
|
||||
// if(![self isOnScreenWidgetEnabled]) return;
|
||||
|
||||
OnScreenWidgetView.buttonVisualFeedbackEnabled = self->settings.buttonVisualFeedback;
|
||||
OnScreenWidgetView.gamepadOverlayFLag = oscProfile.gamepadOverlayEnabled;
|
||||
OnScreenWidgetView.gamepadOverlayFLag = profile.gamepadOverlayEnabled;
|
||||
OnScreenWidgetView.relocatedDuringStreaming = false;
|
||||
|
||||
bool hasLegacyWidget = false;
|
||||
if(reload && !OnScreenWidgetView.editMode){
|
||||
if(reloadWidgets && !OnScreenWidgetView.editMode){
|
||||
// remove all keyboard widget views first
|
||||
[self clearOnScreenWidgets];
|
||||
|
||||
bool sequenceGenerated = false;
|
||||
bool hasMovableWidget = false;
|
||||
for (NSInteger i = 0; i < oscProfile.buttonStatesEncoded.count; i++) {
|
||||
NSData* buttonStateEncoded = oscProfile.buttonStatesEncoded[i];
|
||||
|
||||
for (NSInteger i = 0; i < profile.buttonStatesEncoded.count; i++) {
|
||||
NSData* buttonStateEncoded = profile.buttonStatesEncoded[i];
|
||||
OnScreenButtonState* buttonState = [self->oscProfileMan unarchiveButtonStateEncoded:buttonStateEncoded];
|
||||
if(buttonState.widgetType == CustomOnScreenWidget){
|
||||
OnScreenWidgetView* widgetView = [OnScreenWidgetView widgetWithCmdString:buttonState.name buttonLabel:buttonState.alias shape:buttonState.widgetShape profile:oscProfile]; //reconstruct widgetView
|
||||
OnScreenWidgetView* widgetView = [OnScreenWidgetView widgetWithCmdString:buttonState.name buttonLabel:buttonState.alias shape:buttonState.widgetShape profile:profile]; //reconstruct widgetView
|
||||
|
||||
widgetView.functionalButtonDelegate = (id<OnScreenFunctionalButtonDelegate>)self->_streamFrameVC;
|
||||
widgetView.motionHandler = motionHandler;
|
||||
@@ -733,7 +740,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
if(sequenceGenerated){
|
||||
// NSLog(@"widgetView.sequence %d %f", widgetView.sequence, CACurrentMediaTime());
|
||||
buttonState.sequence = widgetView.sequence;
|
||||
oscProfile.buttonStatesEncoded[i] = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||
profile.buttonStatesEncoded[i] = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||
}
|
||||
|
||||
[widgetView accessWidgetAttributes];
|
||||
@@ -742,7 +749,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
}
|
||||
|
||||
if(sequenceGenerated && hasMovableWidget){
|
||||
[self->oscProfileMan replaceSelectedProfileWith:oscProfile overwriteDefault:YES];
|
||||
[self->oscProfileMan replaceSelectedProfileWith:profile overwriteDefault:YES];
|
||||
}
|
||||
|
||||
uint64_t buttonIndex = 9999999;
|
||||
@@ -771,19 +778,19 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
}
|
||||
}
|
||||
|
||||
OnScreenWidgetView.unfoldedExclusiveFolderSequence = oscProfile.unfoldedExclusiveFolderSequence;
|
||||
[OnScreenWidgetView setPostExclusiveUnfoldeds:oscProfile.postExclusiveUnfoldedSequences];
|
||||
OnScreenWidgetView.unfoldedExclusiveFolderSequence = profile.unfoldedExclusiveFolderSequence;
|
||||
[OnScreenWidgetView setPostExclusiveUnfoldeds:profile.postExclusiveUnfoldedSequences];
|
||||
[OnScreenWidgetView restoreFoldedStates];
|
||||
|
||||
NSLog(@"hasLegacyWidget %d %f", hasLegacyWidget, CACurrentMediaTime());
|
||||
// legacy widgets
|
||||
if(!OnScreenWidgetView.editMode && (hasLegacyWidget || !reload)){
|
||||
if([self isOscEnabled]) [self reloadLegacyWidgets:oscProfile];
|
||||
if(!OnScreenWidgetView.editMode && (hasLegacyWidget || !reloadWidgets)){
|
||||
if([self isOscEnabled]) [self reloadLegacyWidgets:profile];
|
||||
else [self disableOnScreenControls];
|
||||
}
|
||||
|
||||
if(reload && !OnScreenWidgetView.editMode){
|
||||
[PencilHandler.shared setupPressureLUTWithProfile:oscProfile];
|
||||
if(reloadWidgets && !OnScreenWidgetView.editMode){
|
||||
[PencilHandler.shared setupPressureLUTWithProfile:profile];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -220,13 +220,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : " 版面配置: %@ 小工具: %@"
|
||||
"value" : " 版面配置: %@ 控制項: %@"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : " 版面配置: %@ 小工具: %@"
|
||||
"value" : " 版面配置: %@ 控制項: %@"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -421,6 +421,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"[ Edit on-screen widget layout ]" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 编辑屏显控件布局 ]"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 編輯螢幕控制項佈局 ]"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 編輯螢幕控制項佈局 ]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"[ Enter picture-in-picture mode ]" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -444,48 +467,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"[ On-screen widget tool ]" : {
|
||||
"[ Switch game profile ]" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 打开屏显控件工具 ]"
|
||||
"value" : "[ 切换游戏配置 ]"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 調整螢幕小工具版面配置 ]"
|
||||
"value" : "[ 切換遊戲配置 ]"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 調整螢幕小工具版面配置 ]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"[ Switch on-screen widget profile ]" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 切换屏显控件布局 ]"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 切換螢幕小工具版面配置 ]"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "[ 切換螢幕小工具版面配置 ]"
|
||||
"value" : "[ 切換遊戲配置 ]"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3254,13 +3254,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "\n1. 從螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,開啟工具欄選單.\n\n2. 選擇「調整螢幕小工具版面配置」。"
|
||||
"value" : "\n1. 從螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,開啟工具欄選單.\n\n2. 選擇「編輯螢幕控制項佈局」。"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "\n1. 從螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,開啟工具欄選單.\n\n2. 選擇「調整螢幕小工具版面配置」。"
|
||||
"state" : "translated",
|
||||
"value" : "\n1. 從螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,開啟工具欄選單.\n\n2. 選擇「編輯螢幕控制項佈局」。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4083,13 +4083,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "編輯選取的小工具"
|
||||
"value" : "編輯選取的控制項"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "編輯選取的小工具"
|
||||
"value" : "編輯選取的控制項"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4907,25 +4907,25 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Pressure curve saved with current on-screen widget profile. Check custom 'On Screen Widget' in 'Touch Control' section of the settings menu, or toolbox menu brought up by right screen edge slide gesture.\nWhen you switch widget profile, pressure curve will change too."
|
||||
"value" : "Pressure curve saved with current game profile. To switch game profile, tap the [gamepad icon] on navigation bar.\nWhen you switch game profile, pressure curve will change too."
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "笔压曲线已随屏显控件配置保存。见设置菜单‘触控分区’的’屏显控件’ 自定义选项, 或屏幕右边缘滑动手势调出的工具箱菜单。\n切换屏显控件配置时,笔压曲线也将随之变化。"
|
||||
"value" : "笔压曲线已随 [游戏配置] 保存。点击导航栏的 [手柄图标] 即可切换游戏配置。\n切换屏显控件配置时,笔压曲线也将随之变化。"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "笔壓曲線已隨「螢幕小工具」配置儲存。請至設定選單「觸控分區」中的「螢幕小工具」自訂選項,或由螢幕右側邊緣滑動手勢呼叫的工具箱選單查看。\n切換「螢幕小工具」配置時,筆壓曲線也會隨之變化。"
|
||||
"value" : "筆壓曲線已隨[遊戲配置]保存。點擊導覽列的[手把圖示]即可切換遊戲配置。\n切換螢幕控制項配置時,筆壓曲線也將隨之變化。"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "笔壓曲線已隨「螢幕小工具」配置儲存。請至設定選單「觸控分區」中的「螢幕小工具」自訂選項,或由螢幕右側邊緣滑動手勢呼叫的工具箱選單查看。\n切換「螢幕小工具」配置時,筆壓曲線也會隨之變化。"
|
||||
"value" : "筆壓曲線已隨[遊戲配置]保存。點擊導覽列的[手把圖示]即可切換遊戲配置。\n切換螢幕控制項配置時,筆壓曲線也將隨之變化。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5166,6 +5166,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Game Profile" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "游戏配置"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "遊戲配置"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "遊戲配置"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Gamepad" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -5425,6 +5448,64 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"gameProfileIntroduction" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "- The on-screen widget layout (including the virtual gamepad, virtual buttons, etc.), as well as the options in the settings menu marked with a [gamepad icon] (such as motion control settings), are all saved in the game profile.\n\n- To switch game profile during streaming, swipe inward from the %@ edge of the screen by %@ of screen width, open [Switch Game Profile] in the toolbox menu"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "- 屏显控件布局(包含虚拟手柄、虚拟按键等),以及设置菜单中标记 [手柄图标] 的选项(如体感控制参数),皆保存在游戏配置中。\n\n- 串流过程中, 由屏幕 %@ 边缘向内滑动 %@ 屏宽,即可在工具箱菜单中打开 [切换游戏配置]"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "- 螢幕控制項佈局(包含虛擬手把、虛擬按鍵等),以及設定選單中標記 [手把圖示] 的選項(如體感控制參數),皆保存在遊戲配置中。\n\n- 串流過程中,由螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,即可在工具箱選單中開啟[切換遊戲配置]"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "- 螢幕控制項佈局(包含虛擬手把、虛擬按鍵等),以及設定選單中標記 [手把圖示] 的選項(如體感控制參數),皆保存在遊戲配置中。\n\n- 串流過程中,由螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,即可在工具箱選單中開啟[切換遊戲配置]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gameProfileStackTip" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "This setting is saved in [Game Profile]. To open game profile selector:\n- Tap the gamepad icon on navigation bar\n- While streaming, swipe inward from the %@ edge of the screen by %@ of screen width, open [Switch Game Profile] in the toolbox menu"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "该设置保存在 [游戏配置] 中. 游戏配置切换入口:\n- 点击导航栏的手柄图标\n- 串流时,由屏幕 %@ 边缘向内滑动 %@ 屏宽,在工具箱菜单中打开 [切换游戏配置]"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "此設定保存在[遊戲配置]中。遊戲配置切換入口:\n- 點擊導覽列的手把圖示\n- 串流時,由螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,在工具箱選單中開啟[切換遊戲配置]"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "此設定保存在[遊戲配置]中。遊戲配置切換入口:\n- 點擊導覽列的手把圖示\n- 串流時,由螢幕 %@ 邊緣向內滑動 %@ 螢幕寬度,在工具箱選單中開啟[切換遊戲配置]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Gestures" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -6813,25 +6894,25 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "- To map gyro directly to mouse/stick, must turn off DS4 gyro mapping in “Controller” section.\n\n- All settings in “Motion Control” section are saved with on-screen widget profile, which can be selected & managed in the right edge slide toolbox menu.\n\n- Motion control can be turned on & off by controller buttons or on-screen buttons"
|
||||
"value" : "- To map gyro directly to mouse/stick, must turn off DS4 gyro mapping in “Controller” section.\n\n- Motion control can be turned on & off by controller buttons or on-screen buttons"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "- 关闭“手柄”菜单分区的DS4陀螺仪映射后, 方可将陀螺仪直接映射为手柄或鼠标。\n\n- “体感控制”菜单分区的所有设置均保存在屏显控件配置中,可在右边缘滑出的工具箱菜单中切换。\n\n- 体感控制陀螺仪可由手柄按键或屏显按键开关。"
|
||||
"value" : "- 关闭“手柄”菜单分区的DS4陀螺仪映射后, 方可将陀螺仪直接映射为手柄或鼠标。\n\n- 体感控制陀螺仪可由手柄按键或屏显按键开关。"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "- 關閉「手柄」選單分區的 DS4 陀螺儀映射後,方可將陀螺儀直接映射為手柄或滑鼠。\n\n- 「體感控制」選單分區的所有設定皆儲存在螢幕顯示小工具配置中,可在右邊緣滑出的工具箱選單中切換。\n\n- 體感控制陀螺儀可由手把按鍵或螢幕顯示按鍵開關。"
|
||||
"value" : "- 關閉「手柄」選單分區的 DS4 陀螺儀映射後,方可將陀螺儀直接映射為手柄或滑鼠。\n\n- 體感控制陀螺儀可由手把按鍵或螢幕顯示按鍵開關。"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "- 關閉「手柄」選單分區的 DS4 陀螺儀映射後,方可將陀螺儀直接映射為手柄或滑鼠。\n\n- 「體感控制」選單分區的所有設定皆儲存在螢幕顯示小工具配置中,可在右邊緣滑出的工具箱選單中切換。\n\n- 體感控制陀螺儀可由手把按鍵或螢幕顯示按鍵開關。"
|
||||
"value" : "- 關閉「手柄」選單分區的 DS4 陀螺儀映射後,方可將陀螺儀直接映射為手柄或滑鼠。\n\n- 體感控制陀螺儀可由手把按鍵或螢幕顯示按鍵開關。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7390,13 +7471,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "新螢幕小工具"
|
||||
"value" : "新螢幕控制項"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "新螢幕小工具"
|
||||
"value" : "新螢幕控制項"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7488,13 +7569,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "請先點選一個小工具"
|
||||
"value" : "請先點選一個控制項"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "請先點選一個小工具"
|
||||
"value" : "請先點選一個控制項"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7741,13 +7822,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "螢幕控制器與小工具"
|
||||
"value" : "螢幕控制器與控制項"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "螢幕控制器與小工具"
|
||||
"value" : "螢幕控制器與控制項"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8499,25 +8580,25 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "This is saved in onscreen widget profile, which can be selected & managed in toolbox menu slide from the right screen edge."
|
||||
"value" : "Also known as deadzone boost"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "此项设置保存在屏显控件配置方案中, 可在屏幕右边缘滑出的工具箱菜单中切换。"
|
||||
"value" : "该选项也被称为摇杆死区补偿"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "此項設定儲存在螢幕小工具配置方案中,可在螢幕右邊緣滑出的工具箱選單中切換。"
|
||||
"value" : "此選項亦稱為搖桿死區補償"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "此項設定儲存在螢幕小工具配置方案中,可在螢幕右邊緣滑出的工具箱選單中切換。"
|
||||
"value" : "此選項亦稱為搖桿死區補償"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9444,13 +9525,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "閱讀小工具說明"
|
||||
"value" : "閱讀控制項說明"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "閱讀小工具說明"
|
||||
"value" : "閱讀控制項說明"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11444,13 +11525,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "點選「確定」以開啟自訂螢幕小工具與體感控制。"
|
||||
"value" : "點選「確定」以開啟自訂螢幕控制項與體感控制。"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "點選「確定」以開啟自訂螢幕小工具與體感控制。"
|
||||
"value" : "點選「確定」以開啟自訂螢幕控制項與體感控制。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,18 @@ import Foundation
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@objc static func isFirstTappingGameProfileSelectorFromMainFrame() -> Bool {
|
||||
let key = "hasTappedGameProfileSelectorFromMainFrame-6"
|
||||
let defaults = UserDefaults.standard
|
||||
let launchedBefore = defaults.bool(forKey: key)
|
||||
|
||||
if !launchedBefore {
|
||||
defaults.set(true, forKey: key)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@objc static func gamepadOverlayFeatureTipTitle() -> String {
|
||||
SwiftLocalizationHelper.localizedString(forKey: "Gamepad Overlay")
|
||||
|
||||
+77
-12
@@ -282,7 +282,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
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)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleEnterBackground), name: UIApplication.willResignActiveNotification, object: nil)
|
||||
// NotificationCenter.default.addObserver(self, selector: #selector(handleEnterBackground), name: UIApplication.willResignActiveNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil)
|
||||
OnScreenWidgetView.editMode = true
|
||||
handleMissingToolBarIcon(toolbarRootView)
|
||||
@@ -346,6 +346,8 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
}
|
||||
|
||||
@objc func reloadOnScreenWidgetViews() {
|
||||
if self.profileTableLoadingMode == .selectProfileFromMainFrame { return }
|
||||
|
||||
OnScreenWidgetView.isTweakingHighlight = false
|
||||
OnScreenWidgetView.editMode = true
|
||||
|
||||
@@ -450,6 +452,8 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
}
|
||||
self.layoutOSC.oscButtonLayerPool.removeAllObjects()
|
||||
}
|
||||
|
||||
view.bringSubviewToFront(toolbarRootView)
|
||||
}
|
||||
|
||||
@objc func profileRefresh() {
|
||||
@@ -458,15 +462,20 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
oscProfilesTableViewController = storyboard.instantiateViewController(withIdentifier: "OSCProfilesTableViewController") as? OSCProfilesTableViewController
|
||||
oscProfilesTableViewController?.needToUpdateOscLayoutTVC = { [weak self] in
|
||||
guard let self else { return }
|
||||
self.reloadOnScreenWidgetViews()
|
||||
if !loadJustTapped {
|
||||
self.reloadOnScreenWidgetViews()
|
||||
}
|
||||
loadJustTapped = false
|
||||
self.oscProfilesTableViewController?.currentOSCButtonLayers = self.layoutOSC.oscButtonLayerPool
|
||||
}
|
||||
oscProfilesTableViewController?.tableView?.reloadData()
|
||||
reloadOnScreenWidgetViews()
|
||||
}
|
||||
|
||||
@objc var profileTableLoadingMode: OSCProfilesTableViewLoadingMode = .selectProfile
|
||||
@objc(presentProfilesTableViewWithLoadingMode:)
|
||||
func presentProfilesTableView(with loadingMode: OSCProfilesTableViewLoadingMode) {
|
||||
profileTableLoadingMode = loadingMode
|
||||
presentProfilesTableView(with: loadingMode, pickedProfileDataHandler: nil)
|
||||
}
|
||||
|
||||
@@ -482,7 +491,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
controller?.layoutViewBounds = view.bounds
|
||||
controller?.needToUpdateOscLayoutTVC = { [weak self] in
|
||||
guard let self else { return }
|
||||
if loadingMode == .selectProfile {
|
||||
if loadingMode == .selectProfile || loadingMode == .selectProfileFromStreamView {
|
||||
self.reloadOnScreenWidgetViews()
|
||||
}
|
||||
}
|
||||
@@ -497,8 +506,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
}
|
||||
}
|
||||
|
||||
private var loadJustTapped:Bool = false
|
||||
@IBAction func loadTapped(_ sender: Any?) {
|
||||
saveTapped(nil)
|
||||
// saveTapped(nil)
|
||||
loadJustTapped = true
|
||||
presentProfilesTableView(with: .selectProfile)
|
||||
}
|
||||
|
||||
@@ -566,22 +577,57 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@objc private func handleEnterBackground() {
|
||||
saveTapped(nil)
|
||||
}
|
||||
*/
|
||||
|
||||
@objc private func handleReturnToForeground() {
|
||||
setupWidgetPanel()
|
||||
if (self.profileTableLoadingMode != .selectProfileFromMainFrame
|
||||
&& self.profileTableLoadingMode != .selectProfileFromMainFrame)
|
||||
{setupWidgetPanel()}
|
||||
updateViewBounds()
|
||||
}
|
||||
|
||||
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
super.viewWillTransition(to: size, with: coordinator)
|
||||
if UIApplication.shared.applicationState != .active { return }
|
||||
viewWillBeResized = true
|
||||
hideStickIndicators()
|
||||
if !quickSwitchEnabled {
|
||||
saveTapped(nil)
|
||||
if self.profileTableLoadingMode == .selectProfile {
|
||||
|
||||
let oldSize = view.bounds.size
|
||||
let scaleX = size.width / oldSize.width
|
||||
let scaleY = size.height / oldSize.height
|
||||
|
||||
for widget in OnScreenWidgetView.mapping.values {
|
||||
let oldCenter = widget.center
|
||||
let oldStoredCenter = widget.storedCenter
|
||||
|
||||
coordinator.animate(alongsideTransition: { _ in
|
||||
widget.center = CGPoint(
|
||||
x: oldCenter.x * scaleX,
|
||||
y: oldCenter.y * scaleY
|
||||
)
|
||||
widget.storedCenter = CGPoint(
|
||||
x: oldStoredCenter.x * scaleX,
|
||||
y: oldStoredCenter.y * scaleY
|
||||
)
|
||||
}, completion: nil)
|
||||
}
|
||||
|
||||
for buttonLayer in self.layoutOSC.oscButtonLayerPool {
|
||||
if let layer = buttonLayer as? CALayer {
|
||||
let oldPosition = layer.position
|
||||
coordinator.animate(alongsideTransition: { _ in
|
||||
if layer == self.layoutOSC._leftStick
|
||||
|| layer == self.layoutOSC._rightStick {return}
|
||||
layer.position = CGPoint(
|
||||
x: oldPosition.x * scaleX,
|
||||
y: oldPosition.y * scaleY
|
||||
)
|
||||
}, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,6 +636,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
}
|
||||
|
||||
@objc private func handleOrientationChangeForOnScreenWidgets() {
|
||||
|
||||
if !viewWillBeResized { return }
|
||||
setupWidgetPanel()
|
||||
updateViewBounds()
|
||||
@@ -602,7 +649,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
oscProfilesTableViewController?.layoutViewBounds = view.bounds
|
||||
OSCProfilesManager.setLayoutViewBounds(view.bounds)
|
||||
OSCProfilesManager.setOnScreenWidgetViewsSet(onScreenWidgetViews)
|
||||
reloadOnScreenWidgetViews()
|
||||
// reloadOnScreenWidgetViews()
|
||||
}
|
||||
|
||||
@objc func OSCLayoutChanged() {
|
||||
@@ -1472,6 +1519,24 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
}
|
||||
|
||||
@objc private func handleProfileTablViewDismiss() {
|
||||
|
||||
switch profileTableLoadingMode {
|
||||
case .selectProfile:
|
||||
if oscProfilesTableViewController?.loadingMode != .pickProfileData {
|
||||
setupWidgetPanel()
|
||||
}
|
||||
else {widgetPanelStack.isHidden = false}
|
||||
case .selectProfileFromMainFrame, .selectProfileFromStreamView:
|
||||
clearOnScreenWidgets()
|
||||
dismiss(animated: false)
|
||||
case .pickProfile:
|
||||
clearOnScreenWidgets()
|
||||
dismiss(animated: false)
|
||||
case .pickProfileData:
|
||||
widgetPanelStack.isHidden = false
|
||||
}
|
||||
|
||||
/*
|
||||
if quickSwitchEnabled {
|
||||
clearOnScreenWidgets()
|
||||
dismiss(animated: false)
|
||||
@@ -1480,7 +1545,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
setupWidgetPanel()
|
||||
}
|
||||
else {widgetPanelStack.isHidden = false}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
private func addInnerAnalogSticksToOuterAnalogLayers() {
|
||||
@@ -1554,7 +1619,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
}
|
||||
|
||||
private func setupWidgetPanel() {
|
||||
widgetPanelStack.isHidden = quickSwitchEnabled
|
||||
widgetPanelStack.isHidden = profileTableLoadingMode != .selectProfile
|
||||
tipTitleLabel.textAlignment = .left
|
||||
tipTitleLabel.contentMode = .top
|
||||
tipTitleLabel.lineBreakMode = .byWordWrapping
|
||||
|
||||
+10
-3
@@ -22,7 +22,9 @@ enum FileOperation: Int {
|
||||
}
|
||||
|
||||
@objc enum OSCProfilesTableViewLoadingMode: Int {
|
||||
case selectProfile
|
||||
case selectProfile
|
||||
case selectProfileFromStreamView
|
||||
case selectProfileFromMainFrame
|
||||
case pickProfile
|
||||
case pickProfileData
|
||||
}
|
||||
@@ -129,7 +131,9 @@ final class OSCProfilesTableViewController: UIViewController, UITableViewDelegat
|
||||
updateHorizontalLayoutConstraints()
|
||||
horizontalConstraintsConfigured = true
|
||||
tableView.alpha = 1
|
||||
tableView.backgroundColor = UIColor.black.withAlphaComponent(0.43)
|
||||
tableView.backgroundColor = UIColor.black.withAlphaComponent(self.loadingMode == .selectProfileFromMainFrame ? (
|
||||
ThemeManager.userInterfaceStyle() == .dark ? 0.83 : 0.6
|
||||
) : 0.43)
|
||||
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissSelf))
|
||||
tap.cancelsTouchesInView = false
|
||||
@@ -471,7 +475,10 @@ final class OSCProfilesTableViewController: UIViewController, UITableViewDelegat
|
||||
}
|
||||
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
||||
if loadingMode != .selectProfile,
|
||||
if (loadingMode != .selectProfile
|
||||
&& loadingMode != .selectProfileFromMainFrame
|
||||
&& loadingMode != .selectProfileFromStreamView
|
||||
),
|
||||
let touchView = touch.view,
|
||||
touchView.isDescendant(of: tableView) {
|
||||
return true
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
@interface MainFrameViewController : UICollectionViewController <DiscoveryCallback, PairCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate, HostCardActionDelegate, AppViewUpdateLoopDelegate, UITextFieldDelegate>
|
||||
|
||||
@property (nonatomic, strong) IBOutlet UIBarButtonItem *settingsButton;
|
||||
@property (weak, nonatomic) IBOutlet UIBarButtonItem *profilesButton;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
@property (nonatomic, assign) bool settingsExpandedInStreamView;
|
||||
@property (nonatomic, assign) bool sessionLaunchedWithAbsoluteTouch;
|
||||
|
||||
@@ -1160,6 +1160,59 @@ static NSMutableSet* hostList;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)profilesButtonTapped {
|
||||
if([GenericUtils isFirstTappingGameProfileSelectorFromMainFrame]){
|
||||
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
Settings* settings = [dataMan retrieveSettings];
|
||||
|
||||
|
||||
NSString* edgeSide = settings.slideToSettingsScreenEdge.intValue != UIRectEdgeLeft ? [LocalizationHelper localizedStringForKey:@"left"] : [LocalizationHelper localizedStringForKey:@"right"];
|
||||
NSString* slideDist = [NSString stringWithFormat:@"%d%%", (int)(settings.slideToSettingsDistance.floatValue*100)];
|
||||
|
||||
[AlertControllerUtil showAlertIn:self
|
||||
title:[LocalizationHelper localizedStringForKey:@"Game Profile"]
|
||||
message:[LocalizationHelper localizedStringForKey:@"gameProfileIntroduction", edgeSide, slideDist]
|
||||
withCancel:NO
|
||||
buttonTitle:[LocalizationHelper localizedStringForKey:@"Got it!"]
|
||||
countdown:6
|
||||
action:^{}
|
||||
completion:^{
|
||||
[self openGameProfileSeletor];
|
||||
}];
|
||||
}
|
||||
else [self openGameProfileSeletor];
|
||||
}
|
||||
|
||||
- (void)openGameProfileSeletor{
|
||||
if(settingsViewController){
|
||||
[settingsViewController mainFrameGameProfileButtonTapped];
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutOnScreenControlsViewController* layoutToolVC;
|
||||
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
||||
if (isIPhone) {
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil];
|
||||
layoutToolVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"];
|
||||
}
|
||||
else {
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPad" bundle:nil];
|
||||
layoutToolVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"];
|
||||
layoutToolVC.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
}
|
||||
layoutToolVC.view.backgroundColor = UIColor.clearColor;
|
||||
layoutToolVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
||||
|
||||
|
||||
layoutToolVC.profileTableLoadingMode = OSCProfilesTableViewLoadingModeSelectProfileFromMainFrame;
|
||||
layoutToolVC.toolbarStackView.hidden = true;
|
||||
layoutToolVC.toolbarRootView.hidden = true;
|
||||
[self presentViewController:layoutToolVC animated:NO completion:^{
|
||||
[layoutToolVC presentProfilesTableViewWithLoadingMode:OSCProfilesTableViewLoadingModeSelectProfileFromMainFrame];
|
||||
}];
|
||||
}
|
||||
|
||||
// currently obselete:
|
||||
- (void) setNeedsUpdateAllowedOrientation{
|
||||
if (@available(iOS 16.0, *)) {
|
||||
@@ -1174,7 +1227,11 @@ static NSMutableSet* hostList;
|
||||
revealController.navBarMenuDelegate = settingsViewController;
|
||||
_settingsViewExpanded = position != FrontViewPositionLeft;
|
||||
if (position == FrontViewPositionLeft) {
|
||||
self.navigationItem.leftBarButtonItems = @[_settingsButton];
|
||||
if (@available(iOS 26.0, *)) {
|
||||
_settingsButton.sharesBackground = false;
|
||||
_profilesButton.sharesBackground = false;
|
||||
}
|
||||
self.navigationItem.leftBarButtonItems = @[_settingsButton, _profilesButton];
|
||||
|
||||
if(streamFrameViewController.streamMan){
|
||||
// NSLog(@"setNeedRequeuing %f", CACurrentMediaTime());
|
||||
@@ -1186,7 +1243,7 @@ static NSMutableSet* hostList;
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.navigationItem.leftBarButtonItems = @[];
|
||||
self.navigationItem.leftBarButtonItems = @[_profilesButton];
|
||||
[settingsViewController updateTheme];
|
||||
}
|
||||
|
||||
@@ -1552,7 +1609,27 @@ static NSMutableSet* hostList;
|
||||
[_settingsButton setTitle:[LocalizationHelper localizedStringForKey:@"Settings"]];
|
||||
}
|
||||
|
||||
[_profilesButton setTarget:self];
|
||||
[_profilesButton setAction:@selector(profilesButtonTapped)];
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[_profilesButton setTitle:nil];
|
||||
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:GenericUtils.liquidGlassEnabled ? 20.5 : 23 weight:UIImageSymbolWeightRegular ];
|
||||
UIImage *image = [[UIImage systemImageNamed:@"gamecontroller.circle" withConfiguration:config] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||
[_profilesButton setImage:image];
|
||||
_profilesButton.imageInsets = GenericUtils.liquidGlassEnabled ? UIEdgeInsetsMake(0, 0, 0, 0.55) : UIEdgeInsetsMake(10, 10, 0, 0);
|
||||
if(GenericUtils.liquidGlassEnabled){
|
||||
// if(@available(iOS 26.0, *)) _settingsButton.hidesSharedBackground = YES;
|
||||
_profilesButton.tintColor = ThemeManager.appPrimaryColor;
|
||||
}
|
||||
} else {
|
||||
[_profilesButton setTitle:[LocalizationHelper localizedStringForKey:@"Settings"]];
|
||||
}
|
||||
|
||||
if (@available(iOS 26.0, *)) {
|
||||
_settingsButton.sharesBackground = false;
|
||||
_profilesButton.sharesBackground = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Set the host name button action. When it's tapped, it'll show the host selection view.
|
||||
|
||||
@@ -818,7 +818,7 @@ const int FrontViewPositionNone = 0xff;
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
Settings *currentSettings = [dataMan retrieveSettings];
|
||||
|
||||
NSLog(@"orientation unlocked: %d", currentSettings.unlockDisplayOrientation);
|
||||
// NSLog(@"orientation unlocked: %d", currentSettings.unlockDisplayOrientation);
|
||||
|
||||
if(currentSettings.unlockDisplayOrientation) return UIInterfaceOrientationMaskAll;
|
||||
else return [self isIPhone] ? UIInterfaceOrientationMaskLandscape : [self getCurrentOrientation];
|
||||
|
||||
@@ -157,7 +157,9 @@
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *mapGyroToSelector;
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UIStackView *gyroToStickSwitchStack;
|
||||
@property (weak, nonatomic) IBOutlet UIStackView *yawPitchToRightStickStack;
|
||||
@property (strong, nonatomic) IBOutlet UISwitch *yawPitchToRightStickSwitch;
|
||||
@property (weak, nonatomic) IBOutlet UIStackView *rollToLeftStickStack;
|
||||
@property (strong, nonatomic) IBOutlet UISwitch *rollToLeftStickSwitch;
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UIStackView *yawPitchSensitivityStack;
|
||||
@@ -309,5 +311,6 @@
|
||||
- (void)hideDynamicLabelsWhenOverlapped:(UIView* )view;
|
||||
- (void)setHidden:(BOOL)hidden forStack:(UIStackView* )stack;
|
||||
- (void)updateCodecDependentSwitches;
|
||||
- (void)mainFrameGameProfileButtonTapped;
|
||||
|
||||
@end
|
||||
|
||||
@@ -354,6 +354,12 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
|
||||
- (void)reloadGameProfileConfigs{
|
||||
oscProfile = [oscProfileMan getSelectedProfile];
|
||||
|
||||
[self.pointerVelocityModeDividerSlider setValue: (uint8_t)(oscProfile.pointerVelocityModeDivider * 100) animated:NO]; // Load old setting.
|
||||
[self pointerVelocityModeDividerSliderMoved:self.pointerVelocityModeDividerSlider];
|
||||
|
||||
[self.touchPointerVelocityFactorSlider setValue: [self map_SliderValue_fromVelocFactor: oscProfile.touchPointerVelocityFactor] animated:NO]; // Load old setting.
|
||||
[self touchPointerVelocityFactorSliderMoved:self.touchPointerVelocityFactorSlider];
|
||||
|
||||
self.controllerGyroSwitchButtonSetter.selectedSegmentIndex = oscProfile.controllerGyroSwitchMode;
|
||||
if(self.controllerGyroSwitchButtonSetter.selectedSegmentIndex != ControllerGyroSwitchDisabled){
|
||||
@@ -401,6 +407,7 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
|
||||
- (void)saveGameProfileConfigs{
|
||||
|
||||
CGFloat touchPointerVelocityFactorPercent = [self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value];
|
||||
CGFloat yawSensitivityPercent = [self map_velocFactorDisplay_fromSliderValue:self.yawSensitivitySlider.value];
|
||||
CGFloat pitchSensitivityPercent = [self map_velocFactorDisplay_fromSliderValue:self.pitchSensitivitySlider.value];
|
||||
CGFloat rollSensitivityPercent = [self map_velocFactorDisplay_fromSliderValue:self.rollSensitivitySlider.value];
|
||||
@@ -408,6 +415,8 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
bool configNotChanged = (oscProfile.mapGyroTo == self.mapGyroToSelector.selectedSegmentIndex
|
||||
&& oscProfile.yawPitchToRightStick == self.yawPitchToRightStickSwitch.isOn
|
||||
&& oscProfile.rollToLeftStick == self.rollToLeftStickSwitch.isOn
|
||||
&& (int16_t)(oscProfile.pointerVelocityModeDivider*100) == (int16_t)self.pointerVelocityModeDividerSlider.value
|
||||
&& (int16_t)(oscProfile.touchPointerVelocityFactor*100) == (int16_t)touchPointerVelocityFactorPercent
|
||||
&& (int16_t)(oscProfile.gyroSensitivityYaw*100) == (int16_t)yawSensitivityPercent
|
||||
&& (int16_t)(oscProfile.gyroSensitivityPitch*100) == (int16_t)pitchSensitivityPercent
|
||||
&& (int16_t)(oscProfile.gyroSensitivityRoll*100) == (int16_t)rollSensitivityPercent
|
||||
@@ -427,6 +436,8 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
|
||||
if(!configNotChanged){
|
||||
oscProfile = [oscProfileMan getSelectedProfile];
|
||||
oscProfile.pointerVelocityModeDivider = self.pointerVelocityModeDividerSlider.value/100;
|
||||
oscProfile.touchPointerVelocityFactor = touchPointerVelocityFactorPercent/100;
|
||||
oscProfile.mapGyroTo = self.mapGyroToSelector.selectedSegmentIndex;
|
||||
oscProfile.yawPitchToRightStick = self.yawPitchToRightStickSwitch.isOn;
|
||||
oscProfile.rollToLeftStick = self.rollToLeftStickSwitch.isOn;
|
||||
@@ -482,6 +493,11 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
selector:@selector(reloadGameProfileConfigs)
|
||||
name:@"OscLayoutCloseNotification"
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(reloadGameProfileConfigs)
|
||||
name:@"OscLayoutProfileSelctedInTableView"
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(pencilProPurchaseAborted:)
|
||||
name:@"PencilProPurchaseAbortedNotification"
|
||||
@@ -682,6 +698,7 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
}
|
||||
|
||||
- (UILabel* )findDynamicLabelFromStack:(UIStackView* )stack{
|
||||
|
||||
UILabel* label;
|
||||
for(UIView *view in stack.subviews){
|
||||
if([view isKindOfClass:[UILabel class]] && [view.accessibilityIdentifier isEqualToString:@"dynamicLabel"]) label = (UILabel* )view;
|
||||
@@ -773,15 +790,15 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addSetting:(UIStackView *)stack ofId:(NSString* )identifier withInfoTag:(BOOL)attached withDynamicLabel:(BOOL)added to:(MenuSectionView* )menuSection{
|
||||
- (void)addSetting:(UIStackView *)stack ofId:(NSString* )identifier to:(MenuSectionView* )menuSection{
|
||||
stack.accessibilityIdentifier = identifier;
|
||||
[_settingStackDict setObject:stack forKey:identifier];
|
||||
if(attached) [self attachInfoTagForStack:stack];
|
||||
if(added) [self addDynamicLabelForStack:stack];
|
||||
if(stack.hasInfoTag || stack.isGameProfileSetting) [self attachInfoTagForStack:stack];
|
||||
if(stack.hasDynamicLabel) [self addDynamicLabelForStack:stack];
|
||||
[menuSection addSubStackView:stack];
|
||||
}
|
||||
|
||||
- (void)layoutSections{
|
||||
- (void)layoutSections {
|
||||
videoSection = [[MenuSectionView alloc] init];
|
||||
videoSection.delegate = self;
|
||||
videoSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Video"];
|
||||
@@ -789,21 +806,42 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[videoSection setSectionWithIcon:[UIImage systemImageNamed:@"waveform"] size:13 sizeConstraint:-15];
|
||||
}
|
||||
[self addSetting:self.resolutionStack ofId:@"resolutionStack" withInfoTag:NO withDynamicLabel:YES to:videoSection];
|
||||
[self addSetting:self.fpsStack ofId:@"fpsStack" withInfoTag:NO withDynamicLabel:NO to:videoSection];
|
||||
[self addSetting:self.bitrateStack ofId:@"bitrateStack" withInfoTag:YES withDynamicLabel:YES to:videoSection];
|
||||
[self addSetting:self.codecStack ofId:@"codecStack" withInfoTag:NO withDynamicLabel:NO to:videoSection];
|
||||
[self addSetting:self.hdrStack ofId:@"hdrStack" withInfoTag:![Utils hdrSupported] withDynamicLabel:NO to:videoSection];
|
||||
[self addSetting:self.yuv444Stack ofId:@"yuv444Stack" withInfoTag:YES withDynamicLabel:NO to:videoSection];
|
||||
[self addSetting:self.sdrPerformanceWorkaroundStack ofId:@"sdrPerformanceWorkaroundStack" withInfoTag:YES withDynamicLabel:NO to:videoSection];
|
||||
[self addSetting:self.framePacingStack ofId:@"framePacingStack" withInfoTag:YES withDynamicLabel:NO to:videoSection];
|
||||
[self addSetting:self.frameQueueSizeStack ofId:@"frameQueueSizeStack" withInfoTag:NO withDynamicLabel:YES to:videoSection];
|
||||
[videoSection addToParentStack:_parentStack];
|
||||
[self addSetting:self.asyncFrameDequeueStack ofId:@"asyncFrameDequeueStack" withInfoTag:YES withDynamicLabel:NO to:videoSection];
|
||||
// [videoSection setExpanded:NO];
|
||||
[self addSetting:self.pipStack ofId:@"pipStack" withInfoTag:YES withDynamicLabel:NO to:videoSection];
|
||||
|
||||
|
||||
self.resolutionStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.resolutionStack ofId:@"resolutionStack" to:videoSection];
|
||||
|
||||
[self addSetting:self.fpsStack ofId:@"fpsStack" to:videoSection];
|
||||
|
||||
self.bitrateStack.hasInfoTag = YES;
|
||||
self.bitrateStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.bitrateStack ofId:@"bitrateStack" to:videoSection];
|
||||
|
||||
[self addSetting:self.codecStack ofId:@"codecStack" to:videoSection];
|
||||
|
||||
self.hdrStack.hasInfoTag = ![Utils hdrSupported];
|
||||
[self addSetting:self.hdrStack ofId:@"hdrStack" to:videoSection];
|
||||
|
||||
self.yuv444Stack.hasInfoTag = YES;
|
||||
[self addSetting:self.yuv444Stack ofId:@"yuv444Stack" to:videoSection];
|
||||
|
||||
self.sdrPerformanceWorkaroundStack.hasInfoTag = YES;
|
||||
[self addSetting:self.sdrPerformanceWorkaroundStack ofId:@"sdrPerformanceWorkaroundStack" to:videoSection];
|
||||
|
||||
self.framePacingStack.hasInfoTag = YES;
|
||||
[self addSetting:self.framePacingStack ofId:@"framePacingStack" to:videoSection];
|
||||
|
||||
self.frameQueueSizeStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.frameQueueSizeStack ofId:@"frameQueueSizeStack" to:videoSection];
|
||||
|
||||
self.asyncFrameDequeueStack.hasInfoTag = YES;
|
||||
[self addSetting:self.asyncFrameDequeueStack ofId:@"asyncFrameDequeueStack" to:videoSection];
|
||||
|
||||
self.pipStack.hasInfoTag = YES;
|
||||
[self addSetting:self.pipStack ofId:@"pipStack" to:videoSection];
|
||||
|
||||
[videoSection addToParentStack:_parentStack];
|
||||
|
||||
|
||||
touchControlSection = [[MenuSectionView alloc] init];
|
||||
touchControlSection.delegate = self;
|
||||
touchControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch Control"];
|
||||
@@ -811,23 +849,48 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[touchControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] size:22 sizeConstraint:-13];
|
||||
}
|
||||
[self addSetting:self.touchModeStack ofId:@"touchModeStack" withInfoTag:YES withDynamicLabel:NO to:touchControlSection];
|
||||
[self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection];
|
||||
[self addSetting:self.pointerVelocityDividerStack ofId:@"pointerVelocityDividerStack" withInfoTag:YES withDynamicLabel:YES to:touchControlSection];
|
||||
[self addSetting:self.pointerVelocityFactorStack ofId:@"pointerVelocityFactorStack" withInfoTag:YES withDynamicLabel:YES to:touchControlSection];
|
||||
[self addSetting:self.delayLeftClickStack ofId:@"delayLeftClickStack" withInfoTag:YES withDynamicLabel:NO to:touchControlSection];
|
||||
[self addSetting:self.passthroughGesturesStack ofId:@"passthroughGesturesStack" withInfoTag:NO withDynamicLabel:NO to:touchControlSection];
|
||||
[self addSetting:self.pinchGestureStack ofId:@"pinchGestureStack" withInfoTag:NO withDynamicLabel:NO to:touchControlSection];
|
||||
[self addSetting:self.ctrlDownForPinchStack ofId:@"ctrlDownForPinchStack" withInfoTag:YES withDynamicLabel:NO to:touchControlSection];
|
||||
[self addSetting:self.scrollSensitivityStack ofId:@"scrollSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection];
|
||||
[self addSetting:self.pinchSensitivityStack ofId:@"pinchSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection];
|
||||
[self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" withInfoTag:NO withDynamicLabel:YES to:touchControlSection];
|
||||
[self addSetting:self.onScreenWidgetStack ofId:@"onScreenWidgetStack" withInfoTag:YES withDynamicLabel:NO to:touchControlSection];
|
||||
[self addSetting:self.buttonVisualFeedbackStack ofId:@"buttonVisualFeedbackStack" withInfoTag:NO withDynamicLabel:NO to:touchControlSection];
|
||||
[self addSetting:self.trackTouchPointStack ofId:@"trackTouchPointStack" withInfoTag:NO withDynamicLabel:NO to:touchControlSection];
|
||||
|
||||
self.touchModeStack.hasInfoTag = YES;
|
||||
[self addSetting:self.touchModeStack ofId:@"touchModeStack" to:touchControlSection];
|
||||
|
||||
self.mousePointerVelocityStack.hasDynamicLabel = YES;
|
||||
// self.mousePointerVelocityStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.mousePointerVelocityStack ofId:@"mousePointerVelocityStack" to:touchControlSection];
|
||||
|
||||
self.pointerVelocityDividerStack.hasInfoTag = YES;
|
||||
self.pointerVelocityDividerStack.isGameProfileSetting = YES;
|
||||
self.pointerVelocityDividerStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.pointerVelocityDividerStack ofId:@"pointerVelocityDividerStack" to:touchControlSection];
|
||||
|
||||
self.pointerVelocityFactorStack.hasInfoTag = YES;
|
||||
self.pointerVelocityFactorStack.isGameProfileSetting = YES;
|
||||
self.pointerVelocityFactorStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.pointerVelocityFactorStack ofId:@"pointerVelocityFactorStack" to:touchControlSection];
|
||||
|
||||
self.delayLeftClickStack.hasInfoTag = YES;
|
||||
[self addSetting:self.delayLeftClickStack ofId:@"delayLeftClickStack" to:touchControlSection];
|
||||
|
||||
[self addSetting:self.passthroughGesturesStack ofId:@"passthroughGesturesStack" to:touchControlSection];
|
||||
[self addSetting:self.pinchGestureStack ofId:@"pinchGestureStack" to:touchControlSection];
|
||||
|
||||
self.ctrlDownForPinchStack.hasInfoTag = YES;
|
||||
[self addSetting:self.ctrlDownForPinchStack ofId:@"ctrlDownForPinchStack" to:touchControlSection];
|
||||
|
||||
self.scrollSensitivityStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.scrollSensitivityStack ofId:@"scrollSensitivityStack" to:touchControlSection];
|
||||
|
||||
self.pinchSensitivityStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.pinchSensitivityStack ofId:@"pinchSensitivityStack" to:touchControlSection];
|
||||
|
||||
self.onScreenWidgetStack.hasInfoTag = YES; // ?????
|
||||
[self addSetting:self.onScreenWidgetStack ofId:@"onScreenWidgetStack" to:touchControlSection];
|
||||
|
||||
[self addSetting:self.buttonVisualFeedbackStack ofId:@"buttonVisualFeedbackStack" to:touchControlSection];
|
||||
[self addSetting:self.trackTouchPointStack ofId:@"trackTouchPointStack" to:touchControlSection];
|
||||
|
||||
[touchControlSection addToParentStack:_parentStack];
|
||||
// [touchAndControlSection setExpanded:NO];
|
||||
|
||||
|
||||
|
||||
controllerSection = [[MenuSectionView alloc] init];
|
||||
controllerSection.delegate = self;
|
||||
controllerSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Controller"];
|
||||
@@ -835,76 +898,167 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[controllerSection setSectionWithIcon:[UIImage systemImageNamed:@"gamecontroller"] size:30 sizeConstraint:-10];
|
||||
}
|
||||
[self addSetting:self.swapAbxyStack ofId:@"swapAbaxyStack" withInfoTag:NO withDynamicLabel:NO to:controllerSection];
|
||||
[self addSetting:self.hapticEngineStack ofId:@"hapticEngineStack" withInfoTag:NO withDynamicLabel:NO to:controllerSection];
|
||||
[self addSetting:self.emulatedControllerTypeStack ofId:@"emulatedControllerTypeStack" withInfoTag:YES withDynamicLabel:NO to:controllerSection];
|
||||
[self addSetting:self.gyroModeStack ofId:@"gyroModeStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
|
||||
[self addSetting:self.gyroSensitivityStack ofId:@"gyroSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:controllerSection];
|
||||
[self addSetting:self.leftStickMinOffsetStack ofId:@"leftStickMinOffsetStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
|
||||
[self addSetting:self.rightStickMinOffsetStack ofId:@"rightStickMinOffsetStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
|
||||
[self addSetting:self.controllerToMouseStack ofId:@"controllerToMouseStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
|
||||
[self addSetting:self.controllerMouseVelocityStack ofId:@"controllerMouseVelocityStack" withInfoTag:NO withDynamicLabel:YES to:controllerSection];
|
||||
[self addSetting:self.controllerMouseExpoStack ofId:@"controllerMouseExpoStack" withInfoTag:YES withDynamicLabel:YES to:controllerSection];
|
||||
|
||||
[self addSetting:self.swapAbxyStack ofId:@"swapAbaxyStack" to:controllerSection];
|
||||
[self addSetting:self.hapticEngineStack ofId:@"hapticEngineStack" to:controllerSection];
|
||||
|
||||
self.emulatedControllerTypeStack.hasInfoTag = YES;
|
||||
// self.emulatedControllerTypeStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.emulatedControllerTypeStack ofId:@"emulatedControllerTypeStack" to:controllerSection];
|
||||
|
||||
self.gyroModeStack.hasInfoTag = YES;
|
||||
// self.gyroModeStack.isGameProfileSetting = YES;
|
||||
self.gyroModeStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.gyroModeStack ofId:@"gyroModeStack" to:controllerSection];
|
||||
|
||||
self.gyroSensitivityStack.hasDynamicLabel = YES;
|
||||
// self.gyroSensitivityStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.gyroSensitivityStack ofId:@"gyroSensitivityStack" to:controllerSection];
|
||||
|
||||
self.leftStickMinOffsetStack.hasInfoTag = YES;
|
||||
self.leftStickMinOffsetStack.isGameProfileSetting = YES;
|
||||
self.leftStickMinOffsetStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.leftStickMinOffsetStack ofId:@"leftStickMinOffsetStack" to:controllerSection];
|
||||
|
||||
self.rightStickMinOffsetStack.hasInfoTag = YES;
|
||||
self.rightStickMinOffsetStack.isGameProfileSetting = YES;
|
||||
self.rightStickMinOffsetStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.rightStickMinOffsetStack ofId:@"rightStickMinOffsetStack" to:controllerSection];
|
||||
|
||||
self.controllerToMouseStack.hasInfoTag = YES;
|
||||
self.controllerToMouseStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.controllerToMouseStack ofId:@"controllerToMouseStack" to:controllerSection];
|
||||
|
||||
self.controllerMouseVelocityStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.controllerMouseVelocityStack ofId:@"controllerMouseVelocityStack" to:controllerSection];
|
||||
|
||||
self.controllerMouseExpoStack.hasInfoTag = YES;
|
||||
self.controllerMouseExpoStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.controllerMouseExpoStack ofId:@"controllerMouseExpoStack" to:controllerSection];
|
||||
|
||||
[controllerSection addToParentStack:_parentStack];
|
||||
|
||||
|
||||
|
||||
motionControlSection = [[MenuSectionView alloc] init];
|
||||
motionControlSection.delegate = self;
|
||||
motionControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Motion Control"];
|
||||
motionControlSection.identifier = @"SettingsSectionMotionControl";
|
||||
if (@available(iOS 13.0, *)) [motionControlSection setSectionWithIcon:[UIImage imageNamed:@"gyroscope"] size:23 sizeConstraint:-18];
|
||||
[self addSetting:self.controllerGyroSwitchButtonStack ofId:@"controllerGyroSwitchButtonStack" withInfoTag:YES withDynamicLabel:YES to:motionControlSection];
|
||||
[self addSetting:self.reverseHoldButtonStack ofId:@"reverseHoldButtonStack" withInfoTag:YES withDynamicLabel:YES to:motionControlSection];
|
||||
[self addSetting:self.mapGyroToStack ofId:@"mapGyroToStack" withInfoTag:YES withDynamicLabel:NO to:motionControlSection];
|
||||
[self addSetting:self.gyroToStickSwitchStack ofId:@"gyroToStickStack" withInfoTag:NO withDynamicLabel:NO to:motionControlSection];
|
||||
[self addSetting:self.yawPitchSensitivityStack ofId:@"yawPitchSensitivityStack" withInfoTag:NO withDynamicLabel:NO to:motionControlSection];
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[motionControlSection setSectionWithIcon:[UIImage imageNamed:@"gyroscope"] size:23 sizeConstraint:-18];
|
||||
}
|
||||
|
||||
self.controllerGyroSwitchButtonStack.hasInfoTag = YES;
|
||||
self.controllerGyroSwitchButtonStack.isGameProfileSetting = YES;
|
||||
self.controllerGyroSwitchButtonStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.controllerGyroSwitchButtonStack ofId:@"controllerGyroSwitchButtonStack" to:motionControlSection];
|
||||
|
||||
self.reverseHoldButtonStack.hasInfoTag = YES;
|
||||
self.reverseHoldButtonStack.isGameProfileSetting = YES;
|
||||
self.reverseHoldButtonStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.reverseHoldButtonStack ofId:@"reverseHoldButtonStack" to:motionControlSection];
|
||||
|
||||
self.mapGyroToStack.hasInfoTag = YES;
|
||||
self.mapGyroToStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.mapGyroToStack ofId:@"mapGyroToStack" to:motionControlSection];
|
||||
|
||||
// self.gyroToStickSwitchStack.isGameProfileSetting = YES;
|
||||
self.yawPitchToRightStickStack.isGameProfileSetting = YES;
|
||||
[self attachInfoTagForStack:self.yawPitchToRightStickStack];
|
||||
self.rollToLeftStickStack.isGameProfileSetting = YES;
|
||||
[self attachInfoTagForStack:self.rollToLeftStickStack];
|
||||
[self addSetting:self.gyroToStickSwitchStack ofId:@"gyroToStickStack" to:motionControlSection];
|
||||
|
||||
self.yawSensitivityStack.isGameProfileSetting = YES;
|
||||
self.pitchSensitivityStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.yawPitchSensitivityStack ofId:@"yawPitchSensitivityStack" to:motionControlSection];
|
||||
[self attachInfoTagForStack:self.yawSensitivityStack];
|
||||
[self addDynamicLabelForStack:self.yawSensitivityStack];
|
||||
[self attachInfoTagForStack:self.pitchSensitivityStack];
|
||||
[self addDynamicLabelForStack:self.pitchSensitivityStack];
|
||||
[self addSetting:self.rollSensitivityStack ofId:@"rollSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:motionControlSection];
|
||||
[self addSetting:self.gyroToStickMinOffsetStack ofId:@"gyroToStickMinOffsetStack" withInfoTag:NO withDynamicLabel:YES to:motionControlSection];
|
||||
[self addSetting:self.synthPhysicalInputStack ofId:@"synthPhysicalInputStack" withInfoTag:NO withDynamicLabel:NO to:motionControlSection];
|
||||
|
||||
self.rollSensitivityStack.isGameProfileSetting = YES;
|
||||
self.rollSensitivityStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.rollSensitivityStack ofId:@"rollSensitivityStack" to:motionControlSection];
|
||||
|
||||
self.gyroToStickMinOffsetStack.isGameProfileSetting = YES;
|
||||
self.gyroToStickMinOffsetStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.gyroToStickMinOffsetStack ofId:@"gyroToStickMinOffsetStack" to:motionControlSection];
|
||||
|
||||
self.synthPhysicalInputStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.synthPhysicalInputStack ofId:@"synthPhysicalInputStack" to:motionControlSection];
|
||||
|
||||
[motionControlSection addToParentStack:_parentStack];
|
||||
|
||||
|
||||
|
||||
|
||||
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
|
||||
bool loadPencilSection = ([bundleId isEqualToString:@"com.voidlink.iOS"]
|
||||
|| [bundleId isEqualToString:@"com.voidlinkextreme.iOS"]
|
||||
|| [bundleId isEqualToString:@"com.voidlink.tf.debug10.iOS"]);
|
||||
|
||||
if([GenericUtils isIPad] && loadPencilSection){
|
||||
MenuSectionView* pencilSection = [[MenuSectionView alloc] init];
|
||||
if ([GenericUtils isIPad] && loadPencilSection) {
|
||||
MenuSectionView *pencilSection = [[MenuSectionView alloc] init];
|
||||
pencilSection.delegate = self;
|
||||
pencilSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Drawing Toolkit"];
|
||||
pencilSection.identifier = @"SettingsSectionPencil";
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[pencilSection setSectionWithIcon:[UIImage systemImageNamed:@"pencil.and.outline"] size:19 weight:UIImageSymbolWeightHeavy sizeConstraint:-16.5];
|
||||
}
|
||||
[self addSetting:self.pencilTickStack ofId:@"pencilTickStack" withInfoTag:YES withDynamicLabel:NO to:pencilSection];
|
||||
[self addSetting:self.pencilTickIntervalStack ofId:@"pencilTickIntervalStack" withInfoTag:NO withDynamicLabel:YES to:pencilSection];
|
||||
[self addSetting:self.pressureCurveStack ofId:@"pressureCurveStack" withInfoTag:NO withDynamicLabel:NO to:pencilSection];
|
||||
[self addSetting:self.doubleTapShortcutStack ofId:@"doubleTapShortcutStack" withInfoTag:YES withDynamicLabel:NO to:pencilSection];
|
||||
[self addSetting:self.squeezeShortcutStack ofId:@"squeezeShortcutStack" withInfoTag:YES withDynamicLabel:NO to:pencilSection];
|
||||
[self addSetting:self.hoverModeStack ofId:@"hoverModeStack" withInfoTag:YES withDynamicLabel:NO to:pencilSection];
|
||||
[self addSetting:self.pencilPausesNativeTouchStack ofId:@"pencilPausesNativeTouchStack" withInfoTag:NO withDynamicLabel:NO to:pencilSection];
|
||||
[self addSetting:self.disablePencilSlideGestureStack ofId:@"disablePencilSlideGestureStack" withInfoTag:NO withDynamicLabel:NO to:pencilSection];
|
||||
|
||||
self.pencilTickStack.hasInfoTag = YES;
|
||||
[self addSetting:self.pencilTickStack ofId:@"pencilTickStack" to:pencilSection];
|
||||
|
||||
self.pencilTickIntervalStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.pencilTickIntervalStack ofId:@"pencilTickIntervalStack" to:pencilSection];
|
||||
|
||||
self.pressureCurveStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.pressureCurveStack ofId:@"pressureCurveStack" to:pencilSection];
|
||||
|
||||
self.doubleTapShortcutStack.isGameProfileSetting = YES;
|
||||
self.doubleTapShortcutStack.hasInfoTag = YES;
|
||||
[self addSetting:self.doubleTapShortcutStack ofId:@"doubleTapShortcutStack" to:pencilSection];
|
||||
|
||||
self.squeezeShortcutStack.isGameProfileSetting = YES;
|
||||
self.squeezeShortcutStack.hasInfoTag = YES;
|
||||
[self addSetting:self.squeezeShortcutStack ofId:@"squeezeShortcutStack" to:pencilSection];
|
||||
|
||||
self.hoverModeStack.isGameProfileSetting = YES;
|
||||
self.hoverModeStack.hasInfoTag = YES;
|
||||
[self addSetting:self.hoverModeStack ofId:@"hoverModeStack" to:pencilSection];
|
||||
|
||||
self.pencilPausesNativeTouchStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.pencilPausesNativeTouchStack ofId:@"pencilPausesNativeTouchStack" to:pencilSection];
|
||||
|
||||
self.disablePencilSlideGestureStack.isGameProfileSetting = YES;
|
||||
[self addSetting:self.disablePencilSlideGestureStack ofId:@"disablePencilSlideGestureStack" to:pencilSection];
|
||||
|
||||
[pencilSection addToParentStack:_parentStack];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
MenuSectionView *gesturesSection = [[MenuSectionView alloc] init];
|
||||
gesturesSection.delegate = self;
|
||||
gesturesSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Gestures"];
|
||||
gesturesSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Gestures"];
|
||||
gesturesSection.identifier = @"SettingsSectionGestures";
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[gesturesSection setSectionWithIcon:[UIImage systemImageNamed:@"hand.draw"] size:23 sizeConstraint:-11.3];
|
||||
}
|
||||
|
||||
[self addSetting:self.softKeyboardGestureStack ofId:@"softKeyboardGestureStack" withInfoTag:YES withDynamicLabel:NO to:gesturesSection];
|
||||
[self addSetting:self.slideToSettingsScreenEdgeStack ofId:@"slideToSettingsScreenEdgeStack" withInfoTag:NO withDynamicLabel:NO to:gesturesSection];
|
||||
[self addSetting:self.slideToToolboxScreenEdgeStack ofId:@"slideToToolboxScreenEdgeStack" withInfoTag:NO withDynamicLabel:NO to:gesturesSection];
|
||||
[self addSetting:self.slideToSettingsDistanceStack ofId:@"slideToSettingsDistanceStack" withInfoTag:YES withDynamicLabel:YES to:gesturesSection];
|
||||
[self addSetting:self.edgeSlidingSensitivityStack ofId:@"edgeSlidingSensitivityStack" withInfoTag:YES withDynamicLabel:YES to:gesturesSection];
|
||||
|
||||
self.softKeyboardGestureStack.hasInfoTag = YES;
|
||||
[self addSetting:self.softKeyboardGestureStack ofId:@"softKeyboardGestureStack" to:gesturesSection];
|
||||
|
||||
[self addSetting:self.slideToSettingsScreenEdgeStack ofId:@"slideToSettingsScreenEdgeStack" to:gesturesSection];
|
||||
[self addSetting:self.slideToToolboxScreenEdgeStack ofId:@"slideToToolboxScreenEdgeStack" to:gesturesSection];
|
||||
|
||||
self.slideToSettingsDistanceStack.hasInfoTag = YES;
|
||||
self.slideToSettingsDistanceStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.slideToSettingsDistanceStack ofId:@"slideToSettingsDistanceStack" to:gesturesSection];
|
||||
|
||||
self.edgeSlidingSensitivityStack.hasInfoTag = YES;
|
||||
self.edgeSlidingSensitivityStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.edgeSlidingSensitivityStack ofId:@"edgeSlidingSensitivityStack" to:gesturesSection];
|
||||
|
||||
[gesturesSection addToParentStack:_parentStack];
|
||||
// [gesturesSection setExpanded:NO];
|
||||
|
||||
|
||||
MenuSectionView *peripheralSection = [[MenuSectionView alloc] init];
|
||||
peripheralSection.delegate = self;
|
||||
@@ -913,17 +1067,21 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[peripheralSection setSectionWithIcon:[UIImage imageNamed:@"cable.connector.video"] size:20 sizeConstraint:-16.9];
|
||||
}
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[self addSetting:self.externalDisplayModeStack ofId:@"externalDisplayModeStack" withInfoTag:YES withDynamicLabel:NO to:peripheralSection];
|
||||
}
|
||||
[self addSetting:self.localMousePointerModeStack ofId:@"localMousePointerModeStack" withInfoTag:YES withDynamicLabel:NO to:peripheralSection];
|
||||
[self addSetting:self.reverseMouseWheelDirectionStack ofId:@"reverseMouseWheelDirectionStack" withInfoTag:NO withDynamicLabel:NO to:peripheralSection];
|
||||
[self addSetting:self.citrixX1MouseStack ofId:@"citrixX1MouseStack" withInfoTag:NO withDynamicLabel:NO to:peripheralSection];
|
||||
[peripheralSection addToParentStack:_parentStack];
|
||||
// [peripheralSection setExpanded:NO];
|
||||
|
||||
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
self.externalDisplayModeStack.hasInfoTag = YES;
|
||||
[self addSetting:self.externalDisplayModeStack ofId:@"externalDisplayModeStack" to:peripheralSection];
|
||||
}
|
||||
|
||||
self.localMousePointerModeStack.hasInfoTag = YES;
|
||||
[self addSetting:self.localMousePointerModeStack ofId:@"localMousePointerModeStack" to:peripheralSection];
|
||||
|
||||
[self addSetting:self.reverseMouseWheelDirectionStack ofId:@"reverseMouseWheelDirectionStack" to:peripheralSection];
|
||||
[self addSetting:self.citrixX1MouseStack ofId:@"citrixX1MouseStack" to:peripheralSection];
|
||||
|
||||
[peripheralSection addToParentStack:_parentStack];
|
||||
|
||||
|
||||
MenuSectionView *audioSection = [[MenuSectionView alloc] init];
|
||||
audioSection.delegate = self;
|
||||
audioSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Audio"];
|
||||
@@ -931,21 +1089,30 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[audioSection setSectionWithIcon:[UIImage imageNamed:@"speaker.wave.2"] size:20 sizeConstraint:-15.7];
|
||||
}
|
||||
|
||||
[self addSetting:self.audioOnPcStack ofId:@"audioOnPcStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
|
||||
[self addSetting:self.localVolumeStack ofId:@"localVolumeStack" withInfoTag:NO withDynamicLabel:YES to:audioSection];
|
||||
[self addSetting:self.redirectMicStack ofId:@"redirectMicStack" withInfoTag:YES withDynamicLabel:NO to:audioSection];
|
||||
[self addSetting:self.useBuiltinMicStack ofId:@"useBuiltinMicStack" withInfoTag:YES withDynamicLabel:NO to:audioSection];
|
||||
[self addSetting:self.micVolumeStack ofId:@"micVolumeStack" withInfoTag:NO withDynamicLabel:YES to:audioSection];
|
||||
[self addSetting:self.duckOtherAppStack ofId:@"duckOtherAppStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
|
||||
[self addSetting:self.muteInBackgroundStack ofId:@"muteInBackgroundStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
|
||||
// [self addSetting:self.audioEngineStack ofId:@"audioEngineStack" withInfoTag:YES withDynamicLabel:NO to:audioSection];
|
||||
// cancel audio engine selector due to system engine is unable to playback multi-channel audio
|
||||
[self addSetting:self.audioConfigStack ofId:@"audioConfigStack" withInfoTag:YES withDynamicLabel:NO to:audioSection];
|
||||
[audioSection addToParentStack:_parentStack];
|
||||
// [audioSection setExpanded:NO];
|
||||
|
||||
|
||||
[self addSetting:self.audioOnPcStack ofId:@"audioOnPcStack" to:audioSection];
|
||||
|
||||
self.localVolumeStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.localVolumeStack ofId:@"localVolumeStack" to:audioSection];
|
||||
|
||||
self.redirectMicStack.hasInfoTag = YES;
|
||||
[self addSetting:self.redirectMicStack ofId:@"redirectMicStack" to:audioSection];
|
||||
|
||||
self.useBuiltinMicStack.hasInfoTag = YES;
|
||||
[self addSetting:self.useBuiltinMicStack ofId:@"useBuiltinMicStack" to:audioSection];
|
||||
|
||||
self.micVolumeStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.micVolumeStack ofId:@"micVolumeStack" to:audioSection];
|
||||
|
||||
[self addSetting:self.duckOtherAppStack ofId:@"duckOtherAppStack" to:audioSection];
|
||||
[self addSetting:self.muteInBackgroundStack ofId:@"muteInBackgroundStack" to:audioSection];
|
||||
|
||||
self.audioConfigStack.hasInfoTag = YES;
|
||||
[self addSetting:self.audioConfigStack ofId:@"audioConfigStack" to:audioSection];
|
||||
|
||||
[audioSection addToParentStack:_parentStack];
|
||||
|
||||
|
||||
otherSection = [[MenuSectionView alloc] init];
|
||||
otherSection.delegate = self;
|
||||
otherSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Others"];
|
||||
@@ -953,20 +1120,31 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[otherSection setSectionWithIcon:[UIImage systemImageNamed:@"cube"] size:19.5 sizeConstraint:-17];
|
||||
}
|
||||
[self addSetting:self.statsOverlayStack ofId:@"statsOverlayStack" withInfoTag:NO withDynamicLabel:NO to:otherSection];
|
||||
[self addSetting:self.unlockDisplayOrientationStack ofId:@"unlockDisplayOrientationStack" withInfoTag:YES withDynamicLabel:NO to:otherSection];
|
||||
[self addSetting:self.backgroundSessionTimerStack ofId:@"backgroundSessionTimerStack" withInfoTag:NO withDynamicLabel:YES to:otherSection];
|
||||
[self addSetting:self.appThemeStack ofId:@"appThemeStack" withInfoTag:NO withDynamicLabel:NO to:otherSection];
|
||||
[self addSetting:self.optimizeGamesStack ofId:@"optimizeGamesStack" withInfoTag:YES withDynamicLabel:NO to:otherSection];
|
||||
[self addSetting:self.multiControllerStack ofId:@"multiControllerStack" withInfoTag:NO withDynamicLabel:NO to:otherSection];
|
||||
[self addSetting:self.softKeyboardToolbarStack ofId:@"softKeyboardToolbarStack" withInfoTag:NO withDynamicLabel:NO to:otherSection];
|
||||
[self addSetting:self.softKeyboardHeightStack ofId:@"softKeyboardHeightStack" withInfoTag:YES withDynamicLabel:NO to:otherSection];
|
||||
[self addSetting:self.rememberFoldStateStack ofId:@"rememberFoldStateStack" withInfoTag:NO withDynamicLabel:NO to:otherSection];
|
||||
|
||||
[self addSetting:self.statsOverlayStack ofId:@"statsOverlayStack" to:otherSection];
|
||||
|
||||
self.unlockDisplayOrientationStack.hasInfoTag = YES;
|
||||
[self addSetting:self.unlockDisplayOrientationStack ofId:@"unlockDisplayOrientationStack" to:otherSection];
|
||||
|
||||
self.backgroundSessionTimerStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.backgroundSessionTimerStack ofId:@"backgroundSessionTimerStack" to:otherSection];
|
||||
|
||||
[self addSetting:self.appThemeStack ofId:@"appThemeStack" to:otherSection];
|
||||
|
||||
self.optimizeGamesStack.hasInfoTag = YES;
|
||||
[self addSetting:self.optimizeGamesStack ofId:@"optimizeGamesStack" to:otherSection];
|
||||
|
||||
[self addSetting:self.multiControllerStack ofId:@"multiControllerStack" to:otherSection];
|
||||
[self addSetting:self.softKeyboardToolbarStack ofId:@"softKeyboardToolbarStack" to:otherSection];
|
||||
|
||||
self.softKeyboardHeightStack.hasInfoTag = YES;
|
||||
[self addSetting:self.softKeyboardHeightStack ofId:@"softKeyboardHeightStack" to:otherSection];
|
||||
|
||||
[self addSetting:self.rememberFoldStateStack ofId:@"rememberFoldStateStack" to:otherSection];
|
||||
|
||||
[otherSection addToParentStack:_parentStack];
|
||||
// [otherSection setExpanded:NO];
|
||||
|
||||
|
||||
|
||||
|
||||
experimentalSection = [[MenuSectionView alloc] init];
|
||||
experimentalSection.delegate = self;
|
||||
experimentalSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Experimental"];
|
||||
@@ -974,25 +1152,36 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[experimentalSection setSectionWithIcon:[UIImage imageNamed:@"flask"] size:19 sizeConstraint:-19];
|
||||
}
|
||||
|
||||
[self addSetting:self.touchModeStack2 ofId:@"touchModeStack2" withInfoTag:NO withDynamicLabel:NO to:experimentalSection];
|
||||
// [self.touchModeSelector2 setEnabled:false];
|
||||
[self addSetting:self.touchMoveEventIntervalStack ofId:@"touchMoveEventIntervalStack" withInfoTag:NO withDynamicLabel:YES to:experimentalSection];
|
||||
[self addSetting:self.relativeTouchSlideThresholdStack ofId:@"relativeTouchSlideThresholdStack" withInfoTag:YES withDynamicLabel:YES to:experimentalSection];
|
||||
[self addSetting:self.singleTapSensitivityStack ofId:@"singleTapSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:experimentalSection];
|
||||
[self addSetting:self.leftClickDelayStack ofId:@"leftClickDelayStack" withInfoTag:NO withDynamicLabel:YES to:experimentalSection];
|
||||
[self addSetting:self.renderingBackendStack ofId:@"renderingBackendStack" withInfoTag:YES withDynamicLabel:NO to:experimentalSection];
|
||||
// [self addSetting:self.frameTimebaseStack ofId:@"frameTimebaseStack" withInfoTag:NO withDynamicLabel:NO to:videoSection];
|
||||
[self addSetting:self.fullColorRangeStack ofId:@"fullColorRangeStack" withInfoTag:NO withDynamicLabel:NO to:experimentalSection];
|
||||
[self addSetting:self.performanceGraphStack ofId:@"performanceGraphStack" withInfoTag:YES withDynamicLabel:NO to:experimentalSection];
|
||||
|
||||
[self addSetting:self.touchModeStack2 ofId:@"touchModeStack2" to:experimentalSection];
|
||||
|
||||
self.touchMoveEventIntervalStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.touchMoveEventIntervalStack ofId:@"touchMoveEventIntervalStack" to:experimentalSection];
|
||||
|
||||
self.relativeTouchSlideThresholdStack.hasInfoTag = YES;
|
||||
self.relativeTouchSlideThresholdStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.relativeTouchSlideThresholdStack ofId:@"relativeTouchSlideThresholdStack" to:experimentalSection];
|
||||
|
||||
self.singleTapSensitivityStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.singleTapSensitivityStack ofId:@"singleTapSensitivityStack" to:experimentalSection];
|
||||
|
||||
self.leftClickDelayStack.hasDynamicLabel = YES;
|
||||
[self addSetting:self.leftClickDelayStack ofId:@"leftClickDelayStack" to:experimentalSection];
|
||||
|
||||
self.renderingBackendStack.hasInfoTag = YES;
|
||||
[self addSetting:self.renderingBackendStack ofId:@"renderingBackendStack" to:experimentalSection];
|
||||
|
||||
[self addSetting:self.fullColorRangeStack ofId:@"fullColorRangeStack" to:experimentalSection];
|
||||
|
||||
self.performanceGraphStack.hasInfoTag = YES;
|
||||
[self addSetting:self.performanceGraphStack ofId:@"performanceGraphStack" to:experimentalSection];
|
||||
|
||||
[self addDynamicLabelForStack:self.graphOpacityStack];
|
||||
|
||||
[self addSetting:self.sendDummyEventStack ofId:@"sendDummyEventStack" withInfoTag:YES withDynamicLabel:NO to:experimentalSection];
|
||||
|
||||
[experimentalSection addToParentStack:_parentStack];
|
||||
// [experimentalSection setExpanded:NO];
|
||||
}
|
||||
[self addSetting:self.sendDummyEventStack ofId:@"sendDummyEventStack" to:experimentalSection];
|
||||
|
||||
[experimentalSection addToParentStack:_parentStack];
|
||||
}
|
||||
|
||||
- (void)handleAutoScroll:(CGPoint)location{
|
||||
bool scrollDown = location.y > self.view.bounds.size.height - 100;
|
||||
@@ -1317,8 +1506,14 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
if(button) return;
|
||||
button = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
if (@available(iOS 13.0, *)) {
|
||||
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:13.5 weight:UIImageSymbolWeightBold];
|
||||
[button setImage:[UIImage systemImageNamed:@"info.circle" withConfiguration:config] forState:UIControlStateNormal];
|
||||
if(stack.isGameProfileSetting){
|
||||
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:14.5 weight:UIImageSymbolWeightRegular];
|
||||
[button setImage:[UIImage systemImageNamed:@"gamecontroller.circle" withConfiguration:config] forState:UIControlStateNormal];
|
||||
}
|
||||
else{
|
||||
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:13.5 weight:UIImageSymbolWeightMedium];
|
||||
[button setImage:[UIImage systemImageNamed:@"info.circle" withConfiguration:config] forState:UIControlStateNormal];
|
||||
}
|
||||
} else {
|
||||
[button setTitle:@"info" forState:UIControlStateNormal];
|
||||
button.titleLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightBold];
|
||||
@@ -1342,7 +1537,8 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
NSString* tipText = @"";
|
||||
NSString* onlineDocLink = @"";
|
||||
bool showOnlineDocAction = false;
|
||||
tipText = sender.superview.accessibilityIdentifier;
|
||||
|
||||
tipText = @"";
|
||||
if([sender.superview.accessibilityIdentifier isEqualToString: @"bitrateStack"]){
|
||||
tipText = [LocalizationHelper localizedStringForKey:@"bitrateStackTip"];
|
||||
showOnlineDocAction = false;
|
||||
@@ -1534,6 +1730,12 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
showOnlineDocAction = false;
|
||||
}
|
||||
|
||||
UIStackView* parentStack = (UIStackView* )sender.superview;
|
||||
NSString* edgeSide = self.slideToSettingsScreenEdgeSelector.selectedSegmentIndex == 1 ? [LocalizationHelper localizedStringForKey:@"left"] : [LocalizationHelper localizedStringForKey:@"right"];
|
||||
NSString* slideDist = [NSString stringWithFormat:@"%d%%", (int)(self.slideToMenuDistanceSlider.value*100)];
|
||||
NSString* gameProfileTip = [LocalizationHelper localizedStringForKey:@"gameProfileStackTip", edgeSide, slideDist];
|
||||
tipText = parentStack.isGameProfileSetting ? ([tipText isEqualToString:@""] ? gameProfileTip : [NSString stringWithFormat:@"%@ \n\n%@", gameProfileTip, tipText]) : tipText;
|
||||
|
||||
UIAlertController *tipsAlertController = [UIAlertController alertControllerWithTitle: [LocalizationHelper localizedStringForKey:@"Tips"] message:tipText preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
/*
|
||||
@@ -2103,14 +2305,10 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
//TouchMode & OSC Related Settings:
|
||||
|
||||
// pointer veloc setting, will be enable/disabled by touchMode
|
||||
[self.pointerVelocityModeDividerSlider setValue: (uint8_t)(self->tempSettings.pointerVelocityModeDivider.floatValue * 100) animated:NO]; // Load old setting.
|
||||
[self.pointerVelocityModeDividerSlider addTarget:self action:@selector(pointerVelocityModeDividerSliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
|
||||
[self pointerVelocityModeDividerSliderMoved:self.pointerVelocityModeDividerSlider];
|
||||
|
||||
// init pointer veloc setting, will be enable/disabled by touchMode
|
||||
[self.touchPointerVelocityFactorSlider setValue: [self map_SliderValue_fromVelocFactor: self->tempSettings.touchPointerVelocityFactor.floatValue] animated:NO]; // Load old setting.
|
||||
[self.touchPointerVelocityFactorSlider addTarget:self action:@selector(touchPointerVelocityFactorSliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
|
||||
[self touchPointerVelocityFactorSliderMoved:self.touchPointerVelocityFactorSlider];
|
||||
|
||||
// async native touch event
|
||||
// [self.asyncNativeTouchPrioritySelector setSelectedSegmentIndex:currentSettings.asyncNativeTouchPriority.intValue]; // load old setting of asyncNativeTouchPriority
|
||||
@@ -2743,6 +2941,25 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
[self presentViewController:self.layoutOnScreenControlsVC animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)mainFrameGameProfileButtonTapped{
|
||||
[self saveGameProfileConfigs];
|
||||
|
||||
self.layoutOnScreenControlsVC = [self instantiateOscLayoutViewController];
|
||||
if (self.layoutOnScreenControlsVC == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
// self.layoutOnScreenControlsVC.view.backgroundColor = [UIColor colorWithWhite:0.55 alpha:1.0];
|
||||
self.layoutOnScreenControlsVC.view.backgroundColor = UIColor.clearColor;
|
||||
self.layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
||||
self.layoutOnScreenControlsVC.profileTableLoadingMode = OSCProfilesTableViewLoadingModeSelectProfileFromMainFrame;
|
||||
[self presentViewController:self.layoutOnScreenControlsVC animated:NO completion:^{
|
||||
[self->_layoutOnScreenControlsVC presentProfilesTableViewWithLoadingMode:OSCProfilesTableViewLoadingModeSelectProfileFromMainFrame];
|
||||
}];
|
||||
_layoutOnScreenControlsVC.toolbarStackView.hidden = true;
|
||||
_layoutOnScreenControlsVC.toolbarRootView.hidden = true;
|
||||
}
|
||||
|
||||
- (LayoutOnScreenControlsViewController *)instantiateOscLayoutViewController {
|
||||
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
||||
NSString *storyboardName = isIPhone ? @"iPhone" : @"iPad";
|
||||
@@ -2758,8 +2975,11 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
|
||||
LayoutOnScreenControlsViewController *layoutViewController = (LayoutOnScreenControlsViewController *)viewController;
|
||||
if (!isIPhone) {
|
||||
layoutViewController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
// layoutViewController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
}
|
||||
|
||||
layoutViewController.toolbarStackView.hidden = false;
|
||||
layoutViewController.toolbarRootView.hidden = false;
|
||||
|
||||
return layoutViewController;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
}
|
||||
|
||||
|
||||
- (bool)isOscLayoutToolEnabled{
|
||||
- (bool)isOnScreenWidgetEnabled{
|
||||
return (_settings.touchMode.intValue == RelativeTouch || _settings.touchMode.intValue == NativeTouch || _settings.touchMode.intValue == AbsoluteTouch || _settings.touchMode.intValue == TouchDisabled) && _settings.onscreenControls.intValue == OnScreenControlsLevelCustom;
|
||||
}
|
||||
|
||||
@@ -230,13 +230,13 @@
|
||||
}
|
||||
|
||||
- (void)updateToolboxSpecialEntries{
|
||||
if([self isOscLayoutToolEnabled]){
|
||||
if([self isOnScreenWidgetEnabled]){
|
||||
if(![toolBoxViewController.specialEntries containsObject:@"widgetLayoutTool"]) [toolBoxViewController.specialEntries insertObject:@"widgetLayoutTool" atIndex:0];
|
||||
if(![toolBoxViewController.specialEntries containsObject:@"widgetSwitchTool"]) [toolBoxViewController.specialEntries insertObject:@"widgetSwitchTool" atIndex:1];
|
||||
// if(![toolBoxViewController.specialEntries containsObject:@"widgetSwitchTool"]) [toolBoxViewController.specialEntries insertObject:@"widgetSwitchTool" atIndex:1];
|
||||
}
|
||||
else{
|
||||
[toolBoxViewController.specialEntries removeObject:@"widgetLayoutTool"];
|
||||
[toolBoxViewController.specialEntries removeObject:@"widgetSwitchTool"];
|
||||
// [toolBoxViewController.specialEntries removeObject:@"widgetSwitchTool"];
|
||||
}
|
||||
if(_settings.enablePIP){
|
||||
if(![toolBoxViewController.specialEntries containsObject:@"enterPip"]) [toolBoxViewController.specialEntries addObject:@"enterPip"];
|
||||
@@ -246,9 +246,8 @@
|
||||
NSLog(@"toolBoxViewController.specialEntries %@", toolBoxViewController.specialEntries);
|
||||
}
|
||||
|
||||
- (void)configOscLayoutTool{
|
||||
|
||||
if([self isOscLayoutToolEnabled]){
|
||||
- (void)prepareGameProfileSelector{
|
||||
if(true){
|
||||
/* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */
|
||||
// _layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
|
||||
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
||||
@@ -269,7 +268,7 @@
|
||||
}
|
||||
|
||||
- (void)bringUpToolboxMenu{
|
||||
[self configOscLayoutTool];
|
||||
[self prepareGameProfileSelector];
|
||||
ToolboxViewController* oldToolboxVC = toolBoxViewController;
|
||||
toolBoxViewController = [[ToolboxViewController alloc] init];
|
||||
toolBoxViewController.specialEntryDelegate = self;
|
||||
@@ -301,7 +300,7 @@
|
||||
_slideToToolboxRecognizer.delaysTouchesEnded = NO;
|
||||
[self.view addGestureRecognizer:_slideToToolboxRecognizer];
|
||||
|
||||
if([self isOscLayoutToolEnabled]){
|
||||
if([self isOnScreenWidgetEnabled]){
|
||||
_oscLayoutTapRecoginizer = [[CustomTapGestureRecognizer alloc] initWithTarget:self action:@selector(handleWidgetLayoutGesture)];
|
||||
_oscLayoutTapRecoginizer.numberOfTouchesRequired = _settings.oscLayoutToolFingers.intValue; //tap a predefined number of fingers to open osc layout tool
|
||||
_oscLayoutTapRecoginizer.tapDownTimeThreshold = 0.2;
|
||||
@@ -363,13 +362,13 @@
|
||||
if (reloadSettings) {
|
||||
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
|
||||
}
|
||||
if(!_viewJustLoaded) _oscProfile = [[OSCProfilesManager sharedManager:CGRectZero] getSelectedProfile];
|
||||
_oscProfile = [[OSCProfilesManager sharedManager:CGRectZero] getSelectedProfile];
|
||||
|
||||
overlayLevel = _settings.statsOverlayLevel.intValue;
|
||||
[self setupOverlayView];
|
||||
|
||||
if(viewIsBeingResized) viewIsBeingResized = false;
|
||||
else [self configOscLayoutTool];
|
||||
else [self prepareGameProfileSelector];
|
||||
[self updateToolboxSpecialEntries];
|
||||
[self configGestures];
|
||||
[self configZoomGestureAndAddStreamView];
|
||||
@@ -385,15 +384,14 @@
|
||||
|
||||
if(!_viewJustLoaded) [_controllerSupport updateControllerSupport:self.streamConfig delegate:self];
|
||||
// reload controllerSupport obj, this is mandatory for OSC reload,especially when the stream view is launched without OSC
|
||||
[_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig streamFrameTopLayerView:self.view]; //reinitiate setupStreamView process.
|
||||
// we got self.view passed to streamView class as the topLayerView, will be useful in many cases
|
||||
[self->_streamView reloadOnScreenControlsRealtimeWith:(ControllerSupport*)_controllerSupport
|
||||
andConfig:(StreamConfiguration*)_streamConfig]; //reload OSC here.
|
||||
[_streamView setupStreamViewWithControllerSupport:_controllerSupport interactionDelegate:self streamConfig:self.streamConfig gameProfile:_oscProfile streamFrameTopLayerView:self.view]; //reinitiate setupStreamView process.
|
||||
[self->_streamView reloadOnScreenControlsRealtimeWithControllerSupport:(ControllerSupport*)_controllerSupport
|
||||
streamConfig:(StreamConfiguration*)_streamConfig]; //reload OSC here.
|
||||
|
||||
bool onScreenWidgetSwitched = previousOnScreenWidgetEnabled != [_streamView isOnScreenWidgetEnabled];
|
||||
bool needReload = onScreenWidgetSwitched && !previousOnScreenWidgetEnabled;
|
||||
OnScreenWidgetView.trackPointEnabled = _settings.touchPointTracking;
|
||||
[_streamView reloadOnScreenWidgetViews:_viewJustLoaded||reloadOnscreenWidgets||needReload]; //reload keyboard buttons here. the keyboard widget view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering
|
||||
[_streamView reloadGameProfile:_oscProfile reloadWidgets:reloadOnscreenWidgets||needReload];
|
||||
|
||||
if(onScreenWidgetSwitched && previousOnScreenWidgetEnabled) [_streamView clearOnScreenWidgets];
|
||||
previousOnScreenWidgetEnabled = [_streamView isOnScreenWidgetEnabled];
|
||||
@@ -774,7 +772,7 @@
|
||||
}
|
||||
|
||||
- (void)handleWidgetLayoutGesture{
|
||||
[self configOscLayoutTool];
|
||||
[self prepareGameProfileSelector];
|
||||
[self openWidgetLayoutTool];
|
||||
}
|
||||
|
||||
@@ -797,7 +795,7 @@
|
||||
_layoutOnScreenControlsVC.quickSwitchEnabled = true;
|
||||
_layoutOnScreenControlsVC.toolbarStackView.hidden = true;
|
||||
_layoutOnScreenControlsVC.toolbarRootView.hidden = true;
|
||||
OSCProfilesTableViewLoadingMode loadingMode = pickProfile ? OSCProfilesTableViewLoadingModePickProfile : OSCProfilesTableViewLoadingModeSelectProfile;
|
||||
OSCProfilesTableViewLoadingMode loadingMode = pickProfile ? OSCProfilesTableViewLoadingModePickProfile : OSCProfilesTableViewLoadingModeSelectProfileFromStreamView;
|
||||
[self presentViewController:_layoutOnScreenControlsVC animated:NO completion:^{
|
||||
[self->_layoutOnScreenControlsVC presentProfilesTableViewWithLoadingMode:loadingMode];
|
||||
}];
|
||||
@@ -822,7 +820,8 @@
|
||||
[self->_streamView reloadOnScreenControlsWith:(ControllerSupport*)_controllerSupport
|
||||
andConfig:(StreamConfiguration*)_streamConfig];
|
||||
// [self->_streamView reloadLegacyWidgets];
|
||||
[self->_streamView reloadOnScreenWidgetViews:true]; //update keyboard buttons here
|
||||
[self reConfigStreamViewRealtimeAndReloadSettings:NO reloadOnscreenWidgets:_settings.onscreenControls.intValue == OnScreenControlsLevelCustom];
|
||||
// [self->_streamView reloadGameProfile:nil reloadWidgets:true]; //update keyboard buttons here
|
||||
}
|
||||
|
||||
- (void)setUserInteractionEnabledForStreamView:(bool)enabled{
|
||||
|
||||
@@ -34,8 +34,8 @@ import UIKit
|
||||
|
||||
@objc public var specialEntries : NSMutableArray = ["widgetSwitchTool", "widgetLayoutTool", "bringUpSoftKeyboard", "enterPip", "toggleStatsOverlay", "disconnectAndQuitApp"]
|
||||
private let specialEntryAliasDic : [String:String] = [
|
||||
"widgetSwitchTool":SwiftLocalizationHelper.localizedString(forKey: "[ Switch on-screen widget profile ]"),
|
||||
"widgetLayoutTool":SwiftLocalizationHelper.localizedString(forKey: "[ On-screen widget tool ]"),
|
||||
"widgetSwitchTool":SwiftLocalizationHelper.localizedString(forKey: "[ Switch game profile ]"),
|
||||
"widgetLayoutTool":SwiftLocalizationHelper.localizedString(forKey: "[ Edit on-screen widget layout ]"),
|
||||
"bringUpSoftKeyboard":SwiftLocalizationHelper.localizedString(forKey: "[ Bring up soft keyboard ]"),
|
||||
"enterPip":SwiftLocalizationHelper.localizedString(forKey: "[ Enter picture-in-picture mode ]"),
|
||||
"toggleStatsOverlay":SwiftLocalizationHelper.localizedString(forKey: "[ Toggle stats overlay ]"),
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// UIStackExtension.swift
|
||||
// VoidLink
|
||||
//
|
||||
// Created by Weimin on 2026/4/17.
|
||||
// Copyright © 2026 Moonlight Game Streaming Project. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import ObjectiveC
|
||||
|
||||
private var isGameProfileSettingKey: UInt8 = 0
|
||||
private var hasInfoTagKey: UInt8 = 0
|
||||
private var hasDynamicLabelKey: UInt8 = 0
|
||||
|
||||
extension UIStackView {
|
||||
|
||||
@objc var isGameProfileSetting: Bool {
|
||||
get {
|
||||
return objc_getAssociatedObject(self, &isGameProfileSettingKey) as? Bool ?? false
|
||||
}
|
||||
set {
|
||||
objc_setAssociatedObject(self,
|
||||
&isGameProfileSettingKey,
|
||||
newValue,
|
||||
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
}
|
||||
|
||||
@objc var hasInfoTag: Bool {
|
||||
get {
|
||||
return objc_getAssociatedObject(self, &hasInfoTagKey) as? Bool ?? false
|
||||
}
|
||||
set {
|
||||
objc_setAssociatedObject(self,
|
||||
&hasInfoTagKey,
|
||||
newValue,
|
||||
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
}
|
||||
|
||||
@objc var hasDynamicLabel: Bool {
|
||||
get {
|
||||
return objc_getAssociatedObject(self, &hasDynamicLabelKey) as? Bool ?? false
|
||||
}
|
||||
set {
|
||||
objc_setAssociatedObject(self,
|
||||
&hasDynamicLabelKey,
|
||||
newValue,
|
||||
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1189,6 +1189,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Agc-qg-YgU.title" : {
|
||||
"comment" : "Class = \"UIBarButtonItem\"; title = \"Profiles\"; ObjectID = \"Agc-qg-YgU\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "Profiles"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"aGg-ET-e9F.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Edge Trigger Sensitivity\"; ObjectID = \"aGg-ET-e9F\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
@@ -1280,13 +1292,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "啟用螢幕小工具與外設"
|
||||
"value" : "啟用螢幕控制項與外設"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "啟用螢幕小工具與外設"
|
||||
"value" : "啟用螢幕控制項與外設"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4299,13 +4311,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "螢幕小工具"
|
||||
"value" : "螢幕控制項"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "螢幕小工具"
|
||||
"value" : "螢幕控制項"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5259,13 +5271,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "螢幕小工具佈局"
|
||||
"value" : "螢幕控制項佈局"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "螢幕小工具佈局"
|
||||
"value" : "螢幕控制項佈局"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6047,30 +6059,30 @@
|
||||
}
|
||||
},
|
||||
"uFg-dv-6nT.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Synth Physical Stick Input\"; ObjectID = \"uFg-dv-6nT\";",
|
||||
"comment" : "Class = \"UILabel\"; text = \"Blend Physical Stick Input\"; ObjectID = \"uFg-dv-6nT\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "Synth Physical Stick Input"
|
||||
"value" : "Blend Physical Stick Input"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"state" : "needs_review",
|
||||
"value" : "合成实体摇杆输入"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"state" : "needs_review",
|
||||
"value" : "合成實體搖桿輸入"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"state" : "needs_review",
|
||||
"value" : "合成實體搖桿輸入"
|
||||
}
|
||||
}
|
||||
@@ -6371,13 +6383,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "已收納小工具 "
|
||||
"value" : "已收納控制項 "
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "已收納小工具 "
|
||||
"value" : "已收納控制項 "
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6515,13 +6527,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "輕按任意小工具載入設定(各小工具獨立)"
|
||||
"value" : "輕按任意控制項載入設定(各控制項獨立)"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "輕按任意小工具載入設定(各小工具獨立)"
|
||||
"value" : "輕按任意控制項載入設定(各控制項獨立)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,13 +200,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "啟用螢幕小工具與外設"
|
||||
"value" : "啟用螢幕控制項與外設"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "啟用螢幕小工具與外設"
|
||||
"value" : "啟用螢幕控制項與外設"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -374,13 +374,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "螢幕小工具佈局"
|
||||
"value" : "螢幕控制項佈局"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "螢幕小工具佈局"
|
||||
"value" : "螢幕控制項佈局"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -434,13 +434,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "螢幕小工具"
|
||||
"value" : "螢幕控制項"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "螢幕小工具"
|
||||
"value" : "螢幕控制項"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -902,13 +902,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "輕按任意小工具載入設定(各小工具獨立)"
|
||||
"value" : "輕按任意控制項載入設定(各控制項獨立)"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "輕按任意小工具載入設定(各小工具獨立)"
|
||||
"value" : "輕按任意控制項載入設定(各控制項獨立)"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1580,30 +1580,30 @@
|
||||
}
|
||||
},
|
||||
"Bx3-CM-wet.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Synth Physical Stick Input\"; ObjectID = \"Bx3-CM-wet\";",
|
||||
"comment" : "Class = \"UILabel\"; text = \"Blend Physical Stick Input\"; ObjectID = \"Bx3-CM-wet\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "Synth Physical Stick Input"
|
||||
"value" : "Blend Physical Stick Input"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"state" : "needs_review",
|
||||
"value" : "合成实体摇杆输入"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"state" : "needs_review",
|
||||
"value" : "合成實體搖桿輸入"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"state" : "needs_review",
|
||||
"value" : "合成實體搖桿輸入"
|
||||
}
|
||||
}
|
||||
@@ -1819,6 +1819,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cnk-5b-LLX.title" : {
|
||||
"comment" : "Class = \"UIBarButtonItem\"; title = \"Profiles\"; ObjectID = \"cnk-5b-LLX\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "Profiles"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cti-T5-cSE.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Gesture Slide Distance\"; ObjectID = \"cti-T5-cSE\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
@@ -3098,13 +3110,13 @@
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "已收納小工具 "
|
||||
"value" : "已收納控制項 "
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "已收納小工具 "
|
||||
"value" : "已收納控制項 "
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1613,6 +1613,7 @@ struct WidgetPickerView: View {
|
||||
in: 0...2000,
|
||||
step: 1
|
||||
)
|
||||
.environment(\.colorScheme, .light)
|
||||
.disabled(isShortcutMode)
|
||||
.opacity(isShortcutMode ? 0.45 : 1.0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user