Merge branch 'Moonlight-the-Fried-Fish:noWaterMark' into noWaterMark

This commit is contained in:
Qian23333
2025-02-23 02:18:11 +08:00
committed by GitHub
36 changed files with 654 additions and 339 deletions
+19 -11
View File
@@ -445,11 +445,12 @@ ICAgICAgICAgICAgICA
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="NLH-qN-qCo" userLabel="Statistics Overlay Selector">
<rect key="frame" x="15" y="1843" width="459" height="28"/>
<rect key="frame" x="15" y="1841" width="459" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="No"/>
<segment title="Yes"/>
<segment title="Off"/>
<segment title="Simplified"/>
<segment title="Detailed"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -867,32 +868,32 @@ ICAgICAgICAgICAgICA
<constraint firstItem="YLK-IE-ajS" firstAttribute="centerX" secondItem="fZU-G0-fgM" secondAttribute="centerX" id="xm7-a0-8G7"/>
</constraints>
</view>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="3.8999999999999999" id="Efn-Si-TPp" userLabel="Widget Size Slider">
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="6" id="Efn-Si-TPp" userLabel="Widget Size Slider">
<rect key="frame" x="205" y="87" width="420" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="3.8999999999999999" id="ZOF-sL-e7p" userLabel="Widget Height Slider">
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="6" id="ZOF-sL-e7p" userLabel="Widget Height Slider">
<rect key="frame" x="205" y="122" width="420" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.83299999999999996" minValue="0.23000000000000001" maxValue="0.999" id="ZLL-pE-iZh" userLabel="Widget Alpha Slider">
<rect key="frame" x="205" y="157" width="420" height="31"/>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.83299999999999996" minValue="0.001" maxValue="0.999" id="ZLL-pE-iZh" userLabel="Widget Alpha Slider">
<rect key="frame" x="205" y="157" width="217" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="3.5" id="FRZ-xP-x2r">
<rect key="frame" x="205" y="192" width="420" height="31"/>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="8" id="FRZ-xP-x2r">
<rect key="frame" x="205" y="192" width="591" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Profile:" textAlignment="center" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" id="cRV-Xw-CVi">
<rect key="frame" x="632" y="87" width="163" height="102"/>
<rect key="frame" x="631" y="87" width="163" height="67"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.38551661729999998" green="0.28289704380000003" blue="0.61853601300000005" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -901,7 +902,13 @@ ICAgICAgICAgICAgICA
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="120" minValue="0.0" maxValue="350" id="oc7-kh-RVH">
<rect key="frame" x="205" y="227" width="420" height="31"/>
<rect key="frame" x="205" y="227" width="591" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="8" id="CCy-fw-7og" userLabel="Widget Border Width Slider">
<rect key="frame" x="590" y="157" width="206" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -928,6 +935,7 @@ ICAgICAgICAgICAgICA
<outlet property="trashCanButton" destination="qJs-n8-eV7" id="ubK-qm-Cox"/>
<outlet property="undoButton" destination="F7X-l4-cl3" id="vAI-XQ-hZw"/>
<outlet property="widgetAlphaSlider" destination="ZLL-pE-iZh" id="5OX-P6-YKt"/>
<outlet property="widgetBorderWidthSlider" destination="CCy-fw-7og" id="wio-Ly-MMR"/>
<outlet property="widgetHeightSlider" destination="ZOF-sL-e7p" id="OHK-5i-3RY"/>
<outlet property="widgetSizeSlider" destination="Efn-Si-TPp" id="CgK-cC-Yo0"/>
</connections>
+26 -17
View File
@@ -407,11 +407,12 @@ ICAgICAgICAgICAgIA
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="rdz-eg-2oR" userLabel="Statistics Overlay Selector">
<rect key="frame" x="18" y="1773" width="450" height="28"/>
<rect key="frame" x="18" y="1771" width="450" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="No"/>
<segment title="Yes"/>
<segment title="Off"/>
<segment title="Simplified"/>
<segment title="Detailed"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -731,14 +732,14 @@ ICAgICAgICAgICAgIA
<viewControllerLayoutGuide type="bottom" id="TWA-bF-hnk"/>
</layoutGuides>
<view key="view" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="Mwx-9q-yJJ">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<rect key="frame" x="0.0" y="0.0" width="650" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jnu-63-bcf" customClass="ToolBarContainerView">
<rect key="frame" x="0.0" y="0.0" width="414" height="50"/>
<rect key="frame" x="0.0" y="0.0" width="650" height="50"/>
<subviews>
<stackView opaque="NO" contentMode="scaleAspectFill" alignment="center" spacing="70" translatesAutoresizingMaskIntoConstraints="NO" id="4he-pe-kYB">
<rect key="frame" x="-58" y="0.0" width="530" height="50"/>
<rect key="frame" x="60" y="0.0" width="530" height="50"/>
<subviews>
<button opaque="NO" tag="20" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dhG-Fo-0GK" userLabel="Trash">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
@@ -834,7 +835,7 @@ ICAgICAgICAgICAgIA
</constraints>
</stackView>
<view alpha="0.89999997615814209" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zll-IP-PFt" userLabel="Chevron View">
<rect key="frame" x="181" y="50" width="52" height="25"/>
<rect key="frame" x="299" y="50" width="52" height="25"/>
<subviews>
<imageView clipsSubviews="YES" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ChevronCompactUp" translatesAutoresizingMaskIntoConstraints="NO" id="76O-3K-aa8">
<rect key="frame" x="0.0" y="0.0" width="52" height="25"/>
@@ -870,40 +871,46 @@ ICAgICAgICAgICAgIA
<action selector="closeTapped:" destination="ZYS-Zm-PJs" eventType="touchUpInside" id="U8V-Ry-ym9"/>
</connections>
</button>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="3.8999999999999999" id="DGw-22-vUn" userLabel="Slider">
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="6" id="DGw-22-vUn" userLabel="Slider">
<rect key="frame" x="39" y="82" width="337" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="3.8999999999999999" id="VLi-Mk-ESg" userLabel="Slider">
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.59999999999999998" maxValue="6" id="VLi-Mk-ESg" userLabel="Slider">
<rect key="frame" x="39" y="117" width="337" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.83299999999999996" minValue="0.23000000000000001" maxValue="0.999" id="P6S-oW-Ewb" userLabel="Slider">
<rect key="frame" x="39" y="152" width="337" height="31"/>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.83299999999999996" minValue="0.001" maxValue="0.999" id="P6S-oW-Ewb" userLabel="Slider">
<rect key="frame" x="39" y="152" width="177" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.83300000429153442" minValue="0.23000000417232513" maxValue="0.99900001287460327" id="QXI-Ex-JNV" userLabel="Slider">
<rect key="frame" x="39" y="187" width="337" height="31"/>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="8" id="61X-O2-FOs" userLabel="Slider">
<rect key="frame" x="380" y="152" width="131" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Profile:" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yJC-bq-EOU">
<rect key="frame" x="247" y="82" width="147" height="100"/>
<rect key="frame" x="380" y="83" width="131" height="65"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.38551661729999998" green="0.28289704380000003" blue="0.61853601300000005" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<color key="textColor" red="0.95132106540000005" green="0.97490358349999995" blue="0.99987185000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.83300000429153442" minValue="0.23000000417232513" maxValue="0.99900001287460327" id="OaL-Ph-J4n" userLabel="Slider">
<rect key="frame" x="39" y="222" width="337" height="31"/>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="120" minValue="0.0" maxValue="350" id="OaL-Ph-J4n" userLabel="Slider">
<rect key="frame" x="39" y="222" width="472" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</slider>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="8" id="QXI-Ex-JNV" userLabel="Slider">
<rect key="frame" x="38" y="187" width="473" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -918,6 +925,7 @@ ICAgICAgICAgICAgIA
<constraint firstItem="Jnu-63-bcf" firstAttribute="top" secondItem="Mwx-9q-yJJ" secondAttribute="top" id="wNr-7F-S0i" userLabel="Toolbar Top Constraint iPhone"/>
</constraints>
</view>
<size key="freeformSize" width="650" height="896"/>
<connections>
<outlet property="chevronImageView" destination="76O-3K-aa8" id="yGv-fM-Ohf"/>
<outlet property="chevronView" destination="Zll-IP-PFt" id="MGR-C0-h57"/>
@@ -930,13 +938,14 @@ ICAgICAgICAgICAgIA
<outlet property="trashCanButton" destination="dhG-Fo-0GK" id="dv6-TN-2Bj"/>
<outlet property="undoButton" destination="Pdg-l4-BvF" id="emD-GI-v2v"/>
<outlet property="widgetAlphaSlider" destination="P6S-oW-Ewb" id="cTe-T8-LwU"/>
<outlet property="widgetBorderWidthSlider" destination="61X-O2-FOs" id="Geb-Oq-VtU"/>
<outlet property="widgetHeightSlider" destination="VLi-Mk-ESg" id="6O9-gp-VFZ"/>
<outlet property="widgetSizeSlider" destination="DGw-22-vUn" id="iEF-jl-gJ0"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ORo-HP-JDj" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2640.579710144928" y="1372.7678571428571"/>
<point key="canvasLocation" x="1569.5652173913045" y="1372.7678571428571"/>
</scene>
<!--Profiles Table View Controller-->
<scene sceneID="C7c-yg-gQK">
+2 -1
View File
@@ -41,7 +41,8 @@
btMouseSupport:(BOOL)btMouseSupport
// absoluteTouchMode:(BOOL)absoluteTouchMode
touchMode:(NSInteger)touchMode
statsOverlay:(BOOL)statsOverlay
statsOverlayLevel:(NSInteger)statsOverlayLevel
statsOverlayEnabled:(BOOL)statsOverlayEnabled
unlockDisplayOrientation:(BOOL)unlockDisplayOrientation
resolutionSelected:(NSInteger)resolutionSelected
externalDisplayMode:(NSInteger)externalDisplayMode
+4 -2
View File
@@ -80,7 +80,8 @@
btMouseSupport:(BOOL)btMouseSupport
// absoluteTouchMode:(BOOL)absoluteTouchMode
touchMode:(NSInteger)touchMode
statsOverlay:(BOOL)statsOverlay
statsOverlayLevel:(NSInteger)statsOverlayLevel
statsOverlayEnabled:(BOOL)statsOverlayEnabled
unlockDisplayOrientation:(BOOL)unlockDisplayOrientation
resolutionSelected:(NSInteger)resolutionSelected
externalDisplayMode:(NSInteger)externalDisplayMode
@@ -116,7 +117,8 @@
settingsToSave.btMouseSupport = btMouseSupport;
// settingsToSave.absoluteTouchMode = absoluteTouchMode;
settingsToSave.touchMode = [NSNumber numberWithInteger:(uint16_t)touchMode];
settingsToSave.statsOverlay = statsOverlay;
settingsToSave.statsOverlayEnabled = statsOverlayEnabled;
settingsToSave.statsOverlayLevel = [NSNumber numberWithInteger:(uint16_t)statsOverlayLevel];
settingsToSave.unlockDisplayOrientation = unlockDisplayOrientation;
settingsToSave.resolutionSelected = [NSNumber numberWithInteger:resolutionSelected];
settingsToSave.externalDisplayMode = [NSNumber numberWithInteger:externalDisplayMode];
+2 -1
View File
@@ -53,7 +53,8 @@
@property (nonatomic) BOOL btMouseSupport;
// @property (nonatomic) BOOL absoluteTouchMode;
@property (nonatomic, retain) NSNumber * touchMode;
@property (nonatomic) BOOL statsOverlay;
@property (nonatomic, retain) NSNumber * statsOverlayLevel;
@property (nonatomic) BOOL statsOverlayEnabled;
@property (nonatomic) BOOL liftStreamViewForKeyboard;
@property (nonatomic) BOOL showKeyboardToolbar;
@property (nonatomic) BOOL unlockDisplayOrientation;
+2 -1
View File
@@ -87,7 +87,8 @@
self.btMouseSupport = settings.btMouseSupport;
// self.absoluteTouchMode = settings.absoluteTouchMode;
self.touchMode = settings.touchMode;
self.statsOverlay = settings.statsOverlay;
self.statsOverlayLevel = settings.statsOverlayLevel;
self.statsOverlayEnabled = settings.statsOverlayEnabled;
self.keyboardToggleFingers = settings.keyboardToggleFingers;
self.oscLayoutToolFingers = settings.oscLayoutToolFingers;
self.slideToSettingsScreenEdge = settings.slideToSettingsScreenEdge;
+8
View File
@@ -74,6 +74,14 @@ import UIKit
"OSCL2" : 0,
"OSCR2" : 0]
@objc public static let oscRectangleButtonCmds: [String] = [
"OSCUP",
"OSCDOWN",
"OSCLEFT",
"OSCRIGHT",
"OSCSTART",
"OSCSELECT"]
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "MOUSEPAD", "DPAD", "WASDPAD", "ARROWPAD"]
@objc public static let stickTouchPads: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD"]
@objc public static let nonVectorStickPads: [String] = ["LSPAD", "RSPAD"]
@@ -8,6 +8,7 @@
#import <UIKit/UIKit.h>
#import "OnScreenControls.h"
#import "Moonlight-Swift.h"
NS_ASSUME_NONNULL_BEGIN
/**
@@ -19,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
@property UIView* _view;
@property NSMutableArray *layoutChanges;
@property CALayer *layerBeingDragged;
@property UIViewController *layoutToolVC;
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport
streamConfig:(StreamConfiguration*)streamConfig oscLevel:(int)oscLevel;
@@ -29,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
// - (void) updateGuidelinesForOnScreenWidget:(OnScreenWidgetView* )widget;
@end
NS_ASSUME_NONNULL_END
@@ -11,7 +11,6 @@
#import "OnScreenButtonState.h"
#import "OSCProfilesManager.h"
@interface LayoutOnScreenControls ()
@end
@@ -26,7 +25,16 @@
@synthesize _view;
@synthesize layoutChanges;
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport streamConfig:(StreamConfiguration*)streamConfig oscLevel:(int)oscLevel {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateGuidelinesForOnScreenWidget:)
name:@"OnScreenWidgetMovedByTouch" // This is a special notification for reloading the on screen keyboard buttons. which can't be executed by _oscProfilesTableViewController.needToUpdateOscLayoutTVC code block, and has to be triggered by a notification
object:nil];
_view = view;
_view.multipleTouchEnabled = false;
@@ -101,6 +109,57 @@
[self._view addSubview: verticalGuideline];
}
- (void) updateGuidelinesForOnScreenWidget: (NSNotification *)notification{
/* have guidelines follow wherever the user is touching on the screen */
OnScreenWidgetView* widget = notification.object;
horizontalGuideline.hidden = verticalGuideline.hidden = NO;
horizontalGuideline.center = verticalGuideline.center = CGPointMake(CGRectGetMidX(widget.frame), CGRectGetMidY(widget.frame));
/*
Telegraph to the user whether the horizontal and/or vertical guidelines line up with one or more of the buttons on screen by doing the following:
-Change horizontal guideline color to yellow if its y-position is almost equal to that of one of the buttons on screen.
-Change vertical guideline color to yellow if its x-position is almost equal to that of one of the buttons on screen.
*/
horizontalGuideline.backgroundColor = [UIColor blueColor]; // change horizontal guideline back to blue if it doesn't line up with one of the on screen buttons
for (CALayer *button in self.OSCButtonLayers) { // horizontal guideline position check
if ((layerBeingDragged != button) && !button.isHidden) {
if ((horizontalGuideline.center.y < button.position.y + 1) &&
(horizontalGuideline.center.y > button.position.y - 1)) {
horizontalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
}
for(UIView* view in self.layoutToolVC.view.subviews){
if ([view isKindOfClass:[OnScreenWidgetView class]] && view != widget) {
if ((horizontalGuideline.center.y < view.center.y + 1) && (horizontalGuideline.center.y > view.center.y - 1)) {
horizontalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
}
verticalGuideline.backgroundColor = [UIColor blueColor]; // change vertical guideline back to blue if it doesn't line up with one of the on screen buttons
for (CALayer *button in self.OSCButtonLayers) { // vertical guideline position check
if ((layerBeingDragged != button) && !button.isHidden) {
if ((verticalGuideline.center.x < button.position.x + 1) &&
(verticalGuideline.center.x > button.position.x - 1)) {
verticalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
}
for(UIView* view in self.layoutToolVC.view.subviews){
if ([view isKindOfClass:[OnScreenWidgetView class]] && view != widget) {
if ((verticalGuideline.center.x < view.center.x + 1) && (verticalGuideline.center.x > view.center.x - 1)) {
verticalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
}
}
#pragma mark - Queries
@@ -179,7 +238,7 @@
[[NSNotificationCenter defaultCenter] postNotificationName:@"ControllerCALayerSelected" object:layerBeingDragged]; // inform that a CALayer of onScreen controller has being selected
/* save the name, position, and visibility of button being touched in array in case user wants to undo the change later */
OnScreenButtonState *onScreenButtonState = [[OnScreenButtonState alloc] initWithButtonName:layerBeingDragged.name buttonType:GameControllerButton andPosition:layerBeingDragged.position];
OnScreenButtonState *onScreenButtonState = [[OnScreenButtonState alloc] initWithButtonName:layerBeingDragged.name buttonType:LegacyOscButton andPosition:layerBeingDragged.position];
// add hidden attr here
onScreenButtonState.isHidden = layerBeingDragged.isHidden;
@@ -198,6 +257,7 @@
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:_view];
layerBeingDragged.position = touchLocation; // move object to touch location
/* have guidelines follow wherever the user is touching on the screen */
@@ -206,32 +266,47 @@
/*
Telegraph to the user whether the horizontal and/or vertical guidelines line up with one or more of the buttons on screen by doing the following:
-Change horizontal guideline color to white if its y-position is almost equal to that of one of the buttons on screen.
-Change vertical guideline color to white if its x-position is almost equal to that of one of the buttons on screen.
-Change horizontal guideline color to yellow if its y-position is almost equal to that of one of the buttons on screen.
-Change vertical guideline color to yellow if its x-position is almost equal to that of one of the buttons on screen.
*/
horizontalGuideline.backgroundColor = [UIColor blueColor]; // change horizontal guideline back to blue if it doesn't line up with one of the on screen buttons
for (CALayer *button in self.OSCButtonLayers) { // horizontal guideline position check
if ((layerBeingDragged != button) && !button.isHidden) {
if ((horizontalGuideline.center.y < button.position.y + 1) &&
(horizontalGuideline.center.y > button.position.y - 1)) {
horizontalGuideline.backgroundColor = [UIColor whiteColor];
horizontalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
horizontalGuideline.backgroundColor = [UIColor blueColor]; // change horizontal guideline back to blue if it doesn't line up with one of the on screen buttons
}
// alignment with onScreenWidgets
for(UIView* view in self.layoutToolVC.view.subviews){
if ([view isKindOfClass:[OnScreenWidgetView class]]) {
if ((horizontalGuideline.center.y < view.center.y + 1) && (horizontalGuideline.center.y > view.center.y - 1)) {
horizontalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
}
verticalGuideline.backgroundColor = [UIColor blueColor]; // change vertical guideline back to blue if it doesn't line up with one of the on screen buttons
for (CALayer *button in self.OSCButtonLayers) { // vertical guideline position check
if ((layerBeingDragged != button) && !button.isHidden) {
if ((verticalGuideline.center.x < button.position.x + 1) &&
(verticalGuideline.center.x > button.position.x - 1)) {
verticalGuideline.backgroundColor = [UIColor whiteColor];
verticalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
}
// alignment with onScreenWidgets
for(UIView* view in self.layoutToolVC.view.subviews){
if ([view isKindOfClass:[OnScreenWidgetView class]]) {
if ((verticalGuideline.center.x < view.center.x + 1) && (verticalGuideline.center.x > view.center.x - 1)) {
verticalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
verticalGuideline.backgroundColor = [UIColor blueColor]; // change vertical guideline back to blue if it doesn't line up with one of the on screen buttons
}
}
@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (OSCProfilesManager *) sharedManager;
+ (void) setOnScreenButtonViewsDict:(NSMutableDictionary* )dict;
+ (void) setOnScreenWidgetViewsDict:(NSMutableDictionary* )dict;
#pragma mark - Getters
/**
+16 -15
View File
@@ -14,7 +14,7 @@
@implementation OSCProfilesManager
static NSMutableDictionary *onScreenButtonViewsDict;
static NSMutableDictionary *OnScreenWidgetViewsDict;
#pragma mark - Initializer
@@ -32,8 +32,8 @@ static NSMutableDictionary *onScreenButtonViewsDict;
#pragma mark - Class Helper Methods
+ (void) setOnScreenButtonViewsDict:(NSMutableDictionary* )dict{
onScreenButtonViewsDict = dict;
+ (void) setOnScreenWidgetViewsDict:(NSMutableDictionary* )dict{
OnScreenWidgetViewsDict = dict;
}
/**
@@ -267,7 +267,7 @@ static NSMutableDictionary *onScreenButtonViewsDict;
// save on-screen game controller buttons & sticks as buttonstate:
for (CALayer *oscButtonLayer in oscButtonLayers) {
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:oscButtonLayer.name buttonType:GameControllerButton andPosition:oscButtonLayer.position];
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:oscButtonLayer.name buttonType:LegacyOscButton andPosition:oscButtonLayer.position];
// add hidden attr here
buttonState.isHidden = oscButtonLayer.isHidden;
buttonState.oscLayerSizeFactor = [OnScreenControls getControllerLayerSizeFactor:oscButtonLayer];
@@ -281,17 +281,18 @@ static NSMutableDictionary *onScreenButtonViewsDict;
[buttonStatesEncoded addObject: buttonStateEncoded];
}
// save on-screen button views (keyboard & mouse command) as buttonstate:
[onScreenButtonViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { // this dict is passed from the layout tool VC, as a static obj in this class.
OnScreenButtonView *buttonView = value;
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonView.keyString buttonType:KeyboardOrMouseButton andPosition:buttonView.frame.origin];
buttonState.alias = buttonView.keyLabel;
buttonState.timestamp = buttonView.timestamp;
buttonState.widthFactor = buttonView.widthFactor;
buttonState.heightFactor = buttonView.heightFactor;
buttonState.backgroundAlpha = buttonView.backgroundAlpha;
buttonState.sensitivityFactor = buttonView.sensitivityFactor;
buttonState.stickIndicatorXOffset = buttonView.stickIndicatorXOffset;
// save on-screen widget views (keyboard & mouse command) as buttonstate:
[OnScreenWidgetViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { // this dict is passed from the layout tool VC, as a static obj in this class.
OnScreenWidgetView *widgetView = value;
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:widgetView.keyString buttonType:CustomOnScreenWidget andPosition:widgetView.center];
buttonState.alias = widgetView.keyLabel;
buttonState.timestamp = widgetView.timestamp;
buttonState.widthFactor = widgetView.widthFactor;
buttonState.heightFactor = widgetView.heightFactor;
buttonState.backgroundAlpha = widgetView.backgroundAlpha;
buttonState.borderWidth = widgetView.borderWidth;
buttonState.sensitivityFactor = widgetView.sensitivityFactor;
buttonState.stickIndicatorXOffset = widgetView.stickIndicatorXOffset;
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
[buttonStatesEncoded addObject: buttonStateEncoded];
@@ -25,10 +25,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) BOOL isHidden;
@property (nonatomic, assign) uint8_t buttonType;
@property (nonatomic, assign) NSTimeInterval timestamp;
@property (nonatomic, assign) CGFloat widthFactor; // for OnScreenButtonView
@property (nonatomic, assign) CGFloat heightFactor; // for OnScreenButtonView
@property (nonatomic, assign) CGFloat sensitivityFactor; // for OnScreenButtonView
@property (nonatomic, assign) CGFloat stickIndicatorXOffset; // for OnScreenButtonView
@property (nonatomic, assign) CGFloat widthFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat heightFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat borderWidth; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat sensitivityFactor; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat stickIndicatorXOffset; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat oscLayerSizeFactor; // for OnScreenController CALayer
@property (nonatomic, assign) CGFloat backgroundAlpha; // for OnScreenController CALayer
@@ -36,8 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
// @property (nonatomic, assign) BOOL hasValidPosition;
typedef NS_ENUM(NSInteger, OnScreenButtonType) {
GameControllerButton,
KeyboardOrMouseButton
LegacyOscButton,
CustomOnScreenWidget
};
- (id) initWithButtonName:(NSString*)name buttonType:(uint8_t)buttonType andPosition:(CGPoint)position;
@@ -39,6 +39,7 @@
[encoder encodeFloat:self.stickIndicatorXOffset forKey:@"stickIndicatorOffset"];
[encoder encodeFloat:self.oscLayerSizeFactor forKey:@"oscLayerSizeFactor"];
[encoder encodeFloat:self.backgroundAlpha forKey:@"backgroundAlpha"];
[encoder encodeFloat:self.borderWidth forKey:@"borderWidth"];
}
- (id) initWithCoder:(NSCoder*)decoder {
@@ -55,6 +56,7 @@
self.stickIndicatorXOffset = [decoder decodeFloatForKey:@"stickIndicatorOffset"];
self.oscLayerSizeFactor = [decoder decodeFloatForKey:@"oscLayerSizeFactor"];
self.backgroundAlpha = [decoder decodeFloatForKey:@"backgroundAlpha"];
self.borderWidth = [decoder decodeFloatForKey:@"borderWidth"];
}
return self;
}
+15 -15
View File
@@ -74,7 +74,7 @@ static CGFloat screenWidthInPoints;
_gestureCaptured = false;
self.state = UIGestureRecognizerStateFailed;
}
else if(_gestureCaptured && allTouchesCount == [touches count] && !_isOnScreenControllerBeingPressed && ![self isOnScreenButtonViewBeingPressed]){ //must exclude virtual controller & onscreen button taps here to prevent stucked button, _areVirtualControllerTaps flag is set by onscreencontrols, containOnScreenButtonsTaps will be returned by iterating all button views in streamframeview
else if(_gestureCaptured && allTouchesCount == [touches count] && !_isOnScreenControllerBeingPressed && ![self isOnScreenWidgetViewBeingPressed]){ //must exclude virtual controller & onscreen button taps here to prevent stucked button, _areVirtualControllerTaps flag is set by onscreencontrols, containOnScreenButtonsTaps will be returned by iterating all widget views in streamframeview
_gestureCaptured = false; //reset for next recognition
if((CACurrentMediaTime() - _gestureCapturedTime) < _tapDownTimeThreshold){
lowestTouchPointYCoord = 0.0; //reset for next recognition
@@ -85,28 +85,28 @@ static CGFloat screenWidthInPoints;
}
// it was a not a perfect choice to code OnScreenButtonView in Swift...
// it was a not a perfect choice to code OnScreenWidgetView in Swift...
// we're unable to import this class to swift codebase by the bridging header,and have to exlucde the onscreen button taps here
// by iterating every button view instances. but it's basically ok since the number of buttonViews are always limited.
// by iterating every widget view instances. but it's basically ok since the number of widgetViews are always limited.
// and this method will only be called when the recognizer is active & and the taps passes all the checks and is about to ge triggered.
- (bool)isOnScreenButtonViewBeingPressed {
NSTimeInterval allFingersTapDownTime = CACurrentMediaTime() - _gestureCapturedTime; //RIGHTCLICK_TAP_DOWN_TIME_THRESHOLD_S has been passed to this recognizer as _tapDownTimeShreshold, we'll decide how to deal with pressed flag of on-screen button views based on tapDownTime
bool gotOneButtonPressed = false;
// the tap gestures are all added to the streamFrameTopLayerView, where all the onScreenButtonViews are added. so we can iterate them in this way:
- (bool)isOnScreenWidgetViewBeingPressed {
NSTimeInterval allFingersTapDownTime = CACurrentMediaTime() - _gestureCapturedTime; //RIGHTCLICK_TAP_DOWN_TIME_THRESHOLD_S has been passed to this recognizer as _tapDownTimeShreshold, we'll decide how to deal with pressed flag of on-screen widget views based on tapDownTime
bool gotOneWidgetPressed = false;
// the tap gestures are all added to the streamFrameTopLayerView, where all the OnScreenWidgetViews are added. so we can iterate them in this way:
for(UIView* view in self.view.subviews){
if ([view isKindOfClass:[OnScreenButtonView class]]) {
OnScreenButtonView* buttonView = (OnScreenButtonView*) view;
if(gotOneButtonPressed && allFingersTapDownTime <= _tapDownTimeThreshold){ // once we have just 1 button pressed already,& the tapDownTime has not exceeded the threshold, we'll reset pressed flag for the all the buttonViews.
buttonView.pressed = false; //reset the flag for buttonView
if ([view isKindOfClass:[OnScreenWidgetView class]]) {
OnScreenWidgetView* widgetView = (OnScreenWidgetView*) view;
if(gotOneWidgetPressed && allFingersTapDownTime <= _tapDownTimeThreshold){ // once we have just 1 button pressed already,& the tapDownTime has not exceeded the threshold, we'll reset pressed flag for the all the widgetViews.
widgetView.pressed = false; //reset the flag for widgetView
continue;
}
if(buttonView.pressed){
gotOneButtonPressed = true; //got one button pressed
if(allFingersTapDownTime <= _tapDownTimeThreshold) buttonView.pressed = false; // reset the flag for current buttonView if tapDowntime is still within the threshold, if not, leave the flag for mouse scroller gesture in relative touch mode.
if(widgetView.pressed){
gotOneWidgetPressed = true; //got one button pressed
if(allFingersTapDownTime <= _tapDownTimeThreshold) widgetView.pressed = false; // reset the flag for current widgetView if tapDowntime is still within the threshold, if not, leave the flag for mouse scroller gesture in relative touch mode.
}
}
}
return gotOneButtonPressed;
return gotOneWidgetPressed;
}
@end
+1 -1
View File
@@ -15,7 +15,7 @@
@class ControllerSupport;
@class StreamConfiguration;
// sending self as an instance to OnScreenButtonView or other related classes
// sending self as an instance to OnScreenWidgetView or other related classes
@protocol InstanceProviderDelegate <NSObject>
- (void)getOnScreenControlsInstance:(id)sender; // Renamed delegate method
@end
+5 -5
View File
@@ -189,7 +189,7 @@ static float L3_Y;
[_controllerSupport updateFinished:_controller];
}
// sending self as an instance to OnScreenButtonView
// sending self as an instance to OnScreenWidgetView
- (void)sendInstance{
NSLog(@"OnScreenControls is sending its instance...");
if ([self.delegate respondsToSelector:@selector(getOnScreenControlsInstance:)]) {
@@ -258,7 +258,7 @@ static float L3_Y;
_rightStickBackground = [CALayer layer];
_leftStick = [CALayer layer];
_rightStick = [CALayer layer];
[self.OSCButtonLayers addObject:_aButton];
[self.OSCButtonLayers addObject:_bButton];
[self.OSCButtonLayers addObject:_xButton];
@@ -362,7 +362,7 @@ static float L3_Y;
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
OnScreenButtonState *buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
if(!buttonState.isHidden && [validPositionButtonNames containsObject:buttonState.name] && (buttonState.buttonType == GameControllerButton || [profilesManager getIndexOfSelectedProfile] == 0 ) ){
if(!buttonState.isHidden && [validPositionButtonNames containsObject:buttonState.name] && (buttonState.buttonType == LegacyOscButton || [profilesManager getIndexOfSelectedProfile] == 0 ) ){
[_activeCustomOscButtonPositionDict setObject:[NSValue valueWithCGPoint:buttonState.position] forKey:buttonState.name]; // we got a buttonname -> position dict here
NSLog(@"_activeCustomOscButtonPositionDict update, button name:%@, position: %f, %f", buttonState.name, buttonState.position.x, buttonState.position.y);
}
@@ -1894,9 +1894,9 @@ static float L3_Y;
// CALayer* superLayer = layer.superlayer;
// if(layerBeingDragged.name == @"")
CGFloat targetAlpha;
targetAlpha = alpha;
if(alpha < 0.23) targetAlpha = 0.23;
if(alpha == 0.0 || alpha == 1.0) targetAlpha = 5.0f/6.0f; // invalid alpha value
else targetAlpha = alpha;
NSLog(@"alphas: %f",targetAlpha);
@@ -8,7 +8,7 @@
import UIKit
@objc class OnScreenButtonView: UIView, InstanceProviderDelegate {
@objc class OnScreenWidgetView: UIView, InstanceProviderDelegate {
// receiving the OnScreenControls instance from delegate
@objc func getOnScreenControlsInstance(_ sender: Any) {
if let controls = sender as? OnScreenControls {
@@ -27,6 +27,7 @@ import UIKit
@objc public var pressed: Bool
@objc public var widthFactor: CGFloat = 1.0
@objc public var heightFactor: CGFloat = 1.0
@objc public var borderWidth: CGFloat = 0.0
@objc public var backgroundAlpha: CGFloat = 0.5
@objc public var latestTouchLocation: CGPoint
@objc public var selfViewOnTheRight: Bool = false
@@ -85,7 +86,7 @@ import UIKit
private var mousePointerMoved: Bool
private var twoTouchesDetected: Bool
private var storedLocation: CGPoint = .zero // location from persisted data
private var storedCenter: CGPoint = .zero // location from persisted data
private let minimumBorderAlpha: CGFloat = 0.19
private var defaultBorderColor: CGColor = UIColor(white: 0.2, alpha: 0.3).cgColor
private let moonlightPurple: CGColor = UIColor(red: 0.5, green: 0.5, blue: 1.0, alpha: 0.86).cgColor
@@ -142,28 +143,39 @@ import UIKit
}
@objc public func setLocation(xOffset:CGFloat, yOffset:CGFloat) {
/*
NSLayoutConstraint.activate([
self.leadingAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: xOffset),
self.topAnchor.constraint(equalTo: self.superview!.topAnchor, constant: yOffset),
self.centerXAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: xOffset),
self.centerYAnchor.constraint(equalTo: self.superview!.topAnchor, constant: yOffset),
])
storedLocation = CGPointMake(xOffset, yOffset)
*/
storedCenter = CGPointMake(xOffset, yOffset)
center = storedCenter
}
@objc public func enableRelocationMode(enabled: Bool){
OnScreenButtonView.editMode = enabled
OnScreenWidgetView.editMode = enabled
}
@objc public func adjustButtonTransparency(alpha: CGFloat){
@objc public func adjustTransparency(alpha: CGFloat){
if alpha != 0 {
self.backgroundAlpha = alpha
}
else{
self.backgroundAlpha = 0.5
// self.backgroundAlpha = 0.5
self.backgroundAlpha = alpha
}
self.tweakAlpha()
}
@objc public func resizeButtonView(){
@objc public func adjustBorder(width: CGFloat){
self.borderWidth = width
// self.layer.borderWidth = borderWidth
// if CommandManager.touchPadCmds.contains(self.keyString) && width == 0 {self.layer.borderWidth = 1}
setupView()
}
@objc public func resizeWidgetView(){
guard let superview = superview else { return }
@@ -172,20 +184,26 @@ import UIKit
// To resize the button, we must set this to false temporarily
translatesAutoresizingMaskIntoConstraints = false
// replace invalid factor values
if self.widthFactor == 0 {self.widthFactor = 1.0}
if self.heightFactor == 0 {self.heightFactor = 1.0}
// Constraints for resizing
/*
NSLayoutConstraint.activate([
self.centerXAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: storedLocation.x),
self.centerYAnchor.constraint(equalTo: self.superview!.topAnchor, constant: storedLocation.y)])
*/
// Constraints for resizing
self.changeAndActivateContraints()
// Trigger layout update
superview.layoutIfNeeded()
// Re-setup buttonView style
// Re-setup widgetView style
setupView()
}
@@ -207,10 +225,13 @@ import UIKit
}
private func changeAndActivateContraints(){
if CommandManager.oscButtonMappings.keys.contains(self.keyString){ // we'll make custom osc buttons round & smaller
if CommandManager.oscButtonMappings.keys.contains(self.keyString) && !CommandManager.oscRectangleButtonCmds.contains(self.keyString){ // we'll make custom osc buttons round & smaller
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant: 60 * self.widthFactor),
self.heightAnchor.constraint(equalToConstant: 60 * self.heightFactor),])
// self.frame = CGRectMake(0, 0, 60*self.widthFactor, 60*self.heightFactor)
}
else if CommandManager.touchPadCmds.contains(self.keyString) { // make touchPads larger
NSLayoutConstraint.activate([
@@ -222,6 +243,7 @@ import UIKit
self.widthAnchor.constraint(equalToConstant: 70 * self.widthFactor),
self.heightAnchor.constraint(equalToConstant: 65 * self.heightFactor),])
}
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10), // set up label size contrain within UIView
label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10),
@@ -244,21 +266,23 @@ import UIKit
self.translatesAutoresizingMaskIntoConstraints = true // this is mandatory to prevent unexpected key view location change
self.layer.cornerRadius = 20
self.layer.borderWidth = 1
self.layer.cornerRadius = 16
self.layer.borderWidth = self.borderWidth
self.tweakAlpha()
if CommandManager.oscButtonMappings.keys.contains(self.keyString){ //make oscButtons round and no border
if CommandManager.oscButtonMappings.keys.contains(self.keyString) && !CommandManager.oscRectangleButtonCmds.contains(self.keyString){ //make oscButtons round and no border
self.layer.cornerRadius = self.frame.width/2
self.layer.borderWidth = 0
// self.layer.borderWidth = self.borderWidth
label.minimumScaleFactor = 0.15 // Adjust the scale factor for oscButtons
label.font = UIFont.boldSystemFont(ofSize: 22)
}
if CommandManager.touchPadCmds.contains(self.keyString){
if(self.borderWidth < 1) {self.layer.borderWidth = 1}
else {self.layer.borderWidth = self.borderWidth}
label.text = "" // make touchPad display no text
if OnScreenButtonView.editMode { //display label in edit mode to make the pad more visible
if OnScreenWidgetView.editMode { //display label in edit mode to make the pad more visible
label.text = self.keyString
}
}
@@ -276,6 +300,8 @@ import UIKit
self.changeAndActivateContraints()
center = storedCenter //anchor the center while resizing self
setupButtonDownVisualEffectLayer();
}
@@ -312,10 +338,10 @@ import UIKit
// create stick indicator: the crossMark & stickBall:
@objc public func showStickIndicator(){
// tell if the self button is located on the left or right
self.selfViewOnTheRight = (self.storedLocation.x > self.appWindow.frame.width*0.5)
self.selfViewOnTheRight = (self.storedCenter.x > self.appWindow.frame.width*0.5)
let offsetSign = selfViewOnTheRight ? -1 : 1
let stickMarkerRelativeLocation:CGPoint
if !OnScreenButtonView.editMode {
if !OnScreenWidgetView.editMode {
stickMarkerRelativeLocation = CGPointMake(touchBeganLocation.x + CGFloat(offsetSign) * self.stickIndicatorXOffset, touchBeganLocation.y)
}
else{
@@ -384,7 +410,7 @@ import UIKit
CATransaction.begin()
CATransaction.setDisableActions(true)
self.stickBallLayer.removeAllAnimations()
if !OnScreenButtonView.editMode {
if !OnScreenWidgetView.editMode {
self.stickBallLayer.position = CGPointMake(CGRectGetMidX(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetX*sensitivityFactor), CGRectGetMidY(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetY*sensitivityFactor))
}
else{
@@ -634,7 +660,10 @@ import UIKit
private func setupButtonDownVisualEffectLayer() {
self.buttonDownVisualEffectWidth = 8.6
if CommandManager.oscButtonMappings.keys.contains(self.keyString) {self.buttonDownVisualEffectWidth = 15.3} // wider visual effect for osc buttons
if CommandManager.oscButtonMappings.keys.contains(self.keyString) && !CommandManager.oscRectangleButtonCmds.contains(self.keyString){
if widthFactor < 1.3 {self.buttonDownVisualEffectWidth = 15.3} // wider visual effect for osc buttons
else {self.buttonDownVisualEffectWidth = 9}
}
// Set the frame to be larger than the view to expand outward
buttonDownVisualEffectLayer.borderWidth = 0 // set this 0 to hide the visual effect first
@@ -683,7 +712,7 @@ import UIKit
self.onScreenControls.sendLeftStickTouchPadEvent(targetX, targetY)
}
//==========================================================================================================
// Touch event handling
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
@@ -697,18 +726,19 @@ import UIKit
quickDoubleTapDetected = touchTapTimeInterval < QUICK_TAP_TIME_INTERVAL
let touch = touches.first
self.touchBeganLocation = touch!.location(in: self)
if OnScreenWidgetView.editMode {self.touchBeganLocation = touch!.location(in: superview)}
else {self.touchBeganLocation = touch!.location(in: self)}
self.latestTouchLocation = touchBeganLocation
}
let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self buttonView, and excludes touches in other buttonViews
let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self widgetView, and excludes touches in other widgetViews
if allCapturedTouchesCount == 2 {
self.twoTouchesDetected = true
}
self.pressed = true
if !OnScreenButtonView.editMode {
if !OnScreenWidgetView.editMode {
if CommandManager.touchPadCmds.contains(self.keyString) && touches.count == 1{ // don't use event?.allTouches?.count here, it will counts all touches including the ones captured by other UIViews
switch self.keyString {
case "LSPAD":
@@ -770,29 +800,37 @@ import UIKit
}
// here is in edit mode:
else{
NotificationCenter.default.post(name: Notification.Name("OnScreenButtonViewSelected"),object: self) // inform layout tool controller to fetch button size factors. self will be passed as the object of the notification
NotificationCenter.default.post(name: Notification.Name("OnScreenWidgetViewSelected"),object: self) // inform layout tool controller to fetch button size factors. self will be passed as the object of the notification
if let touch = touches.first {
let touchLocation = touch.location(in: superview)
storedLocation = touchLocation
storedCenter = touchLocation
}
}
}
private func moveByTouch(touch: UITouch){
let currentLocation = touch.location(in: superview)
let offsetX = currentLocation.x - storedLocation.x
let offsetY = currentLocation.y - storedLocation.y
let currentLocation: CGPoint
if OnScreenWidgetView.editMode {currentLocation = touch.location(in: superview)}
else {currentLocation = touch.location(in: self)}
let offsetX = currentLocation.x - latestTouchLocation.x
let offsetY = currentLocation.y - latestTouchLocation.y
center = CGPoint(x: center.x + offsetX, y: center.y + offsetY)
latestTouchLocation = currentLocation
// center = currentLocation;
//NSLog("x coord: %f, y coord: %f", self.frame.origin.x, self.frame.origin.y)
storedLocation = currentLocation // Update initial center for next movement
storedCenter = center // Update initial center for next movement
if OnScreenWidgetView.editMode {
NotificationCenter.default.post(name: Notification.Name("OnScreenWidgetMovedByTouch"), object:self) // inform the layoutOnScreenControl to update guideLines for this widget view
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
OnScreenButtonView.timestampOfButtonBeingDragged = self.timestamp
OnScreenWidgetView.timestampOfButtonBeingDragged = self.timestamp
if !OnScreenButtonView.editMode {
if !OnScreenWidgetView.editMode {
if CommandManager.touchPadCmds.contains(self.keyString){
handleTouchPadMoveEvent(touches, with: event)
}
@@ -808,8 +846,8 @@ import UIKit
}
}
// Move the buttonView based on touch movement in relocation mode
if OnScreenButtonView.editMode {
// Move the widgetView based on touch movement in relocation mode
if OnScreenWidgetView.editMode {
if let touch = touches.first {
self.moveByTouch(touch: touch)
}
@@ -858,10 +896,10 @@ import UIKit
if self.keyString != "MOUSEPAD" {quickDoubleTapDetected = false} //do not reset this flag here in mousePad mode
let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self buttonView, and excludes touches in other buttonViews
let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self widgetView, and excludes touches in other widgetViews
// deal with MOUSPAD first
if !OnScreenButtonView.editMode && self.keyString == "MOUSEPAD" && allCapturedTouchesCount == 1 && !twoTouchesDetected {
if !OnScreenWidgetView.editMode && self.keyString == "MOUSEPAD" && allCapturedTouchesCount == 1 && !twoTouchesDetected {
if !mousePointerMoved && !quickDoubleTapDetected {self.sendLongMouseLeftButtonClickEvent()} // deal with single tap(click)
if quickDoubleTapDetected { //deal with quick double tap
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_LEFT) //must release the button anyway, because the button is likely being held down since the long click turned into a dragging event.
@@ -871,14 +909,14 @@ import UIKit
mousePointerMoved = false // reset this flag
}
if !OnScreenButtonView.editMode && self.keyString == "MOUSEPAD" && twoTouchesDetected && touches.count == allCapturedTouchesCount { // need to enable multi-touch first
if !OnScreenWidgetView.editMode && self.keyString == "MOUSEPAD" && twoTouchesDetected && touches.count == allCapturedTouchesCount { // need to enable multi-touch first
// touches.count == allCapturedTouchesCount means allfingers are lifting
self.sendMouseRightButtonClickEvent()
twoTouchesDetected = false
}
// then other types of pads
if !OnScreenButtonView.editMode && CommandManager.touchPadCmds.contains(self.keyString) {
if !OnScreenWidgetView.editMode && CommandManager.touchPadCmds.contains(self.keyString) {
switch self.keyString{
case "LSPAD":
self.onScreenControls.clearLeftStickTouchPadFlag()
@@ -912,7 +950,7 @@ import UIKit
}
}
if !OnScreenButtonView.editMode && CommandManager.specialOverlayButtonCmds.contains(self.keyString){
if !OnScreenWidgetView.editMode && CommandManager.specialOverlayButtonCmds.contains(self.keyString){
if CACurrentMediaTime() - self.touchTapTimeStamp < 0.3 {
switch self.keyString {
case "SETTINGS":
@@ -940,7 +978,7 @@ import UIKit
if self.keyString == "OSCR2" {self.onScreenControls.updateRightTrigger(0x00)}
}
if !OnScreenButtonView.editMode && !self.keyString.contains("+") { // if the command(keystring contains "+", it's a multi-key command rather than a single key button
if !OnScreenWidgetView.editMode && !self.keyString.contains("+") { // if the command(keystring contains "+", it's a multi-key command rather than a single key button
if CommandManager.mouseButtonMappings.keys.contains(self.keyString){
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), Int32(CommandManager.mouseButtonMappings[self.keyString]!))
@@ -950,7 +988,7 @@ import UIKit
}
}
if OnScreenButtonView.editMode {
if OnScreenWidgetView.editMode {
guard let superview = superview else { return }
// Deactivate existing constraints if necessary
@@ -969,7 +1007,7 @@ import UIKit
// Trigger layout update
superview.layoutIfNeeded()
setupView(); //re-setup buttonView style
setupView(); //re-setup widgetView style
if CommandManager.nonVectorStickPads.contains(self.keyString) {
self.crossMarkLayer.removeFromSuperlayer()
+13 -13
View File
@@ -91,12 +91,12 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
}
- (bool)isOnScreenButtonViewBeingPressed {
- (bool)isOnScreenWidgetViewBeingPressed {
bool gotOneButtonPressed = false;
for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen button views in StreamFrameView
if ([view isKindOfClass:[OnScreenButtonView class]]) {
OnScreenButtonView* buttonView = (OnScreenButtonView*) view;
if(buttonView.pressed){
for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen widget views in StreamFrameView
if ([view isKindOfClass:[OnScreenWidgetView class]]) {
OnScreenWidgetView* widgetView = (OnScreenWidgetView*) view;
if(widgetView.pressed){
gotOneButtonPressed = true; //got one button pressed
}
}
@@ -104,11 +104,11 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
return gotOneButtonPressed;
}
- (void)resetAllPressedFlagsForOnscreenButtonViews {
for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen button views in StreamFrameView
if ([view isKindOfClass:[OnScreenButtonView class]]) {
OnScreenButtonView* buttonView = (OnScreenButtonView*) view;
buttonView.pressed = false;
- (void)resetAllPressedFlagsForOnScreenWidgetViews {
for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen widget views in StreamFrameView
if ([view isKindOfClass:[OnScreenWidgetView class]]) {
OnScreenWidgetView* widgetView = (OnScreenWidgetView*) view;
widgetView.pressed = false;
}
}
}
@@ -146,7 +146,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
touchPointSpawnedAtUpperScreenEdge = false; // reset this flag immediately if we get a touch event passing the check above, this fixes irresponsive touch after closing the command tool menu.
if([[event allTouches] count] == 2 && ![self isOnScreenButtonViewBeingPressed] && ![self isOnScreenControllerBeingPressed:[event allTouches]]){
if([[event allTouches] count] == 2 && ![self isOnScreenWidgetViewBeingPressed] && ![self isOnScreenControllerBeingPressed:[event allTouches]]){
NSLog(@"get in scrolling mode");
isInMouseWheelScrollingMode = true;
return; // if we got 2 touches on the blank area, it's gonna be a mouse scroll touch, and must prevent UITtouch object for mouse pointer being captured & locked
@@ -190,7 +190,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
//NSLog(@"%f, touchesMoved callback, is scrolling: %d, touches count: %d", CACurrentMediaTime(), isInMouseWheelScrollingMode, (uint32_t)[touches count]);
if(isInMouseWheelScrollingMode && [[event allTouches] count] == 2 && ![self isOnScreenButtonViewBeingPressed] && ![self isOnScreenControllerBeingPressed:touches]){
if(isInMouseWheelScrollingMode && [[event allTouches] count] == 2 && ![self isOnScreenWidgetViewBeingPressed] && ![self isOnScreenControllerBeingPressed:touches]){
NSSet* twoTouches = [event allTouches];
CGPoint firstLocation = [[[twoTouches allObjects] objectAtIndex:0] locationInView:streamView];
CGPoint secondLocation = [[[twoTouches allObjects] objectAtIndex:1] locationInView:streamView];
@@ -237,7 +237,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
isInMouseWheelScrollingMode = false;
touchLockedForMouseMove = nil;
mousePointerMoved = false; // need to reset this anyway
[self resetAllPressedFlagsForOnscreenButtonViews]; // reset all pressed flag for on-screen button views after all fingers lifted from screen.
[self resetAllPressedFlagsForOnScreenWidgetViews]; // reset all pressed flag for on-screen widget views after all fingers lifted from screen.
touchPointSpawnedAtUpperScreenEdge = false;
}
}
+1 -1
View File
@@ -43,7 +43,7 @@
- (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport
andConfig:(StreamConfiguration*)streamConfig;
- (void) clearOnScreenKeyboardButtons;
- (void) reloadOnScreenButtonViews;
- (void) reloadOnScreenWidgetViews;
- (CGSize) getVideoAreaSize;
- (CGPoint) adjustCoordinatesForVideoArea:(CGPoint)point;
+19 -17
View File
@@ -368,18 +368,18 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
- (void) clearOnScreenKeyboardButtons{
for (UIView *subview in self->streamFrameTopLayerView.subviews) {
// 检查子视图是否是特定类型的实例
if ([subview isKindOfClass:[OnScreenButtonView class]]) {
if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
// 如果是,就添加到将要被移除的数组中
[subview removeFromSuperview];
}
}
}
- (void) reloadOnScreenButtonViews{
- (void) reloadOnScreenWidgetViews{
NSLog(@"reload on screen keyboard buttons here");
// remove all keyboard button views first
// remove all keyboard widget views first
[self clearOnScreenKeyboardButtons];
// bool customOscEnabled = [self isOscEnabled] && settings.onscreenControls.intValue == OnScreenControlsLevelCustom;
@@ -389,25 +389,27 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
OSCProfilesManager* profilesManager = [OSCProfilesManager sharedManager];
OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile
if(!OnScreenButtonView.editMode){ // in edit mode, keyboard button view will be updated within layoutool view controller.
if(!OnScreenWidgetView.editMode){ // in edit mode, keyboard widget view will be updated within layoutool view controller.
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
OnScreenButtonState* buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
if(buttonState.buttonType == KeyboardOrMouseButton){
OnScreenButtonView* buttonView = [[OnScreenButtonView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct buttonView
if(buttonState.buttonType == CustomOnScreenWidget){
OnScreenWidgetView* widgetView = [[OnScreenWidgetView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct widgetView
//--------------------------------------------------
onScreenControls.delegate = buttonView; // connecting onScreenControls to OnScreenButtonView, sending the active instance for touchPad stick control
onScreenControls.delegate = widgetView; // connecting onScreenControls to OnScreenWidgetView, sending the active instance for touchPad stick control
[onScreenControls sendInstance];
//--------------------------------------------------
buttonView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
buttonView.widthFactor = buttonState.widthFactor;
buttonView.heightFactor = buttonState.heightFactor;
buttonView.sensitivityFactor = buttonState.sensitivityFactor;
buttonView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
// Add the buttonView to the view controller's view
[self->streamFrameTopLayerView addSubview:buttonView]; // add keyboard button to the stream frame view. must add it to the target view before setting location.
[buttonView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
[buttonView resizeButtonView]; // resize must be called after relocation
[buttonView adjustButtonTransparencyWithAlpha:buttonState.backgroundAlpha];
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
widgetView.widthFactor = buttonState.widthFactor;
widgetView.heightFactor = buttonState.heightFactor;
widgetView.borderWidth = buttonState.borderWidth;
widgetView.sensitivityFactor = buttonState.sensitivityFactor;
widgetView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
// Add the widgetView to the view controller's view
[self->streamFrameTopLayerView addSubview:widgetView]; // add keyboard button to the stream frame view. must add it to the target view before setting location.
[widgetView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
[widgetView resizeWidgetView]; // resize must be called after relocation
[widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha];
[widgetView adjustBorderWithWidth:buttonState.borderWidth];
}
}
}
@@ -47,7 +47,8 @@
<attribute name="showKeyboardToolbar" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="slideToSettingsDistance" optional="YES" attributeType="Float" defaultValueString="0.5" usesScalarValueType="NO" syncable="YES"/>
<attribute name="slideToSettingsScreenEdge" optional="YES" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="NO" syncable="YES"/>
<attribute name="statsOverlay" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlayEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlayLevel" optional="YES" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="swapABXYButtons" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="touchMode" optional="YES" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="touchPointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17192" systemVersion="19H2" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22522" systemVersion="22G313" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
@@ -31,14 +31,9 @@
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlay" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlayEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useHevc" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="App" positionX="0" positionY="54" width="128" height="118"/>
<element name="Host" positionX="0" positionY="0" width="128" height="210"/>
<element name="Settings" positionX="0" positionY="0" width="128" height="268"/>
</elements>
</model>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="20G224" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22522" systemVersion="22G313" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
@@ -32,15 +32,10 @@
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlay" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlayEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useFramePacing" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="useHevc" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="App" positionX="0" positionY="54" width="128" height="118"/>
<element name="Host" positionX="0" positionY="0" width="128" height="210"/>
<element name="Settings" positionX="0" positionY="0" width="128" height="254"/>
</elements>
</model>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21G72" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22522" systemVersion="22G313" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
@@ -32,16 +32,11 @@
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlay" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlayEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="swapABXYButtons" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useFramePacing" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="useHevc" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="App" positionX="0" positionY="54" width="128" height="118"/>
<element name="Host" positionX="0" positionY="0" width="128" height="210"/>
<element name="Settings" positionX="0" positionY="0" width="128" height="298"/>
</elements>
</model>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21G72" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22522" systemVersion="22G313" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
@@ -32,16 +32,11 @@
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlay" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="statsOverlayEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="swapABXYButtons" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
<attribute name="useFramePacing" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="useHevc2" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="App" positionX="0" positionY="54" width="128" height="118"/>
<element name="Host" positionX="0" positionY="0" width="128" height="210"/>
<element name="Settings" positionX="0" positionY="0" width="128" height="298"/>
</elements>
</model>
+73 -10
View File
@@ -283,6 +283,52 @@
}
}
},
"Border Width" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "边界宽度"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "边界宽度"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "边界宽度"
}
}
}
},
"Border Width: %.2f" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "边界宽度: %.2f"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "边界宽度: %.2f"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "边界宽度: %.2f"
}
}
}
},
"Cancel" : {
"extractionState" : "manual",
"localizations" : {
@@ -870,6 +916,29 @@
}
}
},
"FPS: %5.2f Network dropped frames: %.2f%% Network latency: %@" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "帧率: %5.2f 网络丢帧: %.2f%% 网络延迟: %@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "帧率: %5.2f 网络丢帧: %.2f%% 网络延迟: %@"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "帧率: %5.2f 网络丢帧: %.2f%% 网络延迟: %@"
}
}
}
},
"Got it!" : {
"extractionState" : "manual",
"localizations" : {
@@ -2660,31 +2729,25 @@
}
}
},
"Video stream: %dx%d %.2f FPS (Codec: %@)\nFrames dropped by your network connection: %.2f%%\nAverage network latency: %@%@" : {
"Video stream: %dx%d %.2f FPS (Codec: %@)\nNetwork dropped frames: %.2f%%\nAverage network latency: %@%@" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Video stream: %dx%d %.2f FPS (Codec: %@)\nFrames dropped by your network connection: %.2f%%\nAverage network latency: %@%@"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "视频流: %dx%d %.2f FPS (编码格式: %@)\n网络造成的丢帧: %.2f%%\n平均网络延迟: %@%@"
"value" : "视频流: %dx%d %.2f FPS (编解码: %@)\n网络丢帧: %.2f%%\n平均网络延迟: %@%@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "视频流: %dx%d %.2f FPS (编码格式: %@)\n网络造成的丢帧: %.2f%%\n平均网络延迟: %@%@"
"value" : "视频流: %dx%d %.2f FPS (编解码: %@)\n网络丢帧: %.2f%%\n平均网络延迟: %@%@"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "视频流: %dx%d %.2f FPS (编码格式: %@)\n网络造成的丢帧: %.2f%%\n平均网络延迟: %@%@"
"value" : "视频流: %dx%d %.2f FPS (编解码: %@)\n网络丢帧: %.2f%%\n平均网络延迟: %@%@"
}
}
}
+1 -1
View File
@@ -15,6 +15,6 @@
- (void) stopStream;
- (NSString*) getStatsOverlayText;
- (NSString*) getStatsOverlayText: (uint16_t) overlayLevel;
@end
+9 -2
View File
@@ -148,9 +148,11 @@
return TRUE;
}
- (NSString*) getStatsOverlayText {
- (NSString*) getStatsOverlayText: (uint16_t) overlayLevel {
video_stats_t stats;
// NSLog(@"overlayLevel: %d", overlayLevel);
if (!_connection) {
return nil;
}
@@ -169,6 +171,7 @@
}
NSString* hostProcessingString;
// overlayLevel 2: detailed
if (stats.framesWithHostProcessingLatency != 0) {
hostProcessingString = [LocalizationHelper localizedStringForKey:@"\nHost processing latency min/max/avg: %.1f/%.1f/%.1f ms",
stats.minHostProcessingLatency / 10.f,
@@ -180,7 +183,7 @@
}
float interval = stats.endTime - stats.startTime;
return [LocalizationHelper localizedStringForKey:@"Video stream: %dx%d %.2f FPS (Codec: %@)\nFrames dropped by your network connection: %.2f%%\nAverage network latency: %@%@",
if(overlayLevel == 2) return [LocalizationHelper localizedStringForKey:@"Video stream: %dx%d %.2f FPS (Codec: %@)\nNetwork dropped frames: %.2f%%\nAverage network latency: %@%@",
_config.width,
_config.height,
stats.totalFrames / interval,
@@ -188,6 +191,10 @@
stats.networkDroppedFrames / interval,
latencyString,
hostProcessingString];
else return [LocalizationHelper localizedStringForKey:@"FPS: %5.2f Network dropped frames: %.2f%% Network latency: %@",
stats.totalFrames / interval,
stats.networkDroppedFrames / interval,
latencyString];
}
@end
@@ -20,10 +20,10 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface LayoutOnScreenControlsViewController : UIViewController
- (void)profileRefresh;
- (void)reloadOnScreenButtonViews;
- (void)reloadOnScreenWidgetViews;
@property LayoutOnScreenControls *layoutOSC; // object that contains a view which contains the on screen controller buttons that allows the user to drag and positions each button on the screen using touch
@property (nonatomic) NSMutableDictionary* onScreenButtonViewsDict;
@property (nonatomic) NSMutableDictionary* OnScreenWidgetViewsDict;
@property int OSCSegmentSelected;
@@ -42,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) IBOutlet UISlider *widgetAlphaSlider;
@property (strong, nonatomic) IBOutlet UISlider *sensitivityFactorSlider;
@property (strong, nonatomic) IBOutlet UISlider *stickIndicatorOffsetSlider;
@property (strong, nonatomic) IBOutlet UISlider *widgetBorderWidthSlider;
@end
@@ -22,16 +22,17 @@
@implementation LayoutOnScreenControlsViewController {
BOOL isToolbarHidden;
OSCProfilesManager* profilesManager;
OnScreenButtonView* selectedButtonView;
OnScreenWidgetView* selectedWidgetView;
CALayer* selectedControllerLayer;
CGRect controllerLoadedBounds;
bool buttonViewSelected;
bool widgetViewSelected;
bool controllerLayerSelected;
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPhone;
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPad;
UILabel *widgetSizeSliderLabel;
UILabel *widgetHeightSliderLabel;
UILabel *widgetAlphaSliderLabel;
UILabel *widgetBorderWidthSliderLabel;
UILabel *sensitivitySliderLabel;
UILabel *stickIndicatorOffsetSliderLabel;
UILabel *stickIndicatorOffsetExplain;
@@ -46,25 +47,25 @@
- (void) viewWillDisappear:(BOOL)animated{
OnScreenButtonView.editMode = false;
for (OnScreenButtonView* buttonView in self.onScreenButtonViewsDict.allValues){
[buttonView.stickBallLayer removeFromSuperlayer];
[buttonView.crossMarkLayer removeFromSuperlayer];
OnScreenWidgetView.editMode = false;
for (OnScreenWidgetView* widgetView in self.OnScreenWidgetViewsDict.allValues){
[widgetView.stickBallLayer removeFromSuperlayer];
[widgetView.crossMarkLayer removeFromSuperlayer];
}
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutCloseNotification" object:self];
}
- (void) reloadOnScreenButtonViews {
- (void) reloadOnScreenWidgetViews {
for (UIView *subview in self.view.subviews) {
// 检查子视图是否是特定类型的实例
if ([subview isKindOfClass:[OnScreenButtonView class]]) {
if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
// 如果是,就添加到将要被移除的数组中
[subview removeFromSuperview];
}
}
[self.onScreenButtonViewsDict removeAllObjects];
[self.OnScreenWidgetViewsDict removeAllObjects];
NSLog(@"reload os Key here");
@@ -72,21 +73,23 @@
OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
OnScreenButtonState* buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
if(buttonState.buttonType == KeyboardOrMouseButton){
OnScreenButtonView* buttonView = [[OnScreenButtonView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct buttonView
buttonView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
buttonView.timestamp = buttonState.timestamp; // will be set as key in in the dict.
buttonView.widthFactor = buttonState.widthFactor;
buttonView.heightFactor = buttonState.heightFactor;
buttonView.sensitivityFactor = buttonState.sensitivityFactor;
buttonView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
// buttonView.backgroundAlpha = buttonState.backgroundAlpha;
// Add the buttonView to the view controller's view
[self.view addSubview:buttonView];
[buttonView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
[buttonView resizeButtonView]; // resize must be called after relocation
[buttonView adjustButtonTransparencyWithAlpha:buttonState.backgroundAlpha];
[self.onScreenButtonViewsDict setObject:buttonView forKey:@(buttonView.timestamp)];
if(buttonState.buttonType == CustomOnScreenWidget){
OnScreenWidgetView* widgetView = [[OnScreenWidgetView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct widgetView
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
widgetView.timestamp = buttonState.timestamp; // will be set as key in in the dict.
widgetView.widthFactor = buttonState.widthFactor;
widgetView.heightFactor = buttonState.heightFactor;
widgetView.borderWidth = buttonState.borderWidth;
widgetView.sensitivityFactor = buttonState.sensitivityFactor;
widgetView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
// widgetView.backgroundAlpha = buttonState.backgroundAlpha;
// Add the widgetView to the view controller's view
[self.view addSubview:widgetView];
[widgetView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
[widgetView resizeWidgetView]; // resize must be called after relocation
[widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha];
[widgetView adjustBorderWithWidth:buttonState.borderWidth];
[self.OnScreenWidgetViewsDict setObject:widgetView forKey:@(widgetView.timestamp)];
}
}
}
@@ -95,14 +98,15 @@
- (void) viewDidLoad {
[super viewDidLoad];
profilesManager = [OSCProfilesManager sharedManager];
self.onScreenButtonViewsDict = [[NSMutableDictionary alloc] init]; // will be revised to read persisted data , somewhere else
[OSCProfilesManager setOnScreenButtonViewsDict:self.onScreenButtonViewsDict]; // pass the keyboard button dict to profiles manager
self.OnScreenWidgetViewsDict = [[NSMutableDictionary alloc] init]; // will be revised to read persisted data , somewhere else
[OSCProfilesManager setOnScreenWidgetViewsDict:self.OnScreenWidgetViewsDict]; // pass the keyboard button dict to profiles manager
isToolbarHidden = NO; // keeps track if the toolbar is hidden up above the screen so that we know whether to hide or show it when the user taps the toolbar's hide/show button
widgetSizeSliderLabel = [[UILabel alloc] init];
widgetHeightSliderLabel = [[UILabel alloc] init];
widgetAlphaSliderLabel = [[UILabel alloc] init];
widgetBorderWidthSliderLabel = [[UILabel alloc] init];
sensitivitySliderLabel = [[UILabel alloc] init];
stickIndicatorOffsetSliderLabel = [[UILabel alloc] init];
stickIndicatorOffsetExplain = [[UILabel alloc] init];
@@ -127,6 +131,7 @@
self.layoutOSC = [[LayoutOnScreenControls alloc] initWithView:self.view controllerSup:nil streamConfig:nil oscLevel:OSCSegmentSelected];
self.layoutOSC._level = OnScreenControlsLevelCustom;
self.layoutOSC.layoutToolVC = self;
[self.layoutOSC show]; // draw on screen controls
[self addInnerAnalogSticksToOuterAnalogLayers]; // allows inner and analog sticks to be dragged together around the screen together as one unit which is the expected behavior
@@ -144,13 +149,13 @@
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadOnScreenButtonViews)
selector:@selector(reloadOnScreenWidgetViews)
name:@"OscLayoutProfileSelctedInTableView" // This is a special notification for reloading the on screen keyboard buttons. which can't be executed by _oscProfilesTableViewController.needToUpdateOscLayoutTVC code block, and has to be triggered by a notification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(buttonViewTapped:)
name:@"OnScreenButtonViewSelected"
selector:@selector(widgetViewTapped:)
name:@"OnScreenWidgetViewSelected"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -190,7 +195,7 @@
- (void) viewDidAppear:(BOOL)animated {
OnScreenButtonView.editMode = true;
OnScreenWidgetView.editMode = true;
[super viewWillAppear:animated];
[self profileRefresh];
}
@@ -354,14 +359,14 @@
if(noValidKeyboardString && noValidMouseButtonString && noValidTouchPadString && noValidOscButtonString && noValidSpecialButtonString) return;
//saving & present the keyboard button:
OnScreenButtonView* buttonView = [[OnScreenButtonView alloc] initWithKeyString:cmdString keyLabel:keyLabel];
buttonView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
buttonView.timestamp = CACurrentMediaTime(); // will be set as key in in the dict.
[self.onScreenButtonViewsDict setObject:buttonView forKey:@(buttonView.timestamp)];
// Add the buttonView to the view controller's view
[self.view addSubview:buttonView];
[buttonView setLocationWithXOffset:50 yOffset:50];
[buttonView resizeButtonView];
OnScreenWidgetView* widgetView = [[OnScreenWidgetView alloc] initWithKeyString:cmdString keyLabel:keyLabel];
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
widgetView.timestamp = CACurrentMediaTime(); // will be set as key in in the dict.
[self.OnScreenWidgetViewsDict setObject:widgetView forKey:@(widgetView.timestamp)];
// Add the widgetView to the view controller's view
[self.view addSubview:widgetView];
[widgetView setLocationWithXOffset:50 yOffset:50];
[widgetView resizeWidgetView];
}];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
@@ -388,48 +393,50 @@
}
}
- (void)buttonViewTapped: (NSNotification *)notification{
// receive the selected buttonView obj passed from the notification
OnScreenButtonView* buttonView = (OnScreenButtonView* )notification.object;
self->buttonViewSelected = true;
- (void)widgetViewTapped: (NSNotification *)notification{
// receive the selected widgetView obj passed from the notification
OnScreenWidgetView* widgetView = (OnScreenWidgetView* )notification.object;
self->widgetViewSelected = true;
self->controllerLayerSelected = false;
self->selectedButtonView = buttonView;
self->selectedWidgetView = widgetView;
// setup slider values
[self.widgetSizeSlider setValue: self->selectedButtonView.widthFactor];
[self.widgetHeightSlider setValue: self->selectedButtonView.heightFactor];
[self.widgetAlphaSlider setValue: self->selectedButtonView.backgroundAlpha];
[self.widgetSizeSlider setValue: self->selectedWidgetView.widthFactor];
[self.widgetHeightSlider setValue: self->selectedWidgetView.heightFactor];
[self.widgetAlphaSlider setValue: self->selectedWidgetView.backgroundAlpha];
[self.widgetBorderWidthSlider setValue:self->selectedWidgetView.borderWidth];
NSSet *stickAndMouseTouchpads = [NSSet setWithObjects:@"LSPAD", @"RSPAD", @"LSVPAD", @"RSVPAD", @"MOUSEPAD", nil];
NSSet *nonVectorStickPads = [NSSet setWithObjects:@"LSPAD", @"RSPAD", nil];
bool showSensitivityFactorSlider = [stickAndMouseTouchpads containsObject:self->selectedButtonView.keyString];
bool showStickIndicatorOffsetSlider = [nonVectorStickPads containsObject:self->selectedButtonView.keyString];
bool showSensitivityFactorSlider = [stickAndMouseTouchpads containsObject:self->selectedWidgetView.keyString];
bool showStickIndicatorOffsetSlider = [nonVectorStickPads containsObject:self->selectedWidgetView.keyString];
self.sensitivityFactorSlider.hidden = self->sensitivitySliderLabel.hidden = !showSensitivityFactorSlider;
self.stickIndicatorOffsetSlider.hidden = self->stickIndicatorOffsetExplain.hidden = self->stickIndicatorOffsetSliderLabel.hidden = !showStickIndicatorOffsetSlider;
if(showSensitivityFactorSlider){
[self.sensitivityFactorSlider setValue:self->selectedButtonView.sensitivityFactor];
[sensitivitySliderLabel setText:[LocalizationHelper localizedStringForKey:@"Sensitivity: %.2f", self->selectedButtonView.sensitivityFactor]];
[self.sensitivityFactorSlider setValue:self->selectedWidgetView.sensitivityFactor];
[sensitivitySliderLabel setText:[LocalizationHelper localizedStringForKey:@"Sensitivity: %.2f", self->selectedWidgetView.sensitivityFactor]];
}
if(showStickIndicatorOffsetSlider){
// illustrating the indicator offset,
[selectedButtonView.stickBallLayer removeFromSuperlayer];
[selectedButtonView.crossMarkLayer removeFromSuperlayer];
selectedButtonView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedButtonView.frame)/2, CGRectGetHeight(selectedButtonView.frame)/4);
[selectedButtonView showStickIndicator];// this will create the indicator CAShapeLayers
[self.stickIndicatorOffsetSlider setValue:self->selectedButtonView.stickIndicatorXOffset];
[stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self->selectedButtonView.stickIndicatorXOffset]];
[self->selectedButtonView updateStickIndicator];
[selectedWidgetView.stickBallLayer removeFromSuperlayer];
[selectedWidgetView.crossMarkLayer removeFromSuperlayer];
selectedWidgetView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedWidgetView.frame)/2, CGRectGetHeight(selectedWidgetView.frame)/4);
[selectedWidgetView showStickIndicator];// this will create the indicator CAShapeLayers
[self.stickIndicatorOffsetSlider setValue:self->selectedWidgetView.stickIndicatorXOffset];
[stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self->selectedWidgetView.stickIndicatorXOffset]];
[self->selectedWidgetView updateStickIndicator];
}
[widgetSizeSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Size: %.2f", self->selectedButtonView.widthFactor]];
[widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self->selectedButtonView.heightFactor]];
[widgetAlphaSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Alpha: %.2f", self->selectedButtonView.backgroundAlpha]];
[widgetSizeSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Size: %.2f", self->selectedWidgetView.widthFactor]];
[widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self->selectedWidgetView.heightFactor]];
[widgetAlphaSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Alpha: %.2f", self->selectedWidgetView.backgroundAlpha]];
[widgetBorderWidthSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Border Width: %.2f", self->selectedWidgetView.borderWidth]];
}
- (void)setControllerCALayerSliderValues: (NSNotification *)notification{
// receive the selected buttonView obj passed from the notification
// receive the selected widgetView obj passed from the notification
CALayer* controllerLayer = (CALayer* )notification.object;
self->buttonViewSelected = false;
self->widgetViewSelected = false;
self->stickIndicatorOffsetExplain.hidden = true;
self->stickIndicatorOffsetSliderLabel.hidden = true;
self.stickIndicatorOffsetSlider.hidden = true;
@@ -457,11 +464,11 @@
[widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self.widgetSizeSlider.value]]; // resizing the whole button
[self.widgetHeightSlider setValue: self.widgetSizeSlider.value];
if(self->selectedButtonView != nil && self->buttonViewSelected){
self->selectedButtonView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
// when adjusting width, the buttonView height will be syncronized
self->selectedButtonView.widthFactor = self->selectedButtonView.heightFactor = self.widgetSizeSlider.value;
[self->selectedButtonView resizeButtonView];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
self->selectedWidgetView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
// when adjusting width, the widgetView height will be syncronized
self->selectedWidgetView.widthFactor = self->selectedWidgetView.heightFactor = self.widgetSizeSlider.value;
[self->selectedWidgetView resizeWidgetView];
}
if(self->selectedControllerLayer != nil && self->controllerLayerSelected){
[self.layoutOSC resizeControllerLayerWith:self->selectedControllerLayer and:self.widgetSizeSlider.value];
@@ -470,18 +477,18 @@
- (void)widgetHeightSliderMoved{
[widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self.widgetHeightSlider.value]];
if(self->selectedButtonView != nil && self->buttonViewSelected){
self->selectedButtonView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
if([CommandManager.oscButtonMappings.allKeys containsObject:selectedButtonView.keyString]) return; // don't change custom osc button height
self->selectedButtonView.heightFactor = self.widgetHeightSlider.value;
[self->selectedButtonView resizeButtonView];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
self->selectedWidgetView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
if([CommandManager.oscButtonMappings.allKeys containsObject:selectedWidgetView.keyString] && ![CommandManager.oscRectangleButtonCmds containsObject:selectedWidgetView.keyString]) return; // don't change custom osc button height, except for dPad buttons which are in rectangle shape
self->selectedWidgetView.heightFactor = self.widgetHeightSlider.value;
[self->selectedWidgetView resizeWidgetView];
}
}
- (void)widgetAlphaSliderMoved{
[widgetAlphaSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Alpha: %.2f", self.widgetAlphaSlider.value]];
if(self->selectedButtonView != nil && self->buttonViewSelected){
[self->selectedButtonView adjustButtonTransparencyWithAlpha:self.widgetAlphaSlider.value];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
[self->selectedWidgetView adjustTransparencyWithAlpha:self.widgetAlphaSlider.value];
}
if(self->selectedControllerLayer != nil && self->controllerLayerSelected){
@@ -490,24 +497,32 @@
return;
}
- (void)widgetBorderWidthSliderMoved{
[widgetBorderWidthSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Border Width: %.2f", self.widgetBorderWidthSlider.value]];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
[self->selectedWidgetView adjustBorderWithWidth:self.widgetBorderWidthSlider.value];
}
return;
}
- (void)sensitivitySliderMoved{
[sensitivitySliderLabel setText:[LocalizationHelper localizedStringForKey:@"Sensitivity: %.2f", self.sensitivityFactorSlider.value]];
if(self->selectedButtonView != nil && self->buttonViewSelected) self->selectedButtonView.sensitivityFactor = self.sensitivityFactorSlider.value;
if(self->selectedWidgetView != nil && self->widgetViewSelected) self->selectedWidgetView.sensitivityFactor = self.sensitivityFactorSlider.value;
return;
}
- (void)stickIndicatorOffsetSliderMoved{
[stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self.stickIndicatorOffsetSlider.value]];
if(self->selectedButtonView != nil && self->buttonViewSelected){
self->selectedButtonView.stickIndicatorXOffset = self.stickIndicatorOffsetSlider.value;
[self->selectedButtonView updateStickIndicator];
if(self->selectedWidgetView != nil && self->widgetViewSelected){
self->selectedWidgetView.stickIndicatorXOffset = self.stickIndicatorOffsetSlider.value;
[self->selectedWidgetView updateStickIndicator];
}
return;
}
- (void)showIndicatorOffset{
selectedButtonView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedButtonView.frame)/2, CGRectGetHeight(selectedButtonView.frame)/4);
[selectedButtonView showStickIndicator];
selectedWidgetView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedWidgetView.frame)/2, CGRectGetHeight(selectedWidgetView.frame)/4);
[selectedWidgetView showStickIndicator];
}
- (void)setupProfileLableAndSliders{
@@ -589,6 +604,27 @@
widgetAlphaSliderLabel.hidden = NO;
// border Width slider
self.widgetBorderWidthSlider.hidden = NO;
self.widgetBorderWidthSlider.frame = CGRectMake(CGRectGetMaxX(self.currentProfileLabel.frame)-self.widgetBorderWidthSlider.frame.size.width, self.widgetBorderWidthSlider.frame.origin.y, self.widgetBorderWidthSlider.frame.size.width, self.widgetBorderWidthSlider.frame.size.height);
[self.widgetBorderWidthSlider addTarget:self action:@selector(widgetBorderWidthSliderMoved) forControlEvents:(UIControlEventValueChanged)];
widgetBorderWidthSliderLabel.text = [LocalizationHelper localizedStringForKey:@"Border Width"];
widgetBorderWidthSliderLabel.font = [UIFont systemFontOfSize:18];
widgetBorderWidthSliderLabel.textColor = [UIColor whiteColor];
widgetBorderWidthSliderLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
widgetBorderWidthSliderLabel.translatesAutoresizingMaskIntoConstraints = NO; // Disable autoresizing mask for Auto Layout
[self.view addSubview:widgetBorderWidthSliderLabel];
[NSLayoutConstraint activateConstraints:@[
// Position the label to the left of the slider
[widgetBorderWidthSliderLabel.trailingAnchor constraintEqualToAnchor:self.widgetBorderWidthSlider.leadingAnchor constant:-10],
// Align vertically with the slider
[widgetBorderWidthSliderLabel.centerYAnchor constraintEqualToAnchor:self.widgetBorderWidthSlider.centerYAnchor]
]];
widgetBorderWidthSliderLabel.hidden = NO;
// sensitivity slider
self.sensitivityFactorSlider.hidden = YES;
self.sensitivityFactorSlider.frame = CGRectMake(sliderXPosition, self.sensitivityFactorSlider.frame.origin.y, self.sensitivityFactorSlider.frame.size.width, self.sensitivityFactorSlider.frame.size.height);
@@ -609,6 +645,7 @@
]];
sensitivitySliderLabel.hidden = self.sensitivityFactorSlider.hidden;
// stick indicator offset slider
self.stickIndicatorOffsetSlider.hidden = YES;
self.stickIndicatorOffsetSlider.frame = CGRectMake(sliderXPosition, self.stickIndicatorOffsetSlider.frame.origin.y, self.stickIndicatorOffsetSlider.frame.size.width, self.stickIndicatorOffsetSlider.frame.size.height); // make this label bigger to show some tips
@@ -671,7 +708,7 @@
};
[self.oscProfilesTableViewController profileViewRefresh]; // execute this will make sure OSCLayout is updated from persisted profile, not any cache.
[self reloadOnScreenButtonViews];
[self reloadOnScreenWidgetViews];
// [self presentViewController:vc animated:YES completion:nil];
}
@@ -732,7 +769,9 @@
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// for OnScreenWidgets:
// -------- for OSC buttons
[self.layoutOSC touchesMoved:touches withEvent:event];
if ([self.layoutOSC isLayer:self.layoutOSC.layerBeingDragged
@@ -768,11 +807,11 @@
// removing keyboard buttons objs
UITouch *touch = [touches anyObject]; // Get the first touch in the set
if([self touchWithinTashcanButton:touch]){
[self.onScreenButtonViewsDict[@(OnScreenButtonView.timestampOfButtonBeingDragged)] removeFromSuperview];
[self.onScreenButtonViewsDict removeObjectForKey:@(OnScreenButtonView.timestampOfButtonBeingDragged)];
[selectedButtonView.stickBallLayer removeFromSuperlayer];
[selectedButtonView.crossMarkLayer removeFromSuperlayer];
OnScreenButtonView.timestampOfButtonBeingDragged = 0; //reset thie timestamp
[self.OnScreenWidgetViewsDict[@(OnScreenWidgetView.timestampOfButtonBeingDragged)] removeFromSuperview];
[self.OnScreenWidgetViewsDict removeObjectForKey:@(OnScreenWidgetView.timestampOfButtonBeingDragged)];
[selectedWidgetView.stickBallLayer removeFromSuperlayer];
[selectedWidgetView.crossMarkLayer removeFromSuperlayer];
OnScreenWidgetView.timestampOfButtonBeingDragged = 0; //reset thie timestamp
}
@@ -625,6 +625,7 @@ const int FrontViewPositionNone = 0xff;
- (void)_initDefaultProperties
{
_mainFrameIsInHostView = true;
_frontViewPosition = FrontViewPositionLeft;
_rearViewPosition = FrontViewPositionLeft;
_rightViewPosition = FrontViewPositionLeft;
@@ -736,7 +737,6 @@ const int FrontViewPositionNone = 0xff;
// tested on iOS17. this method does not call back on iOS14, runtime orientation limitation not working for iOS14. Probably depends on iOS16 or higher.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
// Return the supported interface orientations acoordingly
if(self.mainFrameIsInHostView){
if([self isIphone]) return UIInterfaceOrientationMaskLandscape; //always try to lock orientaion to landscape in mainFrameView in order to prevent bug.
else return [self getCurrentOrientation]; //always try to lock current orientaion in mainFrameView for iPad in order to prevent bug.
@@ -452,7 +452,7 @@ BOOL isCustomResolution(CGSize res) {
[self.hdrSelector setSelectedSegmentIndex:currentSettings.enableHdr ? 1 : 0];
}
[self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlay ? 1 : 0];
[self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlayLevel.intValue];
[self.btMouseSelector setSelectedSegmentIndex:currentSettings.btMouseSupport ? 1 : 0];
[self.optimizeSettingsSelector setSelectedSegmentIndex:currentSettings.optimizeGames ? 1 : 0];
[self.framePacingSelector setSelectedSegmentIndex:currentSettings.useFramePacing ? 1 : 0];
@@ -503,17 +503,17 @@ BOOL isCustomResolution(CGSize res) {
//TouchMode & OSC Related Settings:
// pointer veloc setting, will be enable/disabled by touchMode
[self.pointerVelocityModeDividerSlider setValue:[self map_SliderValue_fromVelocFactor:currentSettings.pointerVelocityModeDivider.floatValue] animated:YES]; // Load old setting.
[self.pointerVelocityModeDividerSlider setValue: (uint8_t)(currentSettings.pointerVelocityModeDivider.floatValue * 100) animated:YES]; // Load old setting.
[self.pointerVelocityModeDividerSlider addTarget:self action:@selector(pointerVelocityModeDividerSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
[self pointerVelocityModeDividerSliderMoved];
// init pointer veloc setting, will be enable/disabled by touchMode
[self.touchPointerVelocityFactorSlider setValue:currentSettings.touchPointerVelocityFactor.floatValue * 100 animated:YES]; // Load old setting.
[self.touchPointerVelocityFactorSlider setValue: [self map_SliderValue_fromVelocFactor: currentSettings.touchPointerVelocityFactor.floatValue] animated:YES]; // Load old setting.
[self.touchPointerVelocityFactorSlider addTarget:self action:@selector(touchPointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
[self touchPointerVelocityFactorSliderMoved];
// init relative touch mouse pointer veloc setting, will be enable/disabled by touchMode
[self.mousePointerVelocityFactorSlider setValue:currentSettings.mousePointerVelocityFactor.floatValue * 100 animated:YES]; // Load old setting.
[self.mousePointerVelocityFactorSlider setValue:[self map_SliderValue_fromVelocFactor: currentSettings.mousePointerVelocityFactor.floatValue] animated:YES]; // Load old setting.
[self.mousePointerVelocityFactorSlider addTarget:self action:@selector(mousePointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
[self mousePointerVelocityFactorSliderMoved];
@@ -687,6 +687,7 @@ BOOL isCustomResolution(CGSize res) {
}
// veloc factor upto 700%
- (CGFloat) map_SliderValue_fromVelocFactor:(CGFloat)velocFactor{
CGFloat sliderValue = 0.0f;
if(velocFactor < 2.0f) sliderValue = velocFactor * 100;
@@ -695,7 +696,7 @@ BOOL isCustomResolution(CGSize res) {
}
- (void) mousePointerVelocityFactorSliderMoved {
[self.mousePointerVelocityFactorUILabel setText:[LocalizationHelper localizedStringForKey: @"Mouse Pointer Velocity: %d%%", (uint16_t)self.mousePointerVelocityFactorSlider.value]]; // Update label display
[self.mousePointerVelocityFactorUILabel setText:[LocalizationHelper localizedStringForKey: @"Mouse Pointer Velocity: %d%%", [self map_velocFactorDisplay_fromSliderValue: self.mousePointerVelocityFactorSlider.value]]]; // Update label display
}
- (uint32_t) getScreenEdgeFromSelector {
@@ -1046,8 +1047,10 @@ BOOL isCustomResolution(CGSize res) {
CGFloat slideToSettingsDistance = self.slideToMenuDistanceSlider.value;
uint32_t slideToSettingsScreenEdge = [self getScreenEdgeFromSelector];
CGFloat pointerVelocityModeDivider = (CGFloat)(uint8_t)self.pointerVelocityModeDividerSlider.value/100;
CGFloat touchPointerVelocityFactor =(CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value]/100;
CGFloat mousePointerVelocityFactor =(CGFloat)(uint16_t)self.mousePointerVelocityFactorSlider.value/100;
CGFloat touchPointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value]/100;
CGFloat mousePointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.mousePointerVelocityFactorSlider.value]/100;
// CGFloat mousePointerVelocityFactor =(CGFloat)(uint16_t)self.mousePointerVelocityFactorSlider.value/100;
CGFloat oscTapExlusionAreaSize =(CGFloat)(uint16_t)self.oscTapExlusionAreaSizeSlider.value/100;
BOOL reverseMouseWheelDirection = [self.reverseMouseWheelDirectionSelector selectedSegmentIndex] == 1;
@@ -1063,7 +1066,8 @@ BOOL isCustomResolution(CGSize res) {
BOOL useFramePacing = [self.framePacingSelector selectedSegmentIndex] == 1;
// BOOL absoluteTouchMode = [self.touchModeSelector selectedSegmentIndex] == 1;
NSInteger touchMode = [self.touchModeSelector selectedSegmentIndex];
BOOL statsOverlay = [self.statsOverlaySelector selectedSegmentIndex] == 1;
NSInteger statsOverlayLevel = [self.statsOverlaySelector selectedSegmentIndex];
BOOL statsOverlayEnabled = statsOverlayLevel != 0;
BOOL enableHdr = [self.hdrSelector selectedSegmentIndex] == 1;
BOOL unlockDisplayOrientation = [self.unlockDisplayOrientationSelector selectedSegmentIndex] == 1;
NSInteger resolutionSelected = [self.resolutionSelector selectedSegmentIndex];
@@ -1097,7 +1101,8 @@ BOOL isCustomResolution(CGSize res) {
btMouseSupport:btMouseSupport
// absoluteTouchMode:absoluteTouchMode
touchMode:touchMode
statsOverlay:statsOverlay
statsOverlayLevel:statsOverlayLevel
statsOverlayEnabled:statsOverlayEnabled
unlockDisplayOrientation:unlockDisplayOrientation
resolutionSelected:resolutionSelected
externalDisplayMode:externalDisplayMode
@@ -47,6 +47,7 @@
UITapGestureRecognizer *_menuDoubleTapGestureRecognizer;
UITapGestureRecognizer *_playPauseTapGestureRecognizer;
UITextView *_overlayView;
uint16_t overlayLevel;
UILabel *_stageLabel;
UILabel *_tipLabel;
UIActivityIndicatorView *_spinner;
@@ -58,7 +59,7 @@
UIView *_streamVideoRenderView;
/*
* View architecture of this viewController:
* self.view (named `streamFrameTopLayerView` in StreamView.m, where slide & tap gestures, and onScreenControls & onScreenButtonView buttons are registered)
* self.view (named `streamFrameTopLayerView` in StreamView.m, where slide & tap gestures, and onScreenControls & OnScreenWidgetView buttons are registered)
* - streamView (where touchHandlers are registered)
* - streamVideoRenderView (where stream view is rendered)
*/
@@ -160,6 +161,7 @@
}
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
overlayLevel = _settings.statsOverlayLevel.intValue;
[self configOscLayoutTool];
[self configSwipeGestures];
[self configZoomGestureAndAddStreamView];
@@ -171,7 +173,7 @@
// 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.
[self->_streamView reloadOnScreenButtonViews]; //reload keyboard buttons here. the keyboard button view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering
[self->_streamView reloadOnScreenWidgetViews]; //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
[self reloadAirPlayConfig];
[self mousePresenceChanged];
@@ -180,7 +182,7 @@
target:self
selector:@selector(updateStatsOverlay)
userInfo:nil
repeats:_settings.statsOverlay];
repeats:_settings.statsOverlayEnabled];
NSLog(@"frameview gestures: %d", (uint32_t)[self.view.gestureRecognizers count]);
NSLog(@"streamview gestures: %d", (uint32_t)[_streamView.gestureRecognizers count]);
@@ -400,7 +402,7 @@
[self->_streamView reloadOnScreenControlsWith:(ControllerSupport*)_controllerSupport
andConfig:(StreamConfiguration*)_streamConfig];
[self->_streamView showOnScreenControls];
[self->_streamView reloadOnScreenButtonViews]; //update keyboard buttons here
[self->_streamView reloadOnScreenWidgetViews]; //update keyboard buttons here
}
@@ -447,13 +449,13 @@
#endif
- (void)updateStatsOverlay {
if(!_settings.statsOverlay){
if(!_settings.statsOverlayEnabled){
[_overlayView removeFromSuperview];
return; // add this for realtime streamview reconfig
}
else [self.view addSubview:_overlayView]; // don't know why but this is necessary for reactivating overlay.
NSString* overlayText = [self->_streamMan getStatsOverlayText];
NSString* overlayText = [self->_streamMan getStatsOverlayText:overlayLevel];
dispatch_async(dispatch_get_main_queue(), ^{
[self updateOverlayText:overlayText];
});
@@ -479,7 +481,13 @@
#if TARGET_OS_TV
[_overlayView setFont:[UIFont systemFontOfSize:24]];
#else
[_overlayView setFont:[UIFont systemFontOfSize:12]];
if (@available(iOS 13.0, *)) {
[_overlayView setFont:[UIFont monospacedSystemFontOfSize:12 weight:UIFontWeightRegular]];
} else {
[_overlayView setFont:[UIFont systemFontOfSize:12]];// Fallback on earlier versions
}
//[_overlayView setFont:[UIFont fontWithName:@"Menlo" size:12]];
#endif
[_overlayView setAlpha:0.5];
[self.view addSubview:_overlayView];
@@ -675,7 +683,7 @@
[self->_controllerSupport connectionEstablished];
if (self->_settings.statsOverlay) {
if (self->_settings.statsOverlayEnabled) {
self->_statsUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(updateStatsOverlay)
@@ -976,7 +984,7 @@
DataManager* dataMan = [[DataManager alloc] init];
Settings *currentSettings = [dataMan retrieveSettings];
currentSettings.statsOverlay = !currentSettings.statsOverlay;
currentSettings.statsOverlayEnabled = !currentSettings.statsOverlayEnabled;
[dataMan saveData];
[self reConfigStreamViewRealtime];
+40 -10
View File
@@ -1718,61 +1718,91 @@
}
},
"NLH-qN-qCo.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[0] = \"No\"; ObjectID = \"NLH-qN-qCo\";",
"comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[0] = \"Off\"; ObjectID = \"NLH-qN-qCo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "No"
"value" : "Off"
}
},
"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" : "关闭"
}
}
}
},
"NLH-qN-qCo.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[1] = \"Yes\"; ObjectID = \"NLH-qN-qCo\";",
"comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[1] = \"Simplified\"; ObjectID = \"NLH-qN-qCo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Yes"
"value" : "Simplified"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "启用"
"value" : "精简"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "启用"
"value" : "精简"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "启用"
"value" : "精简"
}
}
}
},
"NLH-qN-qCo.segmentTitles[2]" : {
"comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[2] = \"Detailed\"; ObjectID = \"NLH-qN-qCo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Detailed"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "完整"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "完整"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "完整"
}
}
}
+40 -10
View File
@@ -1940,61 +1940,91 @@
}
},
"rdz-eg-2oR.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[0] = \"No\"; ObjectID = \"rdz-eg-2oR\";",
"comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[0] = \"Off\"; ObjectID = \"rdz-eg-2oR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "No"
"value" : "Off"
}
},
"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" : "关闭"
}
}
}
},
"rdz-eg-2oR.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[1] = \"Yes\"; ObjectID = \"rdz-eg-2oR\";",
"comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[1] = \"Simplified\"; ObjectID = \"rdz-eg-2oR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Yes"
"value" : "Simplified"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "启用"
"value" : "精简"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "启用"
"value" : "精简"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "启用"
"value" : "精简"
}
}
}
},
"rdz-eg-2oR.segmentTitles[2]" : {
"comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[2] = \"Detailed\"; ObjectID = \"rdz-eg-2oR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Detailed"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "完整"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "完整"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "完整"
}
}
}
+4 -4
View File
@@ -8,7 +8,7 @@
/* Begin PBXBuildFile section */
840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
84203F232C5F24C00032EEED /* OnScreenButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84203F222C5F24C00032EEED /* OnScreenButtonView.swift */; };
84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */; };
84351B0E2C29ACCB00A77989 /* LayoutOnScreenControls.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */; };
84351B0F2C29ACCB00A77989 /* OnScreenButtonState.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B092C29ACCA00A77989 /* OnScreenButtonState.m */; };
84351B102C29ACCB00A77989 /* OSCProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B0A2C29ACCA00A77989 /* OSCProfile.m */; };
@@ -127,7 +127,7 @@
693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomTapGestureRecognizer.h; sourceTree = "<group>"; };
840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomTapGestureRecognizer.m; sourceTree = "<group>"; };
84203F222C5F24C00032EEED /* OnScreenButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnScreenButtonView.swift; sourceTree = "<group>"; };
84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnScreenWidgetView.swift; sourceTree = "<group>"; };
84351B062C29ACCA00A77989 /* OnScreenButtonState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnScreenButtonState.h; sourceTree = "<group>"; };
84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LayoutOnScreenControls.m; sourceTree = "<group>"; };
84351B082C29ACCA00A77989 /* OSCProfilesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSCProfilesManager.h; sourceTree = "<group>"; };
@@ -630,7 +630,7 @@
988FCD3F293B091B003050E2 /* KeyboardInputField.h */,
988FCD40293B091B003050E2 /* KeyboardInputField.m */,
84E1CDEB2C4F67D300547904 /* CommandManager.swift */,
84203F222C5F24C00032EEED /* OnScreenButtonView.swift */,
84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */,
);
path = Input;
sourceTree = "<group>";
@@ -1036,7 +1036,7 @@
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */,
FB89463019F646E200339C8A /* StreamConfiguration.m in Sources */,
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
84203F232C5F24C00032EEED /* OnScreenButtonView.swift in Sources */,
84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */,
84FD0B512C31338D006B5BE5 /* LocalizationHelper.m in Sources */,
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */,
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,