generic improvements & fixes
This commit is contained in:
1 parent
3d82009d4a
commit
5bd9c6bd98
21 files changed
+487
-1005
No files matched your search
@@ -2,6 +2,7 @@
|
|||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24506" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="EVd-wq-ego">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24506" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="EVd-wq-ego">
|
||||||
<device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
|
<device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24504"/>
|
||||||
<capability name="Image references" minToolsVersion="12.0"/>
|
<capability name="Image references" minToolsVersion="12.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView">
|
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
|
<rect key="frame" x="0.0" y="0.0" width="834" height="1124"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
|
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
|
||||||
@@ -1145,16 +1146,16 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="pTO-ff-set">
|
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="pTO-ff-set">
|
||||||
<rect key="frame" x="3145" y="191" width="293.5" height="31"/>
|
<rect key="frame" x="3145" y="191" width="275.5" height="31"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Pencil Tip Offset" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pTO-ff-lbl" userLabel="uiLabel">
|
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Pencil Tip Offset" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.64999997615814209" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pTO-ff-lbl" userLabel="uiLabel">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="143.5" height="31"/>
|
<rect key="frame" x="0.0" y="0.0" width="125.5" height="31"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pTO-ff-swi">
|
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pTO-ff-swi">
|
||||||
<rect key="frame" x="163.5" y="0.0" width="132" height="31"/>
|
<rect key="frame" x="145.5" y="0.0" width="132" height="31"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="130" id="pTO-ff-wid"/>
|
<constraint firstAttribute="width" constant="130" id="pTO-ff-wid"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
@@ -2079,19 +2080,19 @@
|
|||||||
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="WtH-Ii-ZUv">
|
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="WtH-Ii-ZUv">
|
||||||
<rect key="frame" x="3145" y="426" width="380" height="56.5"/>
|
<rect key="frame" x="3145" y="426" width="380" height="56.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hover Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DhB-EF-mDt">
|
<label verifyAmbiguity="off" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Pencil Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DhB-EF-mDt">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="t12-bo-icS">
|
<segmentedControl verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" apportionsSegmentWidthsByContent="YES" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="t12-bo-icS">
|
||||||
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
|
<rect key="frame" x="0.0" y="25.5" width="380" height="32"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Disabled"/>
|
<segment title="Hovering Disabled"/>
|
||||||
<segment title="Stylus"/>
|
<segment title="Stylus"/>
|
||||||
<segment title="Mouse"/>
|
<segment title="Mouse"/>
|
||||||
<segment title="Both"/>
|
<segment title="Touch"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="selectedSegmentTintColor" systemColor="linkColor"/>
|
<color key="selectedSegmentTintColor" systemColor="linkColor"/>
|
||||||
@@ -2325,8 +2326,6 @@
|
|||||||
<outlet property="hapticEngineStack" destination="MUp-Hc-VgH" id="XuW-ww-cmv"/>
|
<outlet property="hapticEngineStack" destination="MUp-Hc-VgH" id="XuW-ww-cmv"/>
|
||||||
<outlet property="hdrStack" destination="dH7-Sy-EdJ" id="cJm-bj-Aqo"/>
|
<outlet property="hdrStack" destination="dH7-Sy-EdJ" id="cJm-bj-Aqo"/>
|
||||||
<outlet property="hdrSwitch" destination="wIq-fF-X8l" id="Ozz-h0-nJL"/>
|
<outlet property="hdrSwitch" destination="wIq-fF-X8l" id="Ozz-h0-nJL"/>
|
||||||
<outlet property="hoverModeSelector" destination="t12-bo-icS" id="0d6-QD-Mtg"/>
|
|
||||||
<outlet property="hoverModeStack" destination="WtH-Ii-ZUv" id="BvA-MP-rmE"/>
|
|
||||||
<outlet property="leftClickDelaySlider" destination="Mh4-1P-bSv" id="Tbj-Y0-t1x"/>
|
<outlet property="leftClickDelaySlider" destination="Mh4-1P-bSv" id="Tbj-Y0-t1x"/>
|
||||||
<outlet property="leftClickDelayStack" destination="q0S-CP-V6v" id="0lz-MN-OEb"/>
|
<outlet property="leftClickDelayStack" destination="q0S-CP-V6v" id="0lz-MN-OEb"/>
|
||||||
<outlet property="leftStickMinOffsetSlider" destination="KtJ-qH-KJX" id="vIV-4l-gbA"/>
|
<outlet property="leftStickMinOffsetSlider" destination="KtJ-qH-KJX" id="vIV-4l-gbA"/>
|
||||||
@@ -2356,6 +2355,8 @@
|
|||||||
<outlet property="optimizeGamesSwitch" destination="Sui-Ig-YxN" id="Lxu-si-ugy"/>
|
<outlet property="optimizeGamesSwitch" destination="Sui-Ig-YxN" id="Lxu-si-ugy"/>
|
||||||
<outlet property="passthroughGesturesStack" destination="wUP-2q-5vh" id="a4w-16-lLs"/>
|
<outlet property="passthroughGesturesStack" destination="wUP-2q-5vh" id="a4w-16-lLs"/>
|
||||||
<outlet property="passthroughGesturesSwitch" destination="eO1-kV-e9j" id="5r8-o4-t9J"/>
|
<outlet property="passthroughGesturesSwitch" destination="eO1-kV-e9j" id="5r8-o4-t9J"/>
|
||||||
|
<outlet property="pencilModeSelector" destination="t12-bo-icS" id="0d6-QD-Mtg"/>
|
||||||
|
<outlet property="pencilModeStack" destination="WtH-Ii-ZUv" id="BvA-MP-rmE"/>
|
||||||
<outlet property="pencilPausesNativeTouchStack" destination="jLJ-Eo-Zi6" id="a4V-Lp-xDG"/>
|
<outlet property="pencilPausesNativeTouchStack" destination="jLJ-Eo-Zi6" id="a4V-Lp-xDG"/>
|
||||||
<outlet property="pencilPausesNativeTouchSwitch" destination="Pjf-Vi-3wE" id="L84-RY-6iV"/>
|
<outlet property="pencilPausesNativeTouchSwitch" destination="Pjf-Vi-3wE" id="L84-RY-6iV"/>
|
||||||
<outlet property="pencilTickIntervalSlider" destination="IOG-l4-gtQ" id="3Kb-uT-ILa"/>
|
<outlet property="pencilTickIntervalSlider" destination="IOG-l4-gtQ" id="3Kb-uT-ILa"/>
|
||||||
@@ -3947,9 +3948,6 @@
|
|||||||
<systemColor name="systemGray3Color">
|
<systemColor name="systemGray3Color">
|
||||||
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</systemColor>
|
</systemColor>
|
||||||
<systemColor name="systemGray5Color">
|
|
||||||
<color red="0.8980392157" green="0.8980392157" blue="0.91764705879999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
</systemColor>
|
|
||||||
<systemColor name="systemTealColor">
|
<systemColor name="systemTealColor">
|
||||||
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</systemColor>
|
</systemColor>
|
||||||
|
|||||||
@@ -389,6 +389,8 @@ import Foundation
|
|||||||
|
|
||||||
@objc static var swapABXY:Bool = false
|
@objc static var swapABXY:Bool = false
|
||||||
|
|
||||||
|
@objc static var gamepadArrivalReported: Bool = false
|
||||||
|
|
||||||
@objc static func string(for element: ControllerElement) -> String {
|
@objc static func string(for element: ControllerElement) -> String {
|
||||||
return element.displayName
|
return element.displayName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,9 +88,8 @@
|
|||||||
[self._dPadBackground addSublayer:self._leftButton];
|
[self._dPadBackground addSublayer:self._leftButton];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"layer name ttttttttttt============================");
|
|
||||||
for(CALayer* buttonLayer in self.OSCButtonLayerPool){
|
for(CALayer* buttonLayer in self.OSCButtonLayerPool){
|
||||||
NSLog(@"layer name %@", buttonLayer.name);
|
// NSLog(@"layer name %@", buttonLayer.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
[self resizeControllerLayerWith:self._dPadBackground and:_dPadSizeFactor];
|
[self resizeControllerLayerWith:self._dPadBackground and:_dPadSizeFactor];
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ typedef NS_ENUM(NSInteger, MapGyroTo) {
|
|||||||
driftCorrection
|
driftCorrection
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, PencilHoverMode) {
|
typedef NS_ENUM(NSInteger, PencilAndHoverMode) {
|
||||||
HoverDisabled,
|
hoverDisabled,
|
||||||
HoverPencil,
|
pencilOnly,
|
||||||
HoverMouse,
|
pencilToMouse,
|
||||||
HoverBoth
|
pencilToTouch
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ typedef NS_ENUM(NSInteger, PencilHoverMode) {
|
|||||||
@property NSString *squeezeEndShortcut;
|
@property NSString *squeezeEndShortcut;
|
||||||
@property (nonatomic, assign) bool pencilPausesNativeTouch;
|
@property (nonatomic, assign) bool pencilPausesNativeTouch;
|
||||||
@property (nonatomic, assign) bool disablePencilSlideGestures;
|
@property (nonatomic, assign) bool disablePencilSlideGestures;
|
||||||
@property (nonatomic, assign) PencilHoverMode pencilHoverMode;
|
@property (nonatomic, assign) PencilAndHoverMode pencilAndHoverMode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
[encoder encodeObject:self.squeezeEndShortcut forKey:@"squeezeEndShortcut"];
|
[encoder encodeObject:self.squeezeEndShortcut forKey:@"squeezeEndShortcut"];
|
||||||
[encoder encodeBool:self.pencilPausesNativeTouch forKey:@"pencilPausesNativeTouch"];
|
[encoder encodeBool:self.pencilPausesNativeTouch forKey:@"pencilPausesNativeTouch"];
|
||||||
[encoder encodeBool:self.disablePencilSlideGestures forKey:@"disablePencilSlideGestures"];
|
[encoder encodeBool:self.disablePencilSlideGestures forKey:@"disablePencilSlideGestures"];
|
||||||
[encoder encodeInt64:self.pencilHoverMode forKey:@"pencilHoverMode"];
|
[encoder encodeInt64:self.pencilAndHoverMode forKey:@"pencilHoverMode"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithCoder:(NSCoder*)decoder {
|
- (id) initWithCoder:(NSCoder*)decoder {
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
|
|
||||||
self.pencilPausesNativeTouch = [decoder containsValueForKey:@"pencilPausesNativeTouch"] ? [decoder decodeBoolForKey:@"pencilPausesNativeTouch"] : false;
|
self.pencilPausesNativeTouch = [decoder containsValueForKey:@"pencilPausesNativeTouch"] ? [decoder decodeBoolForKey:@"pencilPausesNativeTouch"] : false;
|
||||||
self.disablePencilSlideGestures = [decoder containsValueForKey:@"disablePencilSlideGestures"] ? [decoder decodeBoolForKey:@"disablePencilSlideGestures"] : false;
|
self.disablePencilSlideGestures = [decoder containsValueForKey:@"disablePencilSlideGestures"] ? [decoder decodeBoolForKey:@"disablePencilSlideGestures"] : false;
|
||||||
self.pencilHoverMode = [decoder containsValueForKey:@"pencilHoverMode"] ? [decoder decodeInt64ForKey:@"pencilHoverMode"] : HoverPencil;
|
self.pencilAndHoverMode = [decoder containsValueForKey:@"pencilHoverMode"] ? [decoder decodeInt64ForKey:@"pencilHoverMode"] : pencilOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
copy.squeezeEndShortcut = [self.squeezeEndShortcut mutableCopy]; // NSString → NSMutableString
|
copy.squeezeEndShortcut = [self.squeezeEndShortcut mutableCopy]; // NSString → NSMutableString
|
||||||
copy.pencilPausesNativeTouch = self.pencilPausesNativeTouch;
|
copy.pencilPausesNativeTouch = self.pencilPausesNativeTouch;
|
||||||
copy.disablePencilSlideGestures = self.disablePencilSlideGestures;
|
copy.disablePencilSlideGestures = self.disablePencilSlideGestures;
|
||||||
copy.pencilHoverMode = self.pencilHoverMode;
|
copy.pencilAndHoverMode = self.pencilAndHoverMode;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
//
|
|
||||||
// OSCProfilesManager.h
|
|
||||||
// Moonlight
|
|
||||||
//
|
|
||||||
// Created by Long Le on 1/1/23.
|
|
||||||
// Copyright © 2022 Moonlight Game Streaming Project. All rights reserved.
|
|
||||||
//
|
|
||||||
// Modified by True砖家 since 2024.6.24
|
|
||||||
// Copyright © 2024 True砖家 @ Bilibili. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import "OSCProfile.h"
|
|
||||||
#import "DataManager.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
/**
|
|
||||||
This singleton object can be accessed from any class and provides methods to get and set on screen controller profile related data.
|
|
||||||
Note that the implementation file contains a number of 'Helper' methods. These helper methods are only used in this class's implementation file and help to reduce re-writing large blocks of code that are called multiple times throughout the file
|
|
||||||
*/
|
|
||||||
@interface OSCProfilesManager : NSObject
|
|
||||||
@property NSMutableArray <OSCProfile *> *currentProfiles;
|
|
||||||
@property (atomic, assign) WidgetSizeTransition widgetSizeTransition;
|
|
||||||
|
|
||||||
+ (OSCProfilesManager *)sharedManager:(CGRect)viewBounds;
|
|
||||||
+ (void)setOnScreenWidgetViewsSet:(NSMutableSet* )set;
|
|
||||||
+ (void)setLayoutViewBounds:(CGRect)bounds;
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Getters
|
|
||||||
/**
|
|
||||||
* Returns an array of decoded profile objects
|
|
||||||
*/
|
|
||||||
- (NSMutableArray *) getAllProfiles;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the OSC Profile that is currently selected to be displayed on screen during game streaming
|
|
||||||
*/
|
|
||||||
- (OSCProfile *) getSelectedProfile;
|
|
||||||
|
|
||||||
- (uint32_t) getIndexOfLastProfile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index of the 'selected' profile within the array it's in
|
|
||||||
*/
|
|
||||||
- (NSInteger) getIndexOfSelectedProfile;
|
|
||||||
- (NSMutableArray *) getEncodedProfiles;
|
|
||||||
// - (NSData* )getSelectedEncodedProfile;
|
|
||||||
- (void) importEncodedProfiles:(NSMutableArray* )profilesEncoded;
|
|
||||||
- (OnScreenButtonState *)unarchiveButtonStateEncoded:(NSData *)data;
|
|
||||||
- (void) updateDefaultTemplates;
|
|
||||||
- (void) importDefaultTemplates;
|
|
||||||
|
|
||||||
#pragma mark - Setters
|
|
||||||
/**
|
|
||||||
* Sets the profile object with the particular index as the selected profile to be displayed on screen during game streaming
|
|
||||||
*/
|
|
||||||
- (void) setProfileToSelected:(uint32_t)index;
|
|
||||||
- (void) replaceSelectedProfileWith:(OSCProfile*)newProfile overwriteDefault:(bool)overwriteDefault;
|
|
||||||
- (void) replaceProfile:(OSCProfile*)oldProfile withProfile:(OSCProfile*)newProfile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves a profile object with a particular 'name' and an array of button layers (the CALayer button layers are the objects currently visible on screen) to persistent storage
|
|
||||||
*/
|
|
||||||
- (void) duplicateSelectedProfileWithName:(NSString*)name;
|
|
||||||
|
|
||||||
- (bool) updateSelectedProfile:(NSMutableSet *) oscButtonLayers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete current selected profile.
|
|
||||||
*/
|
|
||||||
- (void) deleteCurrentSelectedProfile;
|
|
||||||
|
|
||||||
#pragma mark - Queries
|
|
||||||
/**
|
|
||||||
* Lets the caller of this method know whether a profile with a given name already exists in persistent storage
|
|
||||||
*/
|
|
||||||
- (BOOL) profileNameAlreadyExist:(NSString*)name;
|
|
||||||
- (OSCProfile *) findProfileByName:(NSString*) name inProfileArray:(NSMutableArray*)profiles;
|
|
||||||
- (CGPoint)normalizeWidgetPosition:(CGPoint)position;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
||||||
@@ -1,579 +0,0 @@
|
|||||||
//
|
|
||||||
// OSCProfilesManager.m
|
|
||||||
// Moonlight
|
|
||||||
//
|
|
||||||
// Created by Long Le on 1/1/23.
|
|
||||||
// Copyright © 2023 Moonlight Game Streaming Project. All rights reserved.
|
|
||||||
//
|
|
||||||
// Modified by True砖家 since 2024.6.24
|
|
||||||
// Copyright © 2024 True砖家 @ Bilibili. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "OSCProfilesManager.h"
|
|
||||||
#import "OnScreenButtonState.h"
|
|
||||||
#import "VoidLink-Swift.h"
|
|
||||||
#import "OnScreenControls.h"
|
|
||||||
|
|
||||||
@implementation OSCProfilesManager
|
|
||||||
|
|
||||||
static NSMutableSet *OnScreenWidgetViews;
|
|
||||||
static CGRect layoutViewBounds;
|
|
||||||
|
|
||||||
#pragma mark - Initializer
|
|
||||||
|
|
||||||
+ (OSCProfilesManager *) sharedManager:(CGRect)viewBounds {
|
|
||||||
static OSCProfilesManager *_sharedManager = nil;
|
|
||||||
static dispatch_once_t onceToken;
|
|
||||||
if(!CGRectEqualToRect(viewBounds, CGRectZero)) layoutViewBounds = viewBounds;
|
|
||||||
// NSLog(@"bounds width: %f, height: %f", layoutViewBounds.size.width, layoutViewBounds.size.height);
|
|
||||||
dispatch_once(&onceToken, ^{
|
|
||||||
_sharedManager = [[self alloc] init];
|
|
||||||
});
|
|
||||||
// _sharedManager.currentProfiles = [_sharedManager getAllProfiles];
|
|
||||||
return _sharedManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Class Helper Methods
|
|
||||||
|
|
||||||
|
|
||||||
+ (void)setOnScreenWidgetViewsSet:(NSMutableSet* )set{
|
|
||||||
OnScreenWidgetViews = set;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)setLayoutViewBounds:(CGRect)bounds{
|
|
||||||
layoutViewBounds = bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the profile whose 'name' property has a value that is equal to the 'name' passed into the method
|
|
||||||
*/
|
|
||||||
- (OSCProfile *) OSCProfileWithName:(NSString*)name {
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
|
|
||||||
for (OSCProfile *profile in profiles) {
|
|
||||||
|
|
||||||
if ([profile.name isEqualToString:name]) {
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of encoded 'OSCProfile' objects from the array of decoded 'OSCProfile' objects passed into this method
|
|
||||||
*/
|
|
||||||
- (NSMutableArray *) encodedProfilesFromArray:(NSMutableArray *)profiles {
|
|
||||||
|
|
||||||
NSMutableArray *profilesEncoded = [[NSMutableArray alloc] init];
|
|
||||||
/* encode each profile and add them back into an array */
|
|
||||||
for (OSCProfile *profile in profiles) { //
|
|
||||||
NSData *profileEncoded = [NSKeyedArchiver archivedDataWithRootObject:profile requiringSecureCoding:YES error:nil];
|
|
||||||
[profilesEncoded addObject:profileEncoded];
|
|
||||||
}
|
|
||||||
|
|
||||||
return profilesEncoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an 'OSCProfile' object of specific index for another in the 'OSCProfile' objects array stored in persistent storage
|
|
||||||
*/
|
|
||||||
-(void)deleteCurrentSelectedProfile{
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
NSInteger selectedIndex = [self getIndexOfSelectedProfile];
|
|
||||||
|
|
||||||
/* Remove the selected profile */
|
|
||||||
if(selectedIndex != 0) [profiles removeObjectAtIndex:selectedIndex]; //deleting default profile (index 0) is not allowed
|
|
||||||
else {
|
|
||||||
NSLog(@"Default profile!"); // to be updated here.
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedIndex--;
|
|
||||||
if(selectedIndex < 0) selectedIndex = 0;
|
|
||||||
OSCProfile *newSelectedProfile = [profiles objectAtIndex:selectedIndex];
|
|
||||||
newSelectedProfile.isSelected = YES;
|
|
||||||
|
|
||||||
NSMutableArray *profilesEncoded = [self encodedProfilesFromArray:profiles]; // encode each 'profile' object in the array and add them to a new array
|
|
||||||
|
|
||||||
/* Encode the array itself, NOT the objects in the array, which are already encoded. Save array to persistent storage */
|
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)replaceSelectedProfileWith:(OSCProfile*)newProfile overwriteDefault:(bool)overwriteDefault{
|
|
||||||
NSInteger index = 0;
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
for (OSCProfile *profile in profiles) {
|
|
||||||
if (profile.isSelected == YES) {
|
|
||||||
index = [profiles indexOfObject:profile];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(index>0) profiles[index] = newProfile;
|
|
||||||
else if(overwriteDefault) profiles[index] = newProfile;
|
|
||||||
|
|
||||||
NSMutableArray *profilesEncoded = [self encodedProfilesFromArray:profiles];
|
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replaces one 'OSCProfile' object for another in the 'OSCProfile' objects array stored in persistent storage
|
|
||||||
*/
|
|
||||||
- (void) replaceProfile:(OSCProfile*)oldProfile withProfile:(OSCProfile*)newProfile {
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
|
|
||||||
for (OSCProfile *profile in profiles) { // set all profiles' 'isSelected' property to NO since the new profile we're saving over the old profile with will be the 'selected' profile
|
|
||||||
profile.isSelected = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the new profile as the selected one. The reasoning behind this is that this method is currently being used when the user saves over an existing profile with another profile that has the same name. The expected behavior is that the newly saved profile becomes the selected profile which will show on screen when they launch the game stream view */
|
|
||||||
newProfile.isSelected = YES;
|
|
||||||
|
|
||||||
/* Remove the old profile from the array and insert the new profile into its place */
|
|
||||||
int index = 0;
|
|
||||||
for (int i = 0; i < profiles.count; i++) {
|
|
||||||
|
|
||||||
if ([[profiles[i] name] isEqualToString: oldProfile.name]) {
|
|
||||||
index = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[profiles removeObjectAtIndex:index];
|
|
||||||
[profiles insertObject:newProfile atIndex:index];
|
|
||||||
|
|
||||||
NSMutableArray *profilesEncoded = [self encodedProfilesFromArray:profiles]; // encode each 'profile' object in the array and add them to a new array
|
|
||||||
|
|
||||||
/* Encode the array itself, NOT the objects in the array, which are already encoded. Save array to persistent storage */
|
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSMutableArray *) getEncodedProfiles {
|
|
||||||
NSData *profilesArrayEncoded = [[NSUserDefaults standardUserDefaults] objectForKey: @"OSCProfiles"]; // Get the encoded array of encoded OSC profiles from persistent storage
|
|
||||||
NSSet *classes = [NSSet setWithObjects:[NSString class], [NSMutableData class], [NSMutableArray class], [OSCProfile class], [OnScreenButtonState class], nil];
|
|
||||||
|
|
||||||
NSMutableArray *profilesEncoded = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:profilesArrayEncoded error:nil]; // Decode the encoded array itself, NOT the objects contained in the array
|
|
||||||
|
|
||||||
return profilesEncoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) importEncodedProfiles:(NSMutableArray* )profilesEncoded {
|
|
||||||
NSMutableArray* targetProfiles = [_currentProfiles mutableCopy]; //_currentProfiles is availabled as long as getAllProfiles was called before calling this method (_currentProfiles avoids frequent accessing persisted data)
|
|
||||||
/*
|
|
||||||
profile = [self findProfileByName:DEFAULT_TEMPLATE_NAME1 inProfileArray:targetProfiles];
|
|
||||||
if(profile && targetProfiles.count > 1) [targetProfiles removeObject:profile];
|
|
||||||
profile = [self findProfileByName:DEFAULT_TEMPLATE_NAME2 inProfileArray:targetProfiles];
|
|
||||||
if(profile && targetProfiles.count > 1) [targetProfiles removeObject:profile];
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
|
|
||||||
bool importPencilProProfile = ([bundleId isEqualToString:@"com.voidlink.iOS"]
|
|
||||||
|| [bundleId isEqualToString:@"com.voidlinkextreme.iOS"]
|
|
||||||
|| [bundleId isEqualToString:@"com.voidlink.tf.debug10.iOS"]);
|
|
||||||
|
|
||||||
if(!importPencilProProfile && [GenericUtils isIPad]){
|
|
||||||
[profilesEncoded removeObjectAtIndex:1];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(targetProfiles.count > 0) [targetProfiles removeObjectAtIndex:0];
|
|
||||||
NSMutableArray* localEncodedPofiles = [self encodedProfilesFromArray:targetProfiles];
|
|
||||||
[profilesEncoded addObjectsFromArray:localEncodedPofiles];
|
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (BOOL)isIPhone{
|
|
||||||
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) importDefaultTemplates{
|
|
||||||
NSString *filePath = [[NSBundle mainBundle] pathForResource: [self isIPhone] ? @"widgetTemplatesIPhone": @"widgetTemplates" ofType:@"bin"];
|
|
||||||
if (filePath) {
|
|
||||||
// 2. 读取二进制数据
|
|
||||||
NSError *error;
|
|
||||||
NSData *fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error];
|
|
||||||
NSMutableArray *profilesEncoded;
|
|
||||||
if (fileData && !error) {
|
|
||||||
// 3. 成功读取
|
|
||||||
NSSet *classes = [NSSet setWithObjects: [NSMutableData class], [NSMutableArray class], nil];
|
|
||||||
profilesEncoded = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:fileData error:&error];
|
|
||||||
[self importEncodedProfiles:profilesEncoded];
|
|
||||||
|
|
||||||
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
|
|
||||||
/*
|
|
||||||
bool isRegularTF = !([bundleId isEqualToString:@"com.voidlink.iOS"]
|
|
||||||
|| [bundleId isEqualToString:@"com.voidlinkextreme.iOS"]
|
|
||||||
|| [bundleId isEqualToString:@"com.voidlink.tf.debug10.iOS"]);
|
|
||||||
|
|
||||||
[self setProfileToSelected: GenericUtils.isIPhone ? 1 : (isRegularTF ? 1: 2)]; */
|
|
||||||
[self setProfileToSelected: 0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) updateDefaultTemplates{
|
|
||||||
NSString *filePath = [[NSBundle mainBundle] pathForResource: [self isIPhone] ? @"widgetTemplatesIPhone": @"widgetTemplates" ofType:@"bin"];
|
|
||||||
if (filePath) {
|
|
||||||
// 2. 读取二进制数据
|
|
||||||
NSError *error;
|
|
||||||
NSData *fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error];
|
|
||||||
if (fileData && !error) {
|
|
||||||
NSSet *classes = [NSSet setWithObjects:[NSString class], [NSMutableData class], [NSMutableArray class], [OSCProfile class], [OnScreenButtonState class], nil];
|
|
||||||
NSMutableArray *defaultProfilesEncoded = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:fileData error:nil]; // Decode the encoded array itself, NOT the objects contained in the array
|
|
||||||
OSCProfile *defaultProfileDecoded;
|
|
||||||
NSMutableArray *targetProfilesDecoded = [self getAllProfiles];
|
|
||||||
OSCProfile *newPencilProProfile;
|
|
||||||
bool pencilProProfileExisted = false;
|
|
||||||
for (NSData *profileEncoded in defaultProfilesEncoded) {
|
|
||||||
defaultProfileDecoded = [NSKeyedUnarchiver unarchivedObjectOfClasses: classes fromData:profileEncoded error: nil];
|
|
||||||
OSCProfile *targetProfile = [self findProfileByName:defaultProfileDecoded.name inProfileArray:targetProfilesDecoded];
|
|
||||||
if([defaultProfileDecoded.name isEqualToString:@"Pencil Pro"]){
|
|
||||||
newPencilProProfile = [defaultProfileDecoded mutableCopy];
|
|
||||||
}
|
|
||||||
if(targetProfile){
|
|
||||||
if([targetProfile.name isEqualToString:@"Pencil Pro"]){
|
|
||||||
pencilProProfileExisted = true;
|
|
||||||
}
|
|
||||||
uint64_t targetIndex = [targetProfilesDecoded indexOfObject:targetProfile];
|
|
||||||
targetProfilesDecoded[targetIndex] = defaultProfileDecoded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(newPencilProProfile && !pencilProProfileExisted){
|
|
||||||
if(newPencilProProfile) [targetProfilesDecoded insertObject:newPencilProProfile atIndex:1];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSMutableArray* targetPofilesEncoded = [self encodedProfilesFromArray:targetProfilesDecoded];
|
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:targetPofilesEncoded requiringSecureCoding:YES error:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
[self setProfileToSelected:0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Globally Accessible Methods
|
|
||||||
|
|
||||||
#pragma mark - Getters
|
|
||||||
|
|
||||||
- (NSMutableArray *) getAllProfiles {
|
|
||||||
NSData *profilesArrayEncoded = [[NSUserDefaults standardUserDefaults] objectForKey: @"OSCProfiles"]; // Get the encoded array of encoded OSC profiles from persistent storage
|
|
||||||
NSSet *classes = [NSSet setWithObjects:[NSString class], [NSMutableData class], [NSMutableArray class], [OSCProfile class], [OnScreenButtonState class], nil];
|
|
||||||
|
|
||||||
NSMutableArray *profilesEncoded = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:profilesArrayEncoded error:nil]; // Decode the encoded array itself, NOT the objects contained in the array
|
|
||||||
|
|
||||||
/* Decode each of the encoded profiles, place them into an array, then return the array */
|
|
||||||
NSMutableArray *profilesDecoded = [[NSMutableArray alloc] init];
|
|
||||||
OSCProfile *profileDecoded;
|
|
||||||
for (NSData *profileEncoded in profilesEncoded) {
|
|
||||||
|
|
||||||
profileDecoded = [NSKeyedUnarchiver unarchivedObjectOfClasses: classes fromData:profileEncoded error: nil];
|
|
||||||
[profilesDecoded addObject: profileDecoded];
|
|
||||||
}
|
|
||||||
_currentProfiles = profilesDecoded;
|
|
||||||
return profilesDecoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSMutableArray *) decodeProfilesFrom:(NSMutableArray* )profilesEncoded {
|
|
||||||
NSSet *classes = [NSSet setWithObjects:[NSString class], [NSMutableData class], [NSMutableArray class], [OSCProfile class], [OnScreenButtonState class], nil];
|
|
||||||
NSMutableArray *profilesDecoded = [[NSMutableArray alloc] init];
|
|
||||||
OSCProfile *profileDecoded;
|
|
||||||
for (NSData *profileEncoded in profilesEncoded) {
|
|
||||||
|
|
||||||
profileDecoded = [NSKeyedUnarchiver unarchivedObjectOfClasses: classes fromData:profileEncoded error: nil];
|
|
||||||
[profilesDecoded addObject: profileDecoded];
|
|
||||||
}
|
|
||||||
return profilesDecoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (OSCProfile *) getSelectedProfile {
|
|
||||||
// NSLog(@"getAllProfiles test %f", CACurrentMediaTime());
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
||||||
|
|
||||||
// NSString* persistedKey = @"widgetProfileUpdated-20251015";
|
|
||||||
// NSString* persistedKey = @"widgetProfileUpdated-20260322";
|
|
||||||
// NSString* persistedKey = @"widgetProfileUpdated-20260413-2";
|
|
||||||
// NSString* persistedKey = @"widgetProfileUpdated-20260430-1";
|
|
||||||
// NSString* persistedKey = @"widgetProfileUpdated-20260513-1";
|
|
||||||
NSString* persistedKey = @"widgetProfileUpdated-20260530";
|
|
||||||
BOOL needImportDefaultTemplates = [defaults objectForKey:persistedKey] == nil;
|
|
||||||
|
|
||||||
if(profiles.count == 0 || needImportDefaultTemplates){
|
|
||||||
if(profiles.count == 0) [self importDefaultTemplates];
|
|
||||||
else [self updateDefaultTemplates];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:persistedKey];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
profiles = [self getAllProfiles];
|
|
||||||
}
|
|
||||||
for (OSCProfile *profile in profiles) {
|
|
||||||
if (profile.isSelected) {
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return profiles[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSInteger) getIndexOfSelectedProfile {
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
for (OSCProfile *profile in profiles) {
|
|
||||||
|
|
||||||
if (profile.isSelected == YES) {
|
|
||||||
return [profiles indexOfObject:profile];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0; // if none of the profiles in the array have their 'isSelected' property set to YES (which should not be possible) return the 'Default' profile as the 'selected' profile
|
|
||||||
}
|
|
||||||
|
|
||||||
- (uint32_t) getIndexOfLastProfile {
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
return (uint32_t)profiles.count-1; // if none of the profiles in the array have their 'isSelected' property set to YES (which should not be possible) return the 'Default' profile as the 'selected' profile
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Setters
|
|
||||||
|
|
||||||
- (void) setProfileToSelected:(uint32_t)tableIndex {
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
|
|
||||||
[profiles enumerateObjectsUsingBlock:^(OSCProfile* profile, NSUInteger idx, BOOL *stop) {
|
|
||||||
profile.isSelected = idx == tableIndex;
|
|
||||||
}];
|
|
||||||
|
|
||||||
NSMutableArray *profilesEncoded = [self encodedProfilesFromArray:profiles]; // encode each 'profile' object in the array and add them to a new array
|
|
||||||
|
|
||||||
/* Encode the array itself, NOT the objects inside the array, which have already been encoded by this point */
|
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (bool) updateSelectedProfile:(NSMutableSet *) oscButtonLayers {
|
|
||||||
NSMutableArray* buttonStatesEncoded = [self convertOnScreenControllerAndWidgetsToButtonStates:oscButtonLayers];
|
|
||||||
if([self getIndexOfSelectedProfile]==0) return false;
|
|
||||||
/*
|
|
||||||
OSCProfile *newProfile = [[OSCProfile alloc] initWithName:[self getSelectedProfile].name
|
|
||||||
buttonStates:buttonStatesEncoded isSelected:YES]; // create a new 'OSCProfile'. Set the array of encoded button states created above to the 'buttonStates' property of the new profile, along with a 'name'. Set 'isSelected' argument to YES which will set this saved profile as the one that will show up in the game stream view
|
|
||||||
*/
|
|
||||||
OSCProfile *selectedProfile = [self getSelectedProfile];
|
|
||||||
selectedProfile.buttonStatesEncoded = buttonStatesEncoded;
|
|
||||||
selectedProfile.unfoldedExclusiveFolderSequence = OnScreenWidgetView.unfoldedExclusiveFolderSequence;
|
|
||||||
selectedProfile.postExclusiveUnfoldedSequences = OnScreenWidgetView.postExclusiveUnfoldedSequences;
|
|
||||||
[self replaceSelectedProfileWith:selectedProfile overwriteDefault:NO];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (void) duplicateSelectedProfileWithName:(NSString*)name {
|
|
||||||
if ([self profileNameAlreadyExist:name]) return;
|
|
||||||
else { // otherwise encode then add the new profile to the end of the OSCProfiles array
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
OSCProfile* newProfile = nil;
|
|
||||||
for(OSCProfile* profile in profiles){
|
|
||||||
if(profile.isSelected){
|
|
||||||
profile.isSelected = false;
|
|
||||||
newProfile = [profile mutableCopy];
|
|
||||||
newProfile.isSelected = true;
|
|
||||||
newProfile.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(newProfile){
|
|
||||||
NSData *newProfileEncoded = [NSKeyedArchiver archivedDataWithRootObject:newProfile requiringSecureCoding:YES error:nil];
|
|
||||||
NSMutableArray *profilesEncoded = [self encodedProfilesFromArray:profiles];
|
|
||||||
[profilesEncoded addObject:newProfileEncoded];
|
|
||||||
|
|
||||||
/* Encode the 'profilesEncoded' array itself, NOT the objects in the 'profilesEncoded' array, all of which are already encoded by this point */
|
|
||||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profilesEncoded requiringSecureCoding:YES error:nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"OSCProfiles"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGPoint)normalizeWidgetPosition:(CGPoint)position {
|
|
||||||
CGPoint newPosition = position;
|
|
||||||
if(position.x > 1.0 && position.y >1.0){
|
|
||||||
position.x = position.x / layoutViewBounds.size.width;
|
|
||||||
position.y = position.y / layoutViewBounds.size.height;
|
|
||||||
}
|
|
||||||
NSLog(@"layoutToolView bounds: %f, %f", layoutViewBounds.size.width, layoutViewBounds.size.height);
|
|
||||||
NSLog(@"position: %f, %f, denormalized position: %f, %f", position.x, position.y, newPosition.x, newPosition.y);
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
|
||||||
if(position.x < 1.0 && position.y < 1.0){
|
|
||||||
position.x = position.x * layoutViewBounds.size.width;
|
|
||||||
position.y = position.y * layoutViewBounds.size.height;
|
|
||||||
}
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSMutableArray* ) convertOnScreenControllerAndWidgetsToButtonStates:(NSMutableSet *) oscButtonLayers {
|
|
||||||
/* iterate through each OSC button the user sees on screen, create an 'OnScreenButtonState' object from each button, encode each object, and then add each object to an array */
|
|
||||||
/*
|
|
||||||
NSSet *validPositionButtonNames = [NSSet setWithObjects:
|
|
||||||
@"l2Button",
|
|
||||||
@"l1Button",
|
|
||||||
@"dPad",
|
|
||||||
@"selectButton",
|
|
||||||
@"leftStickBackground",
|
|
||||||
@"rightStickBackground",
|
|
||||||
@"r2Button",
|
|
||||||
@"r1Button",
|
|
||||||
@"aButton",
|
|
||||||
@"bButton",
|
|
||||||
@"xButton",
|
|
||||||
@"yButton",
|
|
||||||
@"startButton",
|
|
||||||
nil]; */
|
|
||||||
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
|
||||||
|
|
||||||
// save on-screen game controller buttons & sticks as buttonstate:
|
|
||||||
for (CALayer *oscButtonLayer in oscButtonLayers) {
|
|
||||||
if(oscButtonLayer.isHidden) continue;
|
|
||||||
|
|
||||||
CGPoint normalizedPosition = [self normalizeWidgetPosition:oscButtonLayer.position];
|
|
||||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:oscButtonLayer.name buttonType:LegacyOnScreenControls andPosition:normalizedPosition];
|
|
||||||
// add hidden attr here
|
|
||||||
buttonState.isHidden = oscButtonLayer.isHidden;
|
|
||||||
buttonState.oscLayerSizeFactor = [OnScreenControls getControllerLayerSizeFactor:oscButtonLayer];
|
|
||||||
buttonState.backgroundAlpha = oscButtonLayer.opacity;
|
|
||||||
|
|
||||||
NSNumber *style = [OnScreenControls.layerVibrationStyleDic objectForKey:oscButtonLayer.name];
|
|
||||||
if ([style isKindOfClass:[NSNumber class]]) {
|
|
||||||
buttonState.vibrationStyle = [style unsignedCharValue];
|
|
||||||
// 使用 val
|
|
||||||
}
|
|
||||||
else buttonState.vibrationStyle = UIImpactFeedbackStyleLight;
|
|
||||||
|
|
||||||
// NSLog(@"oscLayerName: %@, opacity: %f, ", oscButtonLayer.name, buttonState.backgroundAlpha);
|
|
||||||
// buttonState.oscLayerSizeFactor = oscButtonLayer.bounds;
|
|
||||||
|
|
||||||
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
|
||||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
|
||||||
}
|
|
||||||
|
|
||||||
// save on-screen widget views (keyboard & mouse command) as buttonstate:
|
|
||||||
_widgetSizeTransition = keepWidgetSize;
|
|
||||||
for(OnScreenWidgetView* widgetView in OnScreenWidgetView.mapping.allValues){
|
|
||||||
CGPoint normalizedPosition = [self normalizeWidgetPosition:widgetView.storedCenter];
|
|
||||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:widgetView.cmdString buttonType:CustomOnScreenWidget andPosition:normalizedPosition];
|
|
||||||
buttonState.alias = widgetView.widgetLabel;
|
|
||||||
buttonState.sequence = widgetView.sequence;
|
|
||||||
buttonState.sequenceSet = widgetView.sequenceSet;
|
|
||||||
buttonState.parentSequence = widgetView.parentSequence;
|
|
||||||
buttonState.autoDockTimer = widgetView.autoDockIdleDuration;
|
|
||||||
buttonState.dockedAlpha = widgetView.autoDockSettledAlpha;
|
|
||||||
buttonState.folded = widgetView.folded;
|
|
||||||
buttonState.revealMode = widgetView.revealMode;
|
|
||||||
buttonState.bulkMoveEnabled = widgetView.bulkMoveEnabled;
|
|
||||||
buttonState.widthFactor = [self normalizeSizeWidthFactorWith:widgetView];
|
|
||||||
buttonState.heightFactor = [self normalizeSizeHeightFactorWith:widgetView];
|
|
||||||
buttonState.backgroundAlpha = widgetView.originalBackgroundAlpha;
|
|
||||||
buttonState.labelAlpha = widgetView.originalLabelAlpha;
|
|
||||||
buttonState.borderAlpha = widgetView.borderAlpha;
|
|
||||||
buttonState.highlightAlpha = widgetView.highlightAlpha;
|
|
||||||
buttonState.borderWidth = widgetView.borderWidth;
|
|
||||||
buttonState.highlightSizeFactor = widgetView.highlightSizeFactor;
|
|
||||||
buttonState.autoTapInterval = widgetView.autoTapInterval;
|
|
||||||
buttonState.autoTapRepeats = widgetView.autoTapRepeats;
|
|
||||||
buttonState.vibrationStyle = widgetView.vibrationStyle;
|
|
||||||
buttonState.mouseButtonAction = widgetView.mouseButtonAction;
|
|
||||||
buttonState.animatesTransition = widgetView.animatesTransition;
|
|
||||||
buttonState.sensitivityFactorY = widgetView.sensitivityFactorY;
|
|
||||||
buttonState.slideThreshold = widgetView.slideThreshold;
|
|
||||||
buttonState.yawFactor = widgetView.yawFactor;
|
|
||||||
buttonState.pitchFactor = widgetView.pitchFactor;
|
|
||||||
buttonState.rollFactor = widgetView.rollFactor;
|
|
||||||
buttonState.decelerationRateX = widgetView.decelerationRateX;
|
|
||||||
buttonState.decelerationRateY = widgetView.decelerationRateY;
|
|
||||||
buttonState.widgetShape = widgetView.shape;
|
|
||||||
buttonState.walkModeThreshold = widgetView.dWheelWalkModeThreshold;
|
|
||||||
buttonState.minStickOffset = widgetView.minStickOffset;
|
|
||||||
buttonState.buttonMode = widgetView.buttonMode;
|
|
||||||
buttonState.sprintKeyActionType = widgetView.sprintKeyActionType;
|
|
||||||
buttonState.sprintKeyThreshold = widgetView.sprintKeyThreshold;
|
|
||||||
buttonState.walkKeyActionType = widgetView.walkKeyActionType;
|
|
||||||
buttonState.walkKeyThreshold = widgetView.walkKeyThreshold;
|
|
||||||
///
|
|
||||||
buttonState.sensitivityFactorX = widgetView.sensitivityFactorX;
|
|
||||||
buttonState.componentSizeFactor = [self normalizeComponentSizeFactorWith:widgetView];
|
|
||||||
buttonState.touchPointAnchored = widgetView.touchPointAnchored;
|
|
||||||
buttonState.stickIndicatorOffset = widgetView.stickIndicatorOffset;
|
|
||||||
|
|
||||||
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
|
||||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
|
||||||
}
|
|
||||||
return buttonStatesEncoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGFloat)getReferenceLen{
|
|
||||||
CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]);
|
|
||||||
CGFloat screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]);
|
|
||||||
CGFloat longSideLen = fmax(screenWidthInPoints,screenHeightInPoints);
|
|
||||||
CGFloat referenceLen = longSideLen;
|
|
||||||
if(_widgetSizeTransition == keepWidgetSize) referenceLen = longSideLen;
|
|
||||||
if(_widgetSizeTransition == transitionWithOrientation) referenceLen = screenWidthInPoints;
|
|
||||||
return referenceLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGFloat)normalizeSizeWidthFactorWith:(OnScreenWidgetView* )widget{
|
|
||||||
return widget.bounds.size.width/[self getReferenceLen] * 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGFloat)normalizeSizeHeightFactorWith:(OnScreenWidgetView* )widget{
|
|
||||||
return widget.bounds.size.height/[self getReferenceLen] * 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGFloat)normalizeComponentSizeFactorWith:(OnScreenWidgetView* )widget{
|
|
||||||
if(widget.isStickWheel
|
|
||||||
|| widget.isDisplacementBasedStickPad) {
|
|
||||||
return widget.denormalizedComponentSizeFactor*widget.baselineDiameter/[self getReferenceLen] * 10000;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Queries
|
|
||||||
|
|
||||||
- (BOOL) profileNameAlreadyExist:(NSString*)name {
|
|
||||||
NSMutableArray *profiles = [self getAllProfiles];
|
|
||||||
/* Iterate through the decoded profiles and return 'YES' if one of the profiles' 'name' properties equals the 'name' passed into this method */
|
|
||||||
for (OSCProfile *profile in profiles) {
|
|
||||||
if ([profile.name isEqualToString:name]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (OSCProfile *) findProfileByName:(NSString*) name inProfileArray:(NSMutableArray*)profiles {
|
|
||||||
/* Iterate through the decoded profiles and return 'YES' if one of the profiles' 'name' properties equals the 'name' passed into this method */
|
|
||||||
for (OSCProfile *profile in profiles) {
|
|
||||||
if ([profile.name isEqualToString:name]) {
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (OnScreenButtonState *)unarchiveButtonStateEncoded:(NSData *)data {
|
|
||||||
OnScreenButtonState* buttonState;
|
|
||||||
buttonState = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObjects:[NSString class], [OnScreenButtonState class], [NSSet class], [NSNumber class], nil]
|
|
||||||
fromData:data
|
|
||||||
error:nil];
|
|
||||||
return buttonState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -418,8 +418,8 @@ class OSCProfilesManager: NSObject {
|
|||||||
|
|
||||||
func normalizeWidgetPosition(_ position: CGPoint) -> CGPoint {
|
func normalizeWidgetPosition(_ position: CGPoint) -> CGPoint {
|
||||||
var normalizedPosition = position
|
var normalizedPosition = position
|
||||||
let originalPosition = position
|
// let originalPosition = position
|
||||||
if position.x > 1.0, position.y > 1.0 {
|
if abs(position.x) > 1.0, abs(position.y) > 1.0 {
|
||||||
normalizedPosition.x = position.x / Self.layoutViewBounds.size.width
|
normalizedPosition.x = position.x / Self.layoutViewBounds.size.width
|
||||||
normalizedPosition.y = position.y / Self.layoutViewBounds.size.height
|
normalizedPosition.y = position.y / Self.layoutViewBounds.size.height
|
||||||
}
|
}
|
||||||
@@ -430,7 +430,7 @@ class OSCProfilesManager: NSObject {
|
|||||||
|
|
||||||
private func denormalizeWidgetPosition(_ position: CGPoint) -> CGPoint {
|
private func denormalizeWidgetPosition(_ position: CGPoint) -> CGPoint {
|
||||||
var denormalizedPosition = position
|
var denormalizedPosition = position
|
||||||
if position.x < 1.0, position.y < 1.0 {
|
if abs(position.x) < 2.01, abs(position.y) < 2.01 {
|
||||||
denormalizedPosition.x = position.x * Self.layoutViewBounds.size.width
|
denormalizedPosition.x = position.x * Self.layoutViewBounds.size.width
|
||||||
denormalizedPosition.y = position.y * Self.layoutViewBounds.size.height
|
denormalizedPosition.y = position.y * Self.layoutViewBounds.size.height
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -404,8 +404,8 @@ import CoreMotion
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func clearGyroInput(interruptNonGyroInput:Bool){
|
private func clearGyroInput(interruptNonGyroInput:Bool){
|
||||||
// guard let onScreenControls = onScreenControls else { return }
|
guard ControllerUtil.gamepadArrivalReported else { return }
|
||||||
|
|
||||||
if yawPitchToRightStick{
|
if yawPitchToRightStick{
|
||||||
onScreenControls?.sendRightStickTouchPadEvent(rightStickPhysicalInputX+rightStickTouchInputX-yawBias, rightStickPhysicalInputY+rightStickTouchInputY-pitchBias)
|
onScreenControls?.sendRightStickTouchPadEvent(rightStickPhysicalInputX+rightStickTouchInputX-yawBias, rightStickPhysicalInputY+rightStickTouchInputY-pitchBias)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ static float L3_Y;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (CGPoint) denormalizeWidgetPosition:(CGPoint)position {
|
- (CGPoint) denormalizeWidgetPosition:(CGPoint)position {
|
||||||
if(position.x < 1.0 && position.y < 1.0) {
|
if(position.x < 1.01 && position.y < 1.01) {
|
||||||
position.x = position.x * _view.bounds.size.width;
|
position.x = position.x * _view.bounds.size.width;
|
||||||
position.y = position.y * _view.bounds.size.height;
|
position.y = position.y * _view.bounds.size.height;
|
||||||
// NSLog(@"denormalizing position: %f, %f", position.x, position.y);
|
// NSLog(@"denormalizing position: %f, %f", position.x, position.y);
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ import ObjectiveC.runtime
|
|||||||
func alterAbsTouchDragWith(mouseButton:Int32)
|
func alterAbsTouchDragWith(mouseButton:Int32)
|
||||||
func enablePencilHover()
|
func enablePencilHover()
|
||||||
func disablePencilHover()
|
func disablePencilHover()
|
||||||
func setAllowSingleTouchEnabled(_ enabled:Bool)
|
func handleDisableSingleTouchButtonUp()
|
||||||
func replaceBrush(shortcut:String)
|
func replaceBrush(shortcut:String)
|
||||||
func replaceEraser(shortcut:String)
|
func replaceEraser(shortcut:String)
|
||||||
func presentPressureCurveVC()
|
func presentPressureCurveVC()
|
||||||
func toggleTouch(disabled:Bool)
|
func handleTouchDisableButtonUp()
|
||||||
func toggleGamepadOverlay(overlayEnabled:Bool)
|
func toggleGamepadOverlay(overlayEnabled:Bool)
|
||||||
@objc(magnifierMoveStreamViewWithTranslation:)
|
@objc(magnifierMoveStreamViewWithTranslation:)
|
||||||
func magnifierMoveStreamView(translation: CGVector)
|
func magnifierMoveStreamView(translation: CGVector)
|
||||||
@@ -672,14 +672,15 @@ import ObjectiveC.runtime
|
|||||||
self.hasTrackPoint = true
|
self.hasTrackPoint = true
|
||||||
self.hasNonEditableLabel = (self.cmdString == "DISABLETOUCH"
|
self.hasNonEditableLabel = (self.cmdString == "DISABLETOUCH"
|
||||||
|| self.cmdString == "GAMEPADOVERLAY"
|
|| self.cmdString == "GAMEPADOVERLAY"
|
||||||
|| self.cmdString == "DISABLETILT")
|
|| self.cmdString == "DISABLETILT"
|
||||||
|
|| self.cmdString == "NOSINGLETOUCH")
|
||||||
self.hasTemporaryLabel = CommandManager.velocityBasedTouchPads.contains(self.touchPadString) && (self.isMotionControlButton || self.buttonString == "NULL")
|
self.hasTemporaryLabel = CommandManager.velocityBasedTouchPads.contains(self.touchPadString) && (self.isMotionControlButton || self.buttonString == "NULL")
|
||||||
|| self.cmdString == "RSVPAD"
|
|| self.cmdString == "RSVPAD"
|
||||||
|| self.cmdString == "LSVPAD"
|
|| self.cmdString == "LSVPAD"
|
||||||
|
|
||||||
self.mouseButtonActionDelay = self.cmdString.contains("ABSMOUSEPAD") ? 0.005 : 0
|
self.mouseButtonActionDelay = self.cmdString.contains("ABSMOUSEPAD") ? 0.005 : 0
|
||||||
|
|
||||||
self.standardFoldingInterval = widgetType == .touchPad ? 0.05 : 0.15;
|
self.standardFoldingInterval = widgetType == .touchPad ? 0.05 : 0.085;
|
||||||
|
|
||||||
self.isMagnifier = self.cmdString.contains("MAGNIFIER")
|
self.isMagnifier = self.cmdString.contains("MAGNIFIER")
|
||||||
|
|
||||||
@@ -1053,13 +1054,21 @@ import ObjectiveC.runtime
|
|||||||
if self.hasNonEditableLabel {
|
if self.hasNonEditableLabel {
|
||||||
|
|
||||||
switch cmdString {
|
switch cmdString {
|
||||||
case "DISABLETOUCH":
|
|
||||||
self.nonEditableWidgetLabel = LocalizationHelper.localizedString(forKey: touchDisabledFLag ? "=EnableTouch" : "=DisableTouch" )
|
|
||||||
case "GAMEPADOVERLAY":
|
case "GAMEPADOVERLAY":
|
||||||
self.nonEditableWidgetLabel = LocalizationHelper.localizedString(forKey: OnScreenWidgetView.gamepadOverlayFLag ? "=GamepadOverlayOn" : "=GamepadOverlayOff" )
|
self.nonEditableWidgetLabel = OnScreenWidgetView.gamepadOverlayFLag ? "=GamepadOverlayOn".localized : "=GamepadOverlayOff".localized
|
||||||
|
case "DISABLETOUCH":
|
||||||
|
if let vc = StreamFrameViewController.sharedInstance() {
|
||||||
|
self.nonEditableWidgetLabel = vc.touchDisabled ? "=EnableTouch".localized : "=DisableTouch".localized
|
||||||
|
}
|
||||||
|
else {self.nonEditableWidgetLabel = "=DisableTouch".localized}
|
||||||
|
case "NOSINGLETOUCH":
|
||||||
|
if let vc = StreamFrameViewController.sharedInstance() {
|
||||||
|
self.nonEditableWidgetLabel = vc.singleTouchDisabled ? "=EnableSingleTouch".localized : "=DisableSingleTouch".localized
|
||||||
|
}
|
||||||
|
else {self.nonEditableWidgetLabel = "=DisableSingleTouch".localized}
|
||||||
case "DISABLETILT":
|
case "DISABLETILT":
|
||||||
if let pencilHandler = PencilHandler.shared {
|
if let pencilHandler = PencilHandler.shared {
|
||||||
self.nonEditableWidgetLabel = LocalizationHelper.localizedString(forKey: pencilHandler.disableTilt ? "=enableTilt" : "=disableTilt" )
|
self.nonEditableWidgetLabel = pencilHandler.disableTilt ? "=enableTilt".localized : "=disableTilt".localized
|
||||||
}
|
}
|
||||||
else {self.nonEditableWidgetLabel = "=disableTilt".localized}
|
else {self.nonEditableWidgetLabel = "=disableTilt".localized}
|
||||||
default:
|
default:
|
||||||
@@ -1690,7 +1699,7 @@ import ObjectiveC.runtime
|
|||||||
|
|
||||||
// legacy keyboard button combo connected by "+"
|
// legacy keyboard button combo connected by "+"
|
||||||
if !OnScreenWidgetView.editMode && self.cmdString.contains("+") && !self.cmdString.contains("-"){
|
if !OnScreenWidgetView.editMode && self.cmdString.contains("+") && !self.cmdString.contains("-"){
|
||||||
if buttonMode == .movable, moveableButtonLongPressed() {return}
|
if buttonMode == .movable, firstTouchMoved {return}
|
||||||
if leaveNonSkillButtonAlone {return}
|
if leaveNonSkillButtonAlone {return}
|
||||||
self.buttonDownVisualEffect()
|
self.buttonDownVisualEffect()
|
||||||
if var autoReleaseComboButtons = CommandManager.shared.extractAutoReleaseButtonStrings(from: self.cmdString) {
|
if var autoReleaseComboButtons = CommandManager.shared.extractAutoReleaseButtonStrings(from: self.cmdString) {
|
||||||
@@ -1874,7 +1883,7 @@ import ObjectiveC.runtime
|
|||||||
self.onScreenControls?.sendRightStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
|
self.onScreenControls?.sendRightStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
|
||||||
}
|
}
|
||||||
self.motionHandler?.mixOnScreenRightStickAndGyroInput(x: targetX, y: targetY)
|
self.motionHandler?.mixOnScreenRightStickAndGyroInput(x: targetX, y: targetY)
|
||||||
if !OnScreenWidgetView.gamepadArrivalReported {OnScreenWidgetView.gamepadArrivalReported = true}
|
if !ControllerUtil.gamepadArrivalReported {ControllerUtil.gamepadArrivalReported = true}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sendLeftStickTouchPadEvent(weightedTouchX:CGFloat, weightedTouchY:CGFloat, circulate:Bool=false){
|
private func sendLeftStickTouchPadEvent(weightedTouchX:CGFloat, weightedTouchY:CGFloat, circulate:Bool=false){
|
||||||
@@ -1889,7 +1898,7 @@ import ObjectiveC.runtime
|
|||||||
self.onScreenControls?.sendLeftStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
|
self.onScreenControls?.sendLeftStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
|
||||||
}
|
}
|
||||||
self.motionHandler?.mixOnScreenLeftStickAndGyroInput(x: targetX, y: targetY)
|
self.motionHandler?.mixOnScreenLeftStickAndGyroInput(x: targetX, y: targetY)
|
||||||
if !OnScreenWidgetView.gamepadArrivalReported {OnScreenWidgetView.gamepadArrivalReported = true}
|
if !ControllerUtil.gamepadArrivalReported {ControllerUtil.gamepadArrivalReported = true}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sendLeftTriggerTouchPadEvent(inputY: CGFloat){
|
private func sendLeftTriggerTouchPadEvent(inputY: CGFloat){
|
||||||
@@ -1963,7 +1972,7 @@ import ObjectiveC.runtime
|
|||||||
DispatchQueue.global(qos: .userInteractive).async {
|
DispatchQueue.global(qos: .userInteractive).async {
|
||||||
if CommandManager.oscButtonMappings.keys.contains(realButtonString) {
|
if CommandManager.oscButtonMappings.keys.contains(realButtonString) {
|
||||||
self.sendOscButtonDownEvent(oscString: realButtonString)
|
self.sendOscButtonDownEvent(oscString: realButtonString)
|
||||||
if !OnScreenWidgetView.gamepadArrivalReported {OnScreenWidgetView.gamepadArrivalReported = true}
|
if !ControllerUtil.gamepadArrivalReported {ControllerUtil.gamepadArrivalReported = true}
|
||||||
}
|
}
|
||||||
if CommandManager.keyboardButtonMappings.keys.contains(realButtonString) {
|
if CommandManager.keyboardButtonMappings.keys.contains(realButtonString) {
|
||||||
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings[realButtonString]!,Int8(KEY_ACTION_DOWN), 0)
|
LiSendKeyboardEvent(CommandManager.keyboardButtonMappings[realButtonString]!,Int8(KEY_ACTION_DOWN), 0)
|
||||||
@@ -2249,8 +2258,10 @@ import ObjectiveC.runtime
|
|||||||
|
|
||||||
if self.widgetType == WidgetTypeEnum.button && (self.buttonMode == .movable || self.temporarilyMovable) {
|
if self.widgetType == WidgetTypeEnum.button && (self.buttonMode == .movable || self.temporarilyMovable) {
|
||||||
movableButtonReleased = false
|
movableButtonReleased = false
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
if false {
|
||||||
OnScreenWidgetView.updateStreamViewGuidelines(for: self)
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||||
|
OnScreenWidgetView.updateStreamViewGuidelines(for: self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2341,8 +2352,10 @@ import ObjectiveC.runtime
|
|||||||
layoutUpdateDelegate?.updateGuidelinesForOnScreenWidget(self)
|
layoutUpdateDelegate?.updateGuidelinesForOnScreenWidget(self)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if self.widgetType == .button {superview?.bringSubviewToFront(self)}
|
// if self.widgetType == .button {superview?.bringSubviewToFront(self)}
|
||||||
OnScreenWidgetView.updateStreamViewGuidelines(for: self)
|
if false {
|
||||||
|
OnScreenWidgetView.updateStreamViewGuidelines(for: self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2486,7 +2499,10 @@ import ObjectiveC.runtime
|
|||||||
|
|
||||||
if (self.buttonMode == .movable || self.temporarilyMovable) && self.moveableButtonLongPressed() {
|
if (self.buttonMode == .movable || self.temporarilyMovable) && self.moveableButtonLongPressed() {
|
||||||
if let touch = touches.first {
|
if let touch = touches.first {
|
||||||
|
CATransaction.begin()
|
||||||
|
CATransaction.setDisableActions(true)
|
||||||
self.moveByTouch(touch: touch)
|
self.moveByTouch(touch: touch)
|
||||||
|
CATransaction.commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2825,10 +2841,10 @@ import ObjectiveC.runtime
|
|||||||
switch self.motionControlButtonString {
|
switch self.motionControlButtonString {
|
||||||
case "GYRO":
|
case "GYRO":
|
||||||
self.motionHandler?.startMotionControlByOnScreenButton(self, yawFactor: yawFactor, pitchFactor: pitchFactor, rollFactor: rollFactor)
|
self.motionHandler?.startMotionControlByOnScreenButton(self, yawFactor: yawFactor, pitchFactor: pitchFactor, rollFactor: rollFactor)
|
||||||
if !OnScreenWidgetView.gamepadArrivalReported {OnScreenWidgetView.gamepadArrivalReported = oscProfile.mapGyroTo == .mapGyroToControllerStick}
|
if !ControllerUtil.gamepadArrivalReported {ControllerUtil.gamepadArrivalReported = oscProfile.mapGyroTo == .mapGyroToControllerStick}
|
||||||
case "GYROPAUSE":
|
case "GYROPAUSE":
|
||||||
self.motionHandler?.stopMotionUpdate(interruptNoneGyroInput:false)
|
self.motionHandler?.stopMotionUpdate(interruptNoneGyroInput:false)
|
||||||
if !OnScreenWidgetView.gamepadArrivalReported {OnScreenWidgetView.gamepadArrivalReported = oscProfile.mapGyroTo == .mapGyroToControllerStick}
|
if !ControllerUtil.gamepadArrivalReported {ControllerUtil.gamepadArrivalReported = oscProfile.mapGyroTo == .mapGyroToControllerStick}
|
||||||
break
|
break
|
||||||
case "ACCEL":
|
case "ACCEL":
|
||||||
break
|
break
|
||||||
@@ -2888,9 +2904,6 @@ import ObjectiveC.runtime
|
|||||||
case "PENCILHOVER":
|
case "PENCILHOVER":
|
||||||
if !self.isPencilProEnabled() {break}
|
if !self.isPencilProEnabled() {break}
|
||||||
self.functionalWidgetDelegate?.enablePencilHover()
|
self.functionalWidgetDelegate?.enablePencilHover()
|
||||||
case "NOSINGLETOUCH":
|
|
||||||
if !self.isPencilProEnabled() {break}
|
|
||||||
self.functionalWidgetDelegate?.setAllowSingleTouchEnabled(false)
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -2898,29 +2911,24 @@ import ObjectiveC.runtime
|
|||||||
|
|
||||||
private var movableButtonReleased:Bool = true
|
private var movableButtonReleased:Bool = true
|
||||||
private func moveableButtonLongPressed() -> Bool{
|
private func moveableButtonLongPressed() -> Bool{
|
||||||
return !movableButtonReleased && CACurrentMediaTime() - self.touchTapTimeStamp > 0.3
|
return !movableButtonReleased && CACurrentMediaTime() - self.touchTapTimeStamp > 0.05
|
||||||
}
|
}
|
||||||
|
|
||||||
private var singleTouchEnabled:Bool = true
|
|
||||||
|
|
||||||
private func handleFunctionalButtonUp(event: UIEvent? = nil){
|
private func handleFunctionalButtonUp(event: UIEvent? = nil){
|
||||||
// print("handleFunctionalButtonUp \(self.widgetLabel), event Empty: \(String(describing: event)), \(CACurrentMediaTime())")
|
// print("handleFunctionalButtonUp \(self.widgetLabel), event Empty: \(String(describing: event)), \(CACurrentMediaTime())")
|
||||||
if autoDockIsDocked {return}
|
if autoDockIsDocked {return}
|
||||||
|
if firstTouchMoved {return}
|
||||||
|
/*
|
||||||
if buttonMode == .movable {
|
if buttonMode == .movable {
|
||||||
if moveableButtonLongPressed() && !UITouchUtil.touches(in: self, from: event).isEmpty {return}
|
if moveableButtonLongPressed() && !UITouchUtil.touches(in: self, from: event).isEmpty {return}
|
||||||
switch self.functionalButtonString {
|
switch self.functionalButtonString {
|
||||||
// case "FOLDER":
|
// case "FOLDER":
|
||||||
// self.folded = !self.folded
|
// self.folded = !self.folded
|
||||||
// OnScreenWidgetView.set(folded: self.folded, for: self)
|
// OnScreenWidgetView.set(folded: self.folded, for: self)
|
||||||
case "NOSINGLETOUCH":
|
|
||||||
if !self.isPencilProEnabled() {break}
|
|
||||||
singleTouchEnabled = !singleTouchEnabled
|
|
||||||
self.functionalWidgetDelegate?.setAllowSingleTouchEnabled(singleTouchEnabled)
|
|
||||||
return
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
switch self.functionalButtonString {
|
switch self.functionalButtonString {
|
||||||
case "FOLDER":
|
case "FOLDER":
|
||||||
@@ -2962,16 +2970,28 @@ import ObjectiveC.runtime
|
|||||||
self.functionalWidgetDelegate?.bringUpSoftKeyboard()
|
self.functionalWidgetDelegate?.bringUpSoftKeyboard()
|
||||||
case "ABSTCHDRAG":
|
case "ABSTCHDRAG":
|
||||||
self.functionalWidgetDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
|
self.functionalWidgetDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
|
||||||
case "DISABLETOUCH":
|
|
||||||
self.handleTouchDisableButtonUp()
|
|
||||||
case "GAMEPADOVERLAY":
|
case "GAMEPADOVERLAY":
|
||||||
self.gamepadOverlayButtonUp()
|
self.gamepadOverlayButtonUp()
|
||||||
case "PENCILHOVER":
|
case "PENCILHOVER":
|
||||||
if !self.isPencilProEnabled() {break}
|
if !self.isPencilProEnabled() {break}
|
||||||
self.functionalWidgetDelegate?.disablePencilHover()
|
self.functionalWidgetDelegate?.disablePencilHover()
|
||||||
|
|
||||||
|
case "DISABLETOUCH":
|
||||||
|
if let streamFrameVC = StreamFrameViewController.sharedInstance() {
|
||||||
|
streamFrameVC.touchDisabled = !streamFrameVC.touchDisabled
|
||||||
|
self.functionalWidgetDelegate?.handleTouchDisableButtonUp()
|
||||||
|
}
|
||||||
case "NOSINGLETOUCH":
|
case "NOSINGLETOUCH":
|
||||||
if !self.isPencilProEnabled() {break}
|
if !self.isPencilProEnabled() {break}
|
||||||
self.functionalWidgetDelegate?.setAllowSingleTouchEnabled(true)
|
if let streamFrameVC = StreamFrameViewController.sharedInstance() {
|
||||||
|
streamFrameVC.singleTouchDisabled = !streamFrameVC.singleTouchDisabled
|
||||||
|
self.functionalWidgetDelegate?.handleDisableSingleTouchButtonUp()
|
||||||
|
}
|
||||||
|
case "DISABLETILT":
|
||||||
|
if !self.isPencilProEnabled() {break}
|
||||||
|
if let pencilHandler = PencilHandler.shared {
|
||||||
|
pencilHandler.disableTilt = !pencilHandler.disableTilt
|
||||||
|
}
|
||||||
case "BRUSH":
|
case "BRUSH":
|
||||||
if !self.isPencilProEnabled() {break}
|
if !self.isPencilProEnabled() {break}
|
||||||
var brushShortcut = self.cmdString.replacingOccurrences(of: "BRUSH+", with: "")
|
var brushShortcut = self.cmdString.replacingOccurrences(of: "BRUSH+", with: "")
|
||||||
@@ -2982,12 +3002,6 @@ import ObjectiveC.runtime
|
|||||||
var eraserShortcut = self.cmdString.replacingOccurrences(of: "ERASER+", with: "")
|
var eraserShortcut = self.cmdString.replacingOccurrences(of: "ERASER+", with: "")
|
||||||
eraserShortcut = eraserShortcut.replacingOccurrences(of: "ERASER", with: "")
|
eraserShortcut = eraserShortcut.replacingOccurrences(of: "ERASER", with: "")
|
||||||
self.functionalWidgetDelegate?.replaceEraser(shortcut: eraserShortcut)
|
self.functionalWidgetDelegate?.replaceEraser(shortcut: eraserShortcut)
|
||||||
case "DISABLETILT":
|
|
||||||
if !self.isPencilProEnabled() {break}
|
|
||||||
if let pencilHandler = PencilHandler.shared {
|
|
||||||
pencilHandler.disableTilt = !pencilHandler.disableTilt
|
|
||||||
self.setupAtrributedText()
|
|
||||||
}
|
|
||||||
case "PRESSURECURVE":
|
case "PRESSURECURVE":
|
||||||
if ["com.voidlink.iOS"
|
if ["com.voidlink.iOS"
|
||||||
, "com.voidlinkextreme.iOS"
|
, "com.voidlinkextreme.iOS"
|
||||||
@@ -2998,15 +3012,12 @@ import ObjectiveC.runtime
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.hasNonEditableLabel {
|
||||||
|
self.setupAtrributedText()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var touchDisabledFLag:Bool = false
|
|
||||||
private func handleTouchDisableButtonUp(){
|
|
||||||
touchDisabledFLag = !touchDisabledFLag
|
|
||||||
self.setupAtrributedText()
|
|
||||||
self.functionalWidgetDelegate?.toggleTouch(disabled: touchDisabledFLag)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc static var gamepadOverlayFLag:Bool = false
|
@objc static var gamepadOverlayFLag:Bool = false
|
||||||
private func gamepadOverlayButtonUp(){
|
private func gamepadOverlayButtonUp(){
|
||||||
self.relocatedDuringStreaming = true
|
self.relocatedDuringStreaming = true
|
||||||
@@ -3806,10 +3817,20 @@ import ObjectiveC.runtime
|
|||||||
@objc static var enableFolderAnimation:Bool = true
|
@objc static var enableFolderAnimation:Bool = true
|
||||||
private static func setCollection(folded:Bool, for folder:OnScreenWidgetView, exception:OnScreenWidgetView? = nil, recursive:Bool = false, isExclusiveFolderAction:Bool = false) {
|
private static func setCollection(folded:Bool, for folder:OnScreenWidgetView, exception:OnScreenWidgetView? = nil, recursive:Bool = false, isExclusiveFolderAction:Bool = false) {
|
||||||
guard folder.isFolder else {return}
|
guard folder.isFolder else {return}
|
||||||
|
|
||||||
|
if !OnScreenWidgetView.enableFolderAnimation, folder.parentSequence == -1 {
|
||||||
|
folder.buttonDownVisualEffect()
|
||||||
|
folder.buttonDownVisualEffectLayer.isHidden = false
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
|
||||||
|
folder.buttonDownVisualEffectLayer.isHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// guard folder.folded != hidden else { return }
|
// guard folder.folded != hidden else { return }
|
||||||
folder.folded = folded
|
folder.folded = folded
|
||||||
folder.setupAtrributedText()
|
folder.setupAtrributedText()
|
||||||
folder.reverseColorPhase(reversed: !folder.folded)
|
folder.reverseColorPhase(reversed: !folder.folded)
|
||||||
|
|
||||||
if folded {
|
if folded {
|
||||||
for sequence in folder.sequenceSet {
|
for sequence in folder.sequenceSet {
|
||||||
guard let widget = OnScreenWidgetView.mapping[sequence], widget != exception else {continue}
|
guard let widget = OnScreenWidgetView.mapping[sequence], widget != exception else {continue}
|
||||||
@@ -3897,8 +3918,16 @@ import ObjectiveC.runtime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc static func disableFolderAnimation(for duration: TimeInterval){
|
||||||
|
enableFolderAnimation = false
|
||||||
|
DispatchQueue.global().asyncAfter(deadline: .now() + duration) {
|
||||||
|
enableFolderAnimation = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc static func set(folded:Bool, for folder:OnScreenWidgetView) { // folder综合逻辑
|
@objc static func set(folded:Bool, for folder:OnScreenWidgetView) { // folder综合逻辑
|
||||||
guard folder.isFolder else {return}
|
guard folder.isFolder else {return}
|
||||||
|
|
||||||
if !folded {
|
if !folded {
|
||||||
OnScreenWidgetView.deepestButton = OnScreenWidgetView.getDeepestButton()
|
OnScreenWidgetView.deepestButton = OnScreenWidgetView.getDeepestButton()
|
||||||
}
|
}
|
||||||
@@ -4129,7 +4158,6 @@ import ObjectiveC.runtime
|
|||||||
return OnScreenWidgetView.mapping.keys.max() ?? -1
|
return OnScreenWidgetView.mapping.keys.max() ?? -1
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc static var gamepadArrivalReported: Bool = false
|
|
||||||
override func didMoveToSuperview() {
|
override func didMoveToSuperview() {
|
||||||
super.didMoveToSuperview()
|
super.didMoveToSuperview()
|
||||||
OnScreenWidgetView.installAutoDockIfNeeded()
|
OnScreenWidgetView.installAutoDockIfNeeded()
|
||||||
@@ -4141,14 +4169,14 @@ import ObjectiveC.runtime
|
|||||||
label.alpha = 1
|
label.alpha = 1
|
||||||
autoDockRestoreOriginalAlpha()
|
autoDockRestoreOriginalAlpha()
|
||||||
if self.motionControlButtonString == "GYRO" {
|
if self.motionControlButtonString == "GYRO" {
|
||||||
if OnScreenWidgetView.gamepadArrivalReported {self.motionHandler?.stopMotionUpdate(interruptNoneGyroInput: true)}
|
if ControllerUtil.gamepadArrivalReported {self.motionHandler?.stopMotionUpdate(interruptNoneGyroInput: true)}
|
||||||
self.motionHandler?.motionStarter = nil
|
self.motionHandler?.motionStarter = nil
|
||||||
}
|
}
|
||||||
if self.motionControlButtonString == "ACCEL" {}
|
if self.motionControlButtonString == "ACCEL" {}
|
||||||
if self.motionControlButtonString == "MOTION" {}
|
if self.motionControlButtonString == "MOTION" {}
|
||||||
|
|
||||||
if self.widgetType == WidgetTypeEnum.button && !OnScreenWidgetView.editMode {
|
if self.widgetType == WidgetTypeEnum.button && !OnScreenWidgetView.editMode {
|
||||||
if OnScreenWidgetView.gamepadArrivalReported {self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings)}
|
if ControllerUtil.gamepadArrivalReported {self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings)}
|
||||||
self.functionalWidgetDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
|
self.functionalWidgetDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT)
|
||||||
}
|
}
|
||||||
buttonDownVisualEffectLayer.removeFromSuperlayer()
|
buttonDownVisualEffectLayer.removeFromSuperlayer()
|
||||||
@@ -4167,7 +4195,7 @@ import ObjectiveC.runtime
|
|||||||
stickWheelLayer.removeFromSuperlayer()
|
stickWheelLayer.removeFromSuperlayer()
|
||||||
stickWheelLayerSmall.removeFromSuperlayer()
|
stickWheelLayerSmall.removeFromSuperlayer()
|
||||||
self.inertialScroller.timer?.clean()
|
self.inertialScroller.timer?.clean()
|
||||||
if OnScreenWidgetView.gamepadArrivalReported {
|
if ControllerUtil.gamepadArrivalReported {
|
||||||
self.clearLeftStickTouchPadFlag()
|
self.clearLeftStickTouchPadFlag()
|
||||||
self.clearRightStickTouchPadFlag()
|
self.clearRightStickTouchPadFlag()
|
||||||
}
|
}
|
||||||
@@ -4255,7 +4283,7 @@ import ObjectiveC.runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
print("onScreenWidgetView deinit \(self.widgetLabel))")
|
// print("onScreenWidgetView deinit \(self.widgetLabel))")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import UIKit
|
|||||||
private var manualHoverFlag: Bool = false
|
private var manualHoverFlag: Bool = false
|
||||||
@objc static var hoverSupported: Bool = false
|
@objc static var hoverSupported: Bool = false
|
||||||
// @objc static private(set) var autoHoverTermination: Bool = false
|
// @objc static private(set) var autoHoverTermination: Bool = false
|
||||||
@objc static private(set) var hoverMode: PencilHoverMode = .HoverPencil
|
@objc static private(set) var pencilAndHoverMode: PencilAndHoverMode = .pencilOnly
|
||||||
private(set) var pencilProEnabled: Bool = false
|
private(set) var pencilProEnabled: Bool = false
|
||||||
private var isFirstMove: Bool = false
|
private var isFirstMove: Bool = false
|
||||||
private var strokeSampleIndex: Int32 = 0
|
private var strokeSampleIndex: Int32 = 0
|
||||||
@@ -105,7 +105,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PencilHandler.autoHoverTermination = selectedProfile.autoPencilHoverTermination
|
// PencilHandler.autoHoverTermination = selectedProfile.autoPencilHoverTermination
|
||||||
PencilHandler.hoverMode = selectedProfile.pencilHoverMode
|
PencilHandler.pencilAndHoverMode = selectedProfile.pencilAndHoverMode
|
||||||
|
|
||||||
pressureCurveEnabled = selectedProfile.pressureCurveEnabled
|
pressureCurveEnabled = selectedProfile.pressureCurveEnabled
|
||||||
|
|
||||||
@@ -151,6 +151,12 @@ import UIKit
|
|||||||
PencilHandler.isDrawing = true
|
PencilHandler.isDrawing = true
|
||||||
// isFirstMove = true
|
// isFirstMove = true
|
||||||
strokeSampleIndex = 0
|
strokeSampleIndex = 0
|
||||||
|
|
||||||
|
guard PencilHandler.pencilAndHoverMode == .pencilOnly || PencilHandler.pencilAndHoverMode == .hoverDisabled else {
|
||||||
|
handleNonPencilModes(touches)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for touch in touches {
|
for touch in touches {
|
||||||
let coalesced = event.coalescedTouches(for: touch) ?? []
|
let coalesced = event.coalescedTouches(for: touch) ?? []
|
||||||
_ = self.sendStylusEvent(touchBatch: pencilTickEnabled ? coalesced : [touch])
|
_ = self.sendStylusEvent(touchBatch: pencilTickEnabled ? coalesced : [touch])
|
||||||
@@ -159,6 +165,12 @@ import UIKit
|
|||||||
|
|
||||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
guard let event = event else { return }
|
guard let event = event else { return }
|
||||||
|
|
||||||
|
guard PencilHandler.pencilAndHoverMode == .pencilOnly || PencilHandler.pencilAndHoverMode == .hoverDisabled else {
|
||||||
|
handleNonPencilModes(touches)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for touch in touches {
|
for touch in touches {
|
||||||
let coalesced = event.coalescedTouches(for: touch) ?? []
|
let coalesced = event.coalescedTouches(for: touch) ?? []
|
||||||
_ = self.sendStylusEvent(touchBatch: pencilTickEnabled ? coalesced : [touch])
|
_ = self.sendStylusEvent(touchBatch: pencilTickEnabled ? coalesced : [touch])
|
||||||
@@ -167,6 +179,12 @@ import UIKit
|
|||||||
|
|
||||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
guard let event = event else { return }
|
guard let event = event else { return }
|
||||||
|
|
||||||
|
guard PencilHandler.pencilAndHoverMode == .pencilOnly || PencilHandler.pencilAndHoverMode == .hoverDisabled else {
|
||||||
|
handleNonPencilModes(touches)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for touch in touches {
|
for touch in touches {
|
||||||
let coalesced = event.coalescedTouches(for: touch) ?? []
|
let coalesced = event.coalescedTouches(for: touch) ?? []
|
||||||
_ = self.sendStylusEvent(touchBatch: pencilTickEnabled ? coalesced : [touch])
|
_ = self.sendStylusEvent(touchBatch: pencilTickEnabled ? coalesced : [touch])
|
||||||
@@ -176,6 +194,34 @@ import UIKit
|
|||||||
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
self.touchesEnded(touches, with: event)
|
self.touchesEnded(touches, with: event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func handleNonPencilModes(_ touches: Set<UITouch>) {
|
||||||
|
guard let touch = touches.first else { return }
|
||||||
|
let location = touch.location(in: streamView)
|
||||||
|
let normalizedLocation = self.getNormalizedLocation(point: location)
|
||||||
|
if let streamView = streamView as? StreamView {
|
||||||
|
switch touch.phase {
|
||||||
|
case .began where PencilHandler.pencilAndHoverMode == .pencilToMouse:
|
||||||
|
streamView.updateCursorLocation(location, isMouse: false)
|
||||||
|
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), BUTTON_LEFT)
|
||||||
|
case .began where PencilHandler.pencilAndHoverMode == .pencilToTouch:
|
||||||
|
LiSendTouchEvent(UInt8(LI_TOUCH_EVENT_DOWN), 666666, Float(normalizedLocation.x), Float(normalizedLocation.y), Float((touch.force/touch.maximumPossibleForce)/sin(touch.altitudeAngle)), 0, 0, getRotation(fromAzimuthAngle: Float(touch.azimuthAngle(in: streamView))))
|
||||||
|
case .moved where PencilHandler.pencilAndHoverMode == .pencilToMouse:
|
||||||
|
streamView.updateCursorLocation(location, isMouse: false)
|
||||||
|
case .moved where PencilHandler.pencilAndHoverMode == .pencilToTouch:
|
||||||
|
LiSendTouchEvent(UInt8(LI_TOUCH_EVENT_MOVE), 666666, Float(normalizedLocation.x), Float(normalizedLocation.y), Float((touch.force/touch.maximumPossibleForce)/sin(touch.altitudeAngle)), 0, 0, getRotation(fromAzimuthAngle: Float(touch.azimuthAngle(in: streamView))))
|
||||||
|
case .ended where PencilHandler.pencilAndHoverMode == .pencilToMouse,
|
||||||
|
.cancelled where PencilHandler.pencilAndHoverMode == .pencilToMouse:
|
||||||
|
streamView.updateCursorLocation(location, isMouse: false)
|
||||||
|
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_LEFT)
|
||||||
|
case .ended where PencilHandler.pencilAndHoverMode == .pencilToTouch,
|
||||||
|
.cancelled where PencilHandler.pencilAndHoverMode == .pencilToTouch:
|
||||||
|
LiSendTouchEvent(UInt8(LI_TOUCH_EVENT_UP), 666666, Float(normalizedLocation.x), Float(normalizedLocation.y), 0, 0, 0, 0)
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Core Logic
|
// MARK: - Core Logic
|
||||||
|
|
||||||
@@ -229,7 +275,15 @@ import UIKit
|
|||||||
|
|
||||||
func getTilt(fromAltitudeAngle altitudeAngle: Float) -> UInt8 {
|
func getTilt(fromAltitudeAngle altitudeAngle: Float) -> UInt8 {
|
||||||
let altitudeDegs = abs(Int16(altitudeAngle * (180.0 / .pi)))
|
let altitudeDegs = abs(Int16(altitudeAngle * (180.0 / .pi)))
|
||||||
return disableTilt ? 0 : UInt8(90 - min(90, Int(altitudeDegs)))
|
let tilt = disableTilt ? 0 : UInt8(90 - min(90, Int(altitudeDegs)))
|
||||||
|
return tilt
|
||||||
|
}
|
||||||
|
|
||||||
|
private func getNormalizedLocation(point: CGPoint) -> CGPoint {
|
||||||
|
let location = self.adjustCoordinatesForVideoArea(point: point)
|
||||||
|
let videoSize = self.getVideoAreaSize()
|
||||||
|
let normalizedLocation = CGPoint(x: location.x/videoSize.width, y: location.y/videoSize.height)
|
||||||
|
return normalizedLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
var previousForce: Float = 0
|
var previousForce: Float = 0
|
||||||
@@ -250,9 +304,7 @@ import UIKit
|
|||||||
.applying(CGAffineTransform(translationX: pencilTipOffset.x, y: pencilTipOffset.y))
|
.applying(CGAffineTransform(translationX: pencilTipOffset.x, y: pencilTipOffset.y))
|
||||||
let azimuth = touch.azimuthAngle(in: streamView)
|
let azimuth = touch.azimuthAngle(in: streamView)
|
||||||
let altitude = touch.altitudeAngle
|
let altitude = touch.altitudeAngle
|
||||||
let location = self.adjustCoordinatesForVideoArea(point: point)
|
let normalizedLocation = self.getNormalizedLocation(point: point)
|
||||||
let videoSize = self.getVideoAreaSize()
|
|
||||||
let normalizedLocation = CGPoint(x: location.x/videoSize.width, y: location.y/videoSize.height)
|
|
||||||
var force = Float(touch.force/touch.maximumPossibleForce)/sin(Float(altitude))
|
var force = Float(touch.force/touch.maximumPossibleForce)/sin(Float(altitude))
|
||||||
force = (self.pencilTickEnabled && force == 0) ? previousForce : force
|
force = (self.pencilTickEnabled && force == 0) ? previousForce : force
|
||||||
|
|
||||||
@@ -332,7 +384,7 @@ import UIKit
|
|||||||
|
|
||||||
if eventType == UInt8(LI_TOUCH_EVENT_UP) {
|
if eventType == UInt8(LI_TOUCH_EVENT_UP) {
|
||||||
PencilHandler.isDrawing = false
|
PencilHandler.isDrawing = false
|
||||||
if PencilHandler.hoverMode == .HoverDisabled || !PencilHandler.hoverSupported {
|
if PencilHandler.pencilAndHoverMode == .hoverDisabled || !PencilHandler.hoverSupported {
|
||||||
LiSendPenEvent(UInt8(LI_TOUCH_EVENT_HOVER), UInt8(LI_TOOL_TYPE_PEN), 0, Float(normalizedLocation.x), Float(normalizedLocation.y), 0, 0, 0, self.getRotation(fromAzimuthAngle: Float(azimuth)), self.getTilt(fromAltitudeAngle: Float(altitude)))
|
LiSendPenEvent(UInt8(LI_TOUCH_EVENT_HOVER), UInt8(LI_TOOL_TYPE_PEN), 0, Float(normalizedLocation.x), Float(normalizedLocation.y), 0, 0, 0, self.getRotation(fromAzimuthAngle: Float(azimuth)), self.getTilt(fromAltitudeAngle: Float(altitude)))
|
||||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.0086){
|
DispatchQueue.global().asyncAfter(deadline: .now() + 0.0086){
|
||||||
if !PencilHandler.isDrawing {
|
if !PencilHandler.isDrawing {
|
||||||
|
|||||||
+24
-13
@@ -73,7 +73,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
|
|
||||||
NSTimer* interactionTimer;
|
NSTimer* interactionTimer;
|
||||||
BOOL hasUserInteracted;
|
BOOL hasUserInteracted;
|
||||||
|
|
||||||
NSDictionary<NSString *, NSNumber *> *dictCodes;
|
NSDictionary<NSString *, NSNumber *> *dictCodes;
|
||||||
CustomTapGestureRecognizer *keyboardToggleRecognizer;
|
CustomTapGestureRecognizer *keyboardToggleRecognizer;
|
||||||
UIPanGestureRecognizer *discreteMouseWheelRecognizer;
|
UIPanGestureRecognizer *discreteMouseWheelRecognizer;
|
||||||
@@ -236,6 +236,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
case NativeTouch:
|
case NativeTouch:
|
||||||
keyboardToggleRecognizer.immediateTriggering = false;
|
keyboardToggleRecognizer.immediateTriggering = false;
|
||||||
self->touchHandler = [[NativeTouchHandler alloc] initWithView:self settings:settings profile:profile];
|
self->touchHandler = [[NativeTouchHandler alloc] initWithView:self settings:settings profile:profile];
|
||||||
|
[(NativeTouchHandler* )touchHandler setAllowSingleTouchEnabled:!_streamFrameVC.singleTouchDisabled];
|
||||||
break;
|
break;
|
||||||
case NativeTouchOnly:
|
case NativeTouchOnly:
|
||||||
keyboardToggleRecognizer.immediateTriggering = false;
|
keyboardToggleRecognizer.immediateTriggering = false;
|
||||||
@@ -254,11 +255,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
self->touchHandler = nil;
|
self->touchHandler = nil;
|
||||||
keyboardToggleRecognizer.immediateTriggering = false;
|
keyboardToggleRecognizer.immediateTriggering = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sessionTouchHandler = touchHandler;
|
sessionTouchHandler = touchHandler;
|
||||||
|
if(_streamFrameVC.touchDisabled) touchHandler = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshKeyboardToggleRecognizer:(uint8_t)numberOfTouches{
|
- (void)refreshKeyboardToggleRecognizer:(uint8_t)numberOfTouches{
|
||||||
@@ -619,7 +620,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
||||||
if(position.x < 1.0 && position.y < 1.0){
|
if(position.x < 2.01 && position.y < 2.01){
|
||||||
position.x = position.x * _streamFrameTopLayerView.bounds.size.width;
|
position.x = position.x * _streamFrameTopLayerView.bounds.size.width;
|
||||||
position.y = position.y * _streamFrameTopLayerView.bounds.size.height;
|
position.y = position.y * _streamFrameTopLayerView.bounds.size.height;
|
||||||
}
|
}
|
||||||
@@ -691,10 +692,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
self->oscProfileMan = [OSCProfilesManager sharedManager:self->_streamFrameTopLayerView.bounds];
|
self->oscProfileMan = [OSCProfilesManager sharedManager:self->_streamFrameTopLayerView.bounds];
|
||||||
|
|
||||||
if(!profile){
|
if(!profile){
|
||||||
NSLog(@"reloadOnScreenWidgets in streamview %d", reloadWidgets);
|
|
||||||
profile = [self->oscProfileMan getSelectedProfile]; //returns the currently selected OSCProfile
|
profile = [self->oscProfileMan getSelectedProfile]; //returns the currently selected OSCProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSLog(@"reloadOnScreenWidgets in streamview %d", reloadWidgets);
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
MotionHandler* motionHandler = [MotionHandler sharedWithProfile:profile];
|
MotionHandler* motionHandler = [MotionHandler sharedWithProfile:profile];
|
||||||
|
|
||||||
@@ -718,6 +720,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
// remove all keyboard widget views first
|
// remove all keyboard widget views first
|
||||||
[self clearOnScreenWidgets];
|
[self clearOnScreenWidgets];
|
||||||
|
|
||||||
|
self->_streamFrameVC.touchDisabled = false;
|
||||||
|
self->_streamFrameVC.singleTouchDisabled = false;
|
||||||
|
PencilHandler* pencilHandler = [PencilHandler shared];
|
||||||
|
if(pencilHandler) pencilHandler.disableTilt = false;
|
||||||
|
|
||||||
bool sequenceGenerated = false;
|
bool sequenceGenerated = false;
|
||||||
bool hasMovableWidget = false;
|
bool hasMovableWidget = false;
|
||||||
|
|
||||||
@@ -767,6 +774,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
widgetView.minStickOffset = buttonState.minStickOffset;
|
widgetView.minStickOffset = buttonState.minStickOffset;
|
||||||
widgetView.dWheelWalkModeThreshold = buttonState.walkModeThreshold;
|
widgetView.dWheelWalkModeThreshold = buttonState.walkModeThreshold;
|
||||||
widgetView.buttonMode = buttonState.buttonMode;
|
widgetView.buttonMode = buttonState.buttonMode;
|
||||||
|
if([widgetView.cmdString isEqualToString:@"NOSINGLETOUCH"]) widgetView.buttonMode = movable;
|
||||||
widgetView.sprintKeyActionType = buttonState.sprintKeyActionType;
|
widgetView.sprintKeyActionType = buttonState.sprintKeyActionType;
|
||||||
widgetView.sprintKeyThreshold = buttonState.sprintKeyThreshold;
|
widgetView.sprintKeyThreshold = buttonState.sprintKeyThreshold;
|
||||||
widgetView.walkKeyActionType = buttonState.walkKeyActionType;
|
widgetView.walkKeyActionType = buttonState.walkKeyActionType;
|
||||||
@@ -999,7 +1007,9 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPoint location = [self adjustCoordinatesForVideoArea:[gesture locationInView:self]];
|
CGPoint originalLocation = [gesture locationInView:self];
|
||||||
|
CGPoint location = [self adjustCoordinatesForVideoArea:originalLocation];
|
||||||
|
NSLog(@" location %f, %f", location.x, location.y);
|
||||||
PencilHandler* handler = PencilHandler.shared;
|
PencilHandler* handler = PencilHandler.shared;
|
||||||
location = CGPointApplyAffineTransform(location, CGAffineTransformMakeTranslation(handler.pencilTipOffset.x, handler.pencilTipOffset.y));
|
location = CGPointApplyAffineTransform(location, CGAffineTransformMakeTranslation(handler.pencilTipOffset.x, handler.pencilTipOffset.y));
|
||||||
|
|
||||||
@@ -1023,19 +1033,20 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
|
|
||||||
|
|
||||||
dispatch_after(0, dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE,0), ^{// Code to execute after the delay
|
dispatch_after(0, dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE,0), ^{// Code to execute after the delay
|
||||||
if(PencilHandler.isDrawing) return;
|
if(PencilHandler.isDrawing && PencilHandler.pencilAndHoverMode == pencilOnly && PencilHandler.pencilAndHoverMode == hoverDisabled) return;
|
||||||
switch (PencilHandler.hoverMode) {
|
switch (PencilHandler.pencilAndHoverMode) {
|
||||||
case HoverPencil:
|
case pencilOnly:
|
||||||
LiSendPenEvent(type, LI_TOOL_TYPE_PEN, 0, location.x / videoSize.width, location.y / videoSize.height, distance, 0.0f, 0.0f, rotationAngle, tiltAngle);
|
LiSendPenEvent(type, LI_TOOL_TYPE_PEN, 0, location.x / videoSize.width, location.y / videoSize.height, distance, 0.0f, 0.0f, rotationAngle, tiltAngle);
|
||||||
break;
|
break;
|
||||||
case HoverMouse:
|
case pencilToMouse:
|
||||||
[self updateCursorLocation:location isMouse:YES];
|
if(gesture.state != UIGestureRecognizerStateEnded) [self updateCursorLocation:originalLocation isMouse:NO];
|
||||||
break;
|
break;
|
||||||
case HoverDisabled:
|
case hoverDisabled:
|
||||||
break;
|
break;
|
||||||
case HoverBoth:
|
case pencilToTouch:
|
||||||
|
/*
|
||||||
LiSendPenEvent(type, LI_TOOL_TYPE_PEN, 0, location.x / videoSize.width, location.y / videoSize.height, distance, 0.0f, 0.0f, rotationAngle, tiltAngle);
|
LiSendPenEvent(type, LI_TOOL_TYPE_PEN, 0, location.x / videoSize.width, location.y / videoSize.height, distance, 0.0f, 0.0f, rotationAngle, tiltAngle);
|
||||||
[self updateCursorLocation:location isMouse:YES];
|
[self updateCursorLocation:location isMouse:YES]; */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1121,6 +1121,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"=DisableSingleTouch" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "🚫 SingleTouch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "🚫 单指触摸"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "🚫 單指觸摸"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "🚫 單指觸摸"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"=disableTilt" : {
|
"=disableTilt" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -1295,6 +1324,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"=EnableSingleTouch" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "🟢 SingleTouch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "🟢 单指触摸"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "🟢 單指觸摸"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "🟢 單指觸摸"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"=enableTilt" : {
|
"=enableTilt" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2455,35 +2513,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"=noSingleTouch" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "🚫SingleTouch"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "🚫单指触摸"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "needs_review",
|
|
||||||
"value" : "🚫單指觸摸"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "needs_review",
|
|
||||||
"value" : "🚫單指觸摸"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"=null" : {
|
"=null" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -10149,35 +10178,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hoverModeStackTip" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "When “both” is selected, you’ll get flickering cursor on host.\nThis function is available without purchasing [Drawing Toolkit]."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "当选择“同时悬停”时,PC端的光标将会闪烁。\n此功能是Pencil基础功能的一部分,不属于Drawing Toolkit。 "
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "當選擇「同時懸停」時,PC 端的游標將會閃爍。\n此功能為 Pencil 基礎功能的一部分,不屬於 Drawing Toolkit。"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "當選擇「同時懸停」時,PC 端的游標將會閃爍。\n此功能為 Pencil 基礎功能的一部分,不屬於 Drawing Toolkit。"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"I'm an artist" : {
|
"I'm an artist" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -13303,6 +13303,52 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Pencil hover" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Pencil 悬停"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Pencil 懸浮"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Pencil 懸浮"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Pencil Pro Pack" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Pencil 专业套装"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Pencil 專業套裝"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Pencil 專業套裝"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Pencil Tip Offset" : {
|
"Pencil Tip Offset" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -13361,52 +13407,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Pencil hover" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Pencil 悬停"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Pencil 懸浮"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Pencil 懸浮"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Pencil Pro Pack" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Pencil 专业套装"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Pencil 專業套裝"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Pencil 專業套裝"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pencilKeyboardCmdURL" : {
|
"pencilKeyboardCmdURL" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -13436,6 +13436,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pencilModeStackTip" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "This function is available without purchasing [Drawing Toolkit]."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "此功能是Pencil基础功能的一部分,不属于Drawing Toolkit。 "
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "此功能為 Pencil 基礎功能的一部分,不屬於 Drawing Toolkit。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "此功能為 Pencil 基礎功能的一部分,不屬於 Drawing Toolkit。"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"PencilProPackDescription" : {
|
"PencilProPackDescription" : {
|
||||||
"extractionState" : "manual"
|
"extractionState" : "manual"
|
||||||
},
|
},
|
||||||
@@ -19123,6 +19152,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"X Offset" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "X Offset"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "X 偏移"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "X 偏移"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "X 偏移"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"X1" : {
|
"X1" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -19169,58 +19227,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"X Offset" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "X Offset"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "X 偏移"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "X 偏移"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "X 偏移"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Yaw factor: %.2f" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "偏航系数: %.2f"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "偏航係數: %.2f"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "偏航係數: %.2f"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Y Offset" : {
|
"Y Offset" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -19250,6 +19256,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Yaw factor: %.2f" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "偏航系数: %.2f"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "偏航係數: %.2f"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "偏航係數: %.2f"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Yes" : {
|
"Yes" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -19359,4 +19388,4 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "1.1"
|
"version" : "1.1"
|
||||||
}
|
}
|
||||||
+38
-20
@@ -306,6 +306,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
selectedWidget = nil
|
selectedWidget = nil
|
||||||
widgetPanelStoredCenter = widgetPanelStack.center
|
widgetPanelStoredCenter = widgetPanelStack.center
|
||||||
setupWidgetPanel()
|
setupWidgetPanel()
|
||||||
|
// print("loadingMode \(profileSelectorLoadingMode)")
|
||||||
profileRefresh()
|
profileRefresh()
|
||||||
if !toolbarStackView.isHidden {
|
if !toolbarStackView.isHidden {
|
||||||
GenericUtils.handleLayoutToolTip(in: self)
|
GenericUtils.handleLayoutToolTip(in: self)
|
||||||
@@ -330,7 +331,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
@objc func dummytest() {}
|
@objc func dummytest() {}
|
||||||
|
|
||||||
private func denormalizeWidgetPosition(_ position: CGPoint) -> CGPoint {
|
private func denormalizeWidgetPosition(_ position: CGPoint) -> CGPoint {
|
||||||
guard position.x < 1.0, position.y < 1.0 else { return position }
|
guard abs(position.x) < 2.01, abs(position.y) < 2.01 else { return position }
|
||||||
return CGPoint(x: position.x * view.bounds.width, y: position.y * view.bounds.height)
|
return CGPoint(x: position.x * view.bounds.width, y: position.y * view.bounds.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,8 +359,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc func reloadOnScreenWidgetViews() {
|
@objc func reloadOnScreenWidgetViews() {
|
||||||
if self.profileSelectorLoadingMode == .selectProfileFromMainFrame { return }
|
|
||||||
|
// if self.profileSelectorLoadingMode == .selectProfileFromMainFrame { return }
|
||||||
|
guard self.profileSelectorLoadingMode == .selectProfileFromLayoutTool || self.profileSelectorLoadingMode == .selectProfileFromStreamView else { return }
|
||||||
|
|
||||||
OnScreenWidgetView.isTweakingHighlight = false
|
OnScreenWidgetView.isTweakingHighlight = false
|
||||||
OnScreenWidgetView.editMode = true
|
OnScreenWidgetView.editMode = true
|
||||||
|
|
||||||
@@ -367,7 +370,20 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
self.hideStickIndicators()
|
self.hideStickIndicators()
|
||||||
self.clearOnScreenWidgets()
|
self.clearOnScreenWidgets()
|
||||||
|
|
||||||
guard let oscProfile = self.profilesManager?.getSelectedProfile() else { return }
|
var oscProfile: OSCProfile?
|
||||||
|
|
||||||
|
if let profileSelector = self.profileSelectorViewController, profileSelector.profiles.count > 0 {
|
||||||
|
oscProfile = profileSelector.profiles[profileSelector.selectedProfileIndex] as? OSCProfile
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oscProfile = self.profilesManager?.getSelectedProfile()
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let oscProfile = oscProfile else { return }
|
||||||
|
|
||||||
|
if self.profileSelectorLoadingMode == .selectProfileFromStreamView, oscProfile.name == "Default" {
|
||||||
|
OnScreenWidgetView.disableFolderAnimation(for: 1)
|
||||||
|
}
|
||||||
|
|
||||||
if self.profileSelectorLoadingMode == .selectProfileFromStreamView || self.profileSelectorLoadingMode == .pickProfile {
|
if self.profileSelectorLoadingMode == .selectProfileFromStreamView || self.profileSelectorLoadingMode == .pickProfile {
|
||||||
NotificationCenter.default.post(name: Notification.Name("GameProfileSelectedNotification"), object: oscProfile)
|
NotificationCenter.default.post(name: Notification.Name("GameProfileSelectedNotification"), object: oscProfile)
|
||||||
@@ -529,16 +545,18 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
profileSelectorViewController?.layoutViewBounds = view.bounds
|
profileSelectorViewController?.layoutViewBounds = view.bounds
|
||||||
profileSelectorViewController?.needToUpdateOscLayoutTVC = { [weak self] in
|
profileSelectorViewController?.needToUpdateOscLayoutTVC = { [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
if !loadJustTapped {
|
// if !loadJustTapped {
|
||||||
self.reloadOnScreenWidgetViews()
|
self.reloadOnScreenWidgetViews()
|
||||||
}
|
// }
|
||||||
loadJustTapped = false
|
loadJustTapped = false
|
||||||
self.profileSelectorViewController?.currentOSCButtonLayers = self.layoutOSC.oscButtonLayerPool
|
self.profileSelectorViewController?.currentOSCButtonLayers = self.layoutOSC.oscButtonLayerPool
|
||||||
}
|
}
|
||||||
reloadOnScreenWidgetViews()
|
if profileSelectorLoadingMode == .selectProfileFromLayoutTool {
|
||||||
|
reloadOnScreenWidgetViews()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc var profileSelectorLoadingMode: ProfileSelectorLoadingMode = .selectProfile
|
@objc var profileSelectorLoadingMode: ProfileSelectorLoadingMode = .selectProfileFromLayoutTool
|
||||||
|
|
||||||
@objc(presentProfileSelectorWithLoadingMode:)
|
@objc(presentProfileSelectorWithLoadingMode:)
|
||||||
func presentProfileSelector(with loadingModeRawValue: Int) {
|
func presentProfileSelector(with loadingModeRawValue: Int) {
|
||||||
@@ -562,18 +580,18 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
if loadingMode != .pickProfileData {selectedWidget = nil}
|
if loadingMode != .pickProfileData {selectedWidget = nil}
|
||||||
let controller = ProfileSelectorViewController()
|
let controller = ProfileSelectorViewController()
|
||||||
controller.layoutViewBounds = view.bounds
|
controller.layoutViewBounds = view.bounds
|
||||||
controller.needToUpdateOscLayoutTVC = { [weak self] in
|
|
||||||
guard let self else { return }
|
|
||||||
if loadingMode == .selectProfile || loadingMode == .selectProfileFromStreamView || loadingMode == .pickProfile {
|
|
||||||
self.reloadOnScreenWidgetViews()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
controller.currentOSCButtonLayers = layoutOSC.oscButtonLayerPool
|
controller.currentOSCButtonLayers = layoutOSC.oscButtonLayerPool
|
||||||
controller.modalPresentationStyle = .overCurrentContext
|
controller.modalPresentationStyle = .overCurrentContext
|
||||||
controller.loadingMode = loadingMode
|
controller.loadingMode = loadingMode
|
||||||
controller.pickedProfileDataHandler = pickedProfileDataHandler
|
controller.pickedProfileDataHandler = pickedProfileDataHandler
|
||||||
widgetPanelStack.isHidden = true
|
widgetPanelStack.isHidden = true
|
||||||
profileSelectorViewController = controller
|
profileSelectorViewController = controller
|
||||||
|
controller.needToUpdateOscLayoutTVC = { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
if loadingMode == .selectProfileFromLayoutTool || loadingMode == .selectProfileFromStreamView {
|
||||||
|
self.reloadOnScreenWidgetViews()
|
||||||
|
}
|
||||||
|
}
|
||||||
present(controller, animated: animated)
|
present(controller, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,7 +599,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
@IBAction func loadTapped(_ sender: Any?) {
|
@IBAction func loadTapped(_ sender: Any?) {
|
||||||
// saveTapped(nil)
|
// saveTapped(nil)
|
||||||
loadJustTapped = true
|
loadJustTapped = true
|
||||||
presentProfileSelector(with: .selectProfile)
|
presentProfileSelector(with: .selectProfileFromLayoutTool)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func importFromOtherButtonTapped(_ sender: Any?) {
|
@IBAction func importFromOtherButtonTapped(_ sender: Any?) {
|
||||||
@@ -659,7 +677,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
super.viewWillTransition(to: size, with: coordinator)
|
super.viewWillTransition(to: size, with: coordinator)
|
||||||
viewWillBeResized = true
|
viewWillBeResized = true
|
||||||
hideStickIndicators()
|
hideStickIndicators()
|
||||||
if self.profileSelectorLoadingMode == .selectProfile {
|
if self.profileSelectorLoadingMode == .selectProfileFromLayoutTool {
|
||||||
|
|
||||||
let oldSize = view.bounds.size
|
let oldSize = view.bounds.size
|
||||||
let scaleX = size.width / oldSize.width
|
let scaleX = size.width / oldSize.width
|
||||||
@@ -842,7 +860,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
|
|
||||||
private func refreshPanelForSelectedWidget(_ widgetView: OnScreenWidgetView) {
|
private func refreshPanelForSelectedWidget(_ widgetView: OnScreenWidgetView) {
|
||||||
// hideStickIndicators()
|
// hideStickIndicators()
|
||||||
if OnScreenWidgetView.gamepadArrivalReported {clearSickInput()}
|
if ControllerUtil.gamepadArrivalReported {clearSickInput()}
|
||||||
enableCommonWidgetTools()
|
enableCommonWidgetTools()
|
||||||
widgetViewSelected = true
|
widgetViewSelected = true
|
||||||
controllerLayerSelected = false
|
controllerLayerSelected = false
|
||||||
@@ -1587,7 +1605,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func clearSickInput() {
|
private func clearSickInput() {
|
||||||
if selectedWidget != nil && widgetViewSelected && OnScreenWidgetView.gamepadArrivalReported {
|
if selectedWidget != nil && widgetViewSelected && ControllerUtil.gamepadArrivalReported {
|
||||||
OnScreenControls.shared()?.clearLeftStickTouchPadFlag()
|
OnScreenControls.shared()?.clearLeftStickTouchPadFlag()
|
||||||
OnScreenControls.shared()?.clearRightStickTouchPadFlag()
|
OnScreenControls.shared()?.clearRightStickTouchPadFlag()
|
||||||
}
|
}
|
||||||
@@ -1632,7 +1650,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
@objc private func handleProfileSelectorDismiss() {
|
@objc private func handleProfileSelectorDismiss() {
|
||||||
|
|
||||||
switch profileSelectorLoadingMode {
|
switch profileSelectorLoadingMode {
|
||||||
case .selectProfile:
|
case .selectProfileFromLayoutTool:
|
||||||
if profileSelectorViewController?.loadingMode != .pickProfileData {
|
if profileSelectorViewController?.loadingMode != .pickProfileData {
|
||||||
setupWidgetPanel()
|
setupWidgetPanel()
|
||||||
}
|
}
|
||||||
@@ -1721,7 +1739,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func setupWidgetPanel() {
|
private func setupWidgetPanel() {
|
||||||
widgetPanelStack.isHidden = profileSelectorLoadingMode != .selectProfile
|
widgetPanelStack.isHidden = profileSelectorLoadingMode != .selectProfileFromLayoutTool
|
||||||
tipTitleLabel.textAlignment = .left
|
tipTitleLabel.textAlignment = .left
|
||||||
tipTitleLabel.contentMode = .top
|
tipTitleLabel.contentMode = .top
|
||||||
tipTitleLabel.lineBreakMode = .byWordWrapping
|
tipTitleLabel.lineBreakMode = .byWordWrapping
|
||||||
|
|||||||
+8
-7
@@ -274,7 +274,7 @@ private extension UInt64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc enum ProfileSelectorLoadingMode: Int {
|
@objc enum ProfileSelectorLoadingMode: Int {
|
||||||
case selectProfile
|
case selectProfileFromLayoutTool
|
||||||
case selectProfileFromStreamView
|
case selectProfileFromStreamView
|
||||||
case selectProfileFromMainFrame
|
case selectProfileFromMainFrame
|
||||||
case pickProfile
|
case pickProfile
|
||||||
@@ -287,15 +287,15 @@ final class ProfileSelectorViewController: UIViewController, UICollectionViewDat
|
|||||||
var currentFileOperation: FileOperation = .importOperation
|
var currentFileOperation: FileOperation = .importOperation
|
||||||
private var currentExportScope: ProfileExportScope = .allProfiles
|
private var currentExportScope: ProfileExportScope = .allProfiles
|
||||||
var needToUpdateOscLayoutTVC: (() -> Void)?
|
var needToUpdateOscLayoutTVC: (() -> Void)?
|
||||||
var loadingMode: ProfileSelectorLoadingMode = .selectProfile
|
var loadingMode: ProfileSelectorLoadingMode = .selectProfileFromLayoutTool
|
||||||
@nonobjc var pickedProfileDataHandler: ((OSCProfile) -> Void)?
|
@nonobjc var pickedProfileDataHandler: ((OSCProfile) -> Void)?
|
||||||
weak var currentOSCButtonLayers: NSMutableSet?
|
weak var currentOSCButtonLayers: NSMutableSet?
|
||||||
var layoutViewBounds: CGRect = .zero
|
var layoutViewBounds: CGRect = .zero
|
||||||
|
|
||||||
private var profilesManager: OSCProfilesManager!
|
private var profilesManager: OSCProfilesManager!
|
||||||
private var horizontalConstraintsConfigured = false
|
private var horizontalConstraintsConfigured = false
|
||||||
private var profiles: NSMutableArray = []
|
private(set) var profiles: NSMutableArray = []
|
||||||
private var selectedProfileIndex = 0
|
private(set) var selectedProfileIndex = 0
|
||||||
private var profilesLoadGeneration = 0
|
private var profilesLoadGeneration = 0
|
||||||
private var profileCollectionView: UICollectionView!
|
private var profileCollectionView: UICollectionView!
|
||||||
private let contentView = UIView()
|
private let contentView = UIView()
|
||||||
@@ -448,8 +448,9 @@ final class ProfileSelectorViewController: UIViewController, UICollectionViewDat
|
|||||||
}
|
}
|
||||||
if profiles.count > 0 {
|
if profiles.count > 0 {
|
||||||
scrollToSelectedProfile(animated: true)
|
scrollToSelectedProfile(animated: true)
|
||||||
|
notifyProfileViewDidRefresh()
|
||||||
} else {
|
} else {
|
||||||
reloadProfilesAsync(scrollToSelected: true)
|
reloadProfilesAsync(scrollToSelected: true, notify: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadingMode == .selectProfileFromMainFrame || loadingMode == .selectProfileFromStreamView)
|
if (loadingMode == .selectProfileFromMainFrame || loadingMode == .selectProfileFromStreamView)
|
||||||
@@ -748,7 +749,7 @@ final class ProfileSelectorViewController: UIViewController, UICollectionViewDat
|
|||||||
if loadingMode != .selectProfileFromStreamView
|
if loadingMode != .selectProfileFromStreamView
|
||||||
&& loadingMode != .pickProfile
|
&& loadingMode != .pickProfile
|
||||||
&& loadingMode != .pickProfileData
|
&& loadingMode != .pickProfileData
|
||||||
&& loadingMode != .selectProfile
|
&& loadingMode != .selectProfileFromLayoutTool
|
||||||
{
|
{
|
||||||
guard let selectedProfileIndex = validProfileIndex(selectedProfileIndex) else { return }
|
guard let selectedProfileIndex = validProfileIndex(selectedProfileIndex) else { return }
|
||||||
NotificationCenter.default.post(name: Notification.Name("GameProfileSelectedNotification"), object: self.profiles[selectedProfileIndex])
|
NotificationCenter.default.post(name: Notification.Name("GameProfileSelectedNotification"), object: self.profiles[selectedProfileIndex])
|
||||||
@@ -1189,7 +1190,7 @@ final class ProfileSelectorViewController: UIViewController, UICollectionViewDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
||||||
if (loadingMode != .selectProfile
|
if (loadingMode != .selectProfileFromLayoutTool
|
||||||
&& loadingMode != .selectProfileFromMainFrame
|
&& loadingMode != .selectProfileFromMainFrame
|
||||||
&& loadingMode != .selectProfileFromStreamView
|
&& loadingMode != .selectProfileFromStreamView
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -306,8 +306,8 @@
|
|||||||
@property (weak, nonatomic) IBOutlet UIStackView *disablePencilSlideGestureStack;
|
@property (weak, nonatomic) IBOutlet UIStackView *disablePencilSlideGestureStack;
|
||||||
@property (weak, nonatomic) IBOutlet UISwitch *disablePencilSlideGestureSwitch;
|
@property (weak, nonatomic) IBOutlet UISwitch *disablePencilSlideGestureSwitch;
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UIStackView *hoverModeStack;
|
@property (weak, nonatomic) IBOutlet UIStackView *pencilModeStack;
|
||||||
@property (weak, nonatomic) IBOutlet UISegmentedControl *hoverModeSelector;
|
@property (weak, nonatomic) IBOutlet UISegmentedControl *pencilModeSelector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
[self.squeezeShortcutSwitch setOn:oscProfile.squeezeShorcutEnabled];
|
[self.squeezeShortcutSwitch setOn:oscProfile.squeezeShorcutEnabled];
|
||||||
[self.pencilPausesNativeTouchSwitch setOn:oscProfile.pencilPausesNativeTouch];
|
[self.pencilPausesNativeTouchSwitch setOn:oscProfile.pencilPausesNativeTouch];
|
||||||
[self.disablePencilSlideGestureSwitch setOn:oscProfile.disablePencilSlideGestures];
|
[self.disablePencilSlideGestureSwitch setOn:oscProfile.disablePencilSlideGestures];
|
||||||
self.hoverModeSelector.selectedSegmentIndex = oscProfile.pencilHoverMode;
|
self.pencilModeSelector.selectedSegmentIndex = oscProfile.pencilAndHoverMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)saveGameProfileConfigs{
|
- (void)saveGameProfileConfigs{
|
||||||
@@ -472,7 +472,7 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
&& oscProfile.squeezeShorcutEnabled == self.squeezeShortcutSwitch.isOn
|
&& oscProfile.squeezeShorcutEnabled == self.squeezeShortcutSwitch.isOn
|
||||||
&& oscProfile.pencilPausesNativeTouch == self.pencilPausesNativeTouchSwitch.isOn
|
&& oscProfile.pencilPausesNativeTouch == self.pencilPausesNativeTouchSwitch.isOn
|
||||||
&& oscProfile.disablePencilSlideGestures == self.disablePencilSlideGestureSwitch.isOn
|
&& oscProfile.disablePencilSlideGestures == self.disablePencilSlideGestureSwitch.isOn
|
||||||
&& oscProfile.pencilHoverMode == self.hoverModeSelector.selectedSegmentIndex
|
&& oscProfile.pencilAndHoverMode == self.pencilModeSelector.selectedSegmentIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!configNotChanged){
|
if(!configNotChanged){
|
||||||
@@ -499,12 +499,12 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
oscProfile.squeezeShorcutEnabled = self.squeezeShortcutSwitch.isOn;
|
oscProfile.squeezeShorcutEnabled = self.squeezeShortcutSwitch.isOn;
|
||||||
oscProfile.pencilPausesNativeTouch = self.pencilPausesNativeTouchSwitch.isOn;
|
oscProfile.pencilPausesNativeTouch = self.pencilPausesNativeTouchSwitch.isOn;
|
||||||
oscProfile.disablePencilSlideGestures = self.disablePencilSlideGestureSwitch.isOn;
|
oscProfile.disablePencilSlideGestures = self.disablePencilSlideGestureSwitch.isOn;
|
||||||
oscProfile.pencilHoverMode = self.hoverModeSelector.selectedSegmentIndex;
|
oscProfile.pencilAndHoverMode = self.pencilModeSelector.selectedSegmentIndex;
|
||||||
[oscProfileMan replaceSelectedProfileWith:oscProfile overwriteDefault:YES];
|
[oscProfileMan replaceSelectedProfileWith:oscProfile overwriteDefault:YES];
|
||||||
if(PencilHandler.shared) [PencilHandler.shared setupPressureLUTWithProfile:oscProfile];
|
if(PencilHandler.shared) [PencilHandler.shared setupPressureLUTWithProfile:oscProfile];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!leftStickMinOffsetSliderNotMoved || !rightStickMinOffsetSliderNotMoved || OnScreenWidgetView.gamepadArrivalReported){
|
if(!leftStickMinOffsetSliderNotMoved || !rightStickMinOffsetSliderNotMoved || ControllerUtil.gamepadArrivalReported){
|
||||||
if(OnScreenControls.shared){
|
if(OnScreenControls.shared){
|
||||||
[OnScreenControls.shared clearLeftStickTouchPadFlag];
|
[OnScreenControls.shared clearLeftStickTouchPadFlag];
|
||||||
[OnScreenControls.shared clearRightStickTouchPadFlag];
|
[OnScreenControls.shared clearRightStickTouchPadFlag];
|
||||||
@@ -1087,9 +1087,9 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
self.squeezeShortcutStack.hasInfoTag = YES;
|
self.squeezeShortcutStack.hasInfoTag = YES;
|
||||||
[self addSetting:self.squeezeShortcutStack ofId:@"squeezeShortcutStack" to:pencilSection];
|
[self addSetting:self.squeezeShortcutStack ofId:@"squeezeShortcutStack" to:pencilSection];
|
||||||
|
|
||||||
self.hoverModeStack.isGameProfileSetting = YES;
|
self.pencilModeStack.isGameProfileSetting = YES;
|
||||||
self.hoverModeStack.hasInfoTag = YES;
|
self.pencilModeStack.hasInfoTag = YES;
|
||||||
[self addSetting:self.hoverModeStack ofId:@"hoverModeStack" to:pencilSection];
|
[self addSetting:self.pencilModeStack ofId:@"pencilModeStack" to:pencilSection];
|
||||||
|
|
||||||
self.pencilPausesNativeTouchStack.isGameProfileSetting = YES;
|
self.pencilPausesNativeTouchStack.isGameProfileSetting = YES;
|
||||||
[self addSetting:self.pencilPausesNativeTouchStack ofId:@"pencilPausesNativeTouchStack" to:pencilSection];
|
[self addSetting:self.pencilPausesNativeTouchStack ofId:@"pencilPausesNativeTouchStack" to:pencilSection];
|
||||||
@@ -1799,8 +1799,8 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
tipText = [LocalizationHelper localizedStringForKey:@"asyncFrameDequeueStackTip"];
|
tipText = [LocalizationHelper localizedStringForKey:@"asyncFrameDequeueStackTip"];
|
||||||
showOnlineDocAction = false;
|
showOnlineDocAction = false;
|
||||||
}
|
}
|
||||||
if([sender.superview.accessibilityIdentifier isEqualToString: @"hoverModeStack"]){
|
if([sender.superview.accessibilityIdentifier isEqualToString: @"pencilModeStack"]){
|
||||||
tipText = [LocalizationHelper localizedStringForKey:@"hoverModeStackTip"];
|
tipText = [LocalizationHelper localizedStringForKey:@"pencilModeStackTip"];
|
||||||
showOnlineDocAction = false;
|
showOnlineDocAction = false;
|
||||||
}
|
}
|
||||||
if([sender.superview.accessibilityIdentifier isEqualToString: @"pencilTickStack"]){
|
if([sender.superview.accessibilityIdentifier isEqualToString: @"pencilTickStack"]){
|
||||||
@@ -3107,7 +3107,7 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
rightButtonCaptured = true;
|
rightButtonCaptured = true;
|
||||||
|
|
||||||
if (@available(iOS 13.0, *)) {
|
if (@available(iOS 13.0, *)) {
|
||||||
NSLog(@"custom posistion local %d , stream: %d", currentSettings.customLocalRadialMenuButtonPosition.intValue, currentSettings.customStreamingRadialMenuButtonPosition.intValue);
|
// NSLog(@"custom posistion local %d , stream: %d", currentSettings.customLocalRadialMenuButtonPosition.intValue, currentSettings.customStreamingRadialMenuButtonPosition.intValue);
|
||||||
|
|
||||||
ControllerNavigator.localRadialMenuButton = (ControllerElement)currentSettings.localRadialMenuButton.intValue;
|
ControllerNavigator.localRadialMenuButton = (ControllerElement)currentSettings.localRadialMenuButton.intValue;
|
||||||
ControllerNavigator.customPositionForLocalRadialMenuButton = (ControllerElementPosition)currentSettings.customLocalRadialMenuButtonPosition.intValue;
|
ControllerNavigator.customPositionForLocalRadialMenuButton = (ControllerElementPosition)currentSettings.customLocalRadialMenuButtonPosition.intValue;
|
||||||
@@ -3196,21 +3196,21 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
[self findDynamicLabelFromStack:(UIStackView*)sender.superview].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
|
[self findDynamicLabelFromStack:(UIStackView*)sender.superview].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
|
||||||
if(settingsViewJustExpanded) return;
|
if(settingsViewJustExpanded) return;
|
||||||
LiSendControllerEvent(0, 0, 0, _rollToLeftStickSwitch.isOn?sender.value:0, 0, _yawPitchToRightStickSwitch.isOn?sender.value:0, 0);
|
LiSendControllerEvent(0, 0, 0, _rollToLeftStickSwitch.isOn?sender.value:0, 0, _yawPitchToRightStickSwitch.isOn?sender.value:0, 0);
|
||||||
OnScreenWidgetView.gamepadArrivalReported = true;
|
ControllerUtil.gamepadArrivalReported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)leftStickMinOffsetSliderMoved:(UISlider* )sender{
|
- (void)leftStickMinOffsetSliderMoved:(UISlider* )sender{
|
||||||
[self findDynamicLabelFromStack:(UIStackView*)sender.superview].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
|
[self findDynamicLabelFromStack:(UIStackView*)sender.superview].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
|
||||||
if(settingsViewJustExpanded) return;
|
if(settingsViewJustExpanded) return;
|
||||||
LiSendControllerEvent(0, 0, 0, sender.value, 0, 0, 0);
|
LiSendControllerEvent(0, 0, 0, sender.value, 0, 0, 0);
|
||||||
OnScreenWidgetView.gamepadArrivalReported = true;
|
ControllerUtil.gamepadArrivalReported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)rightStickMinOffsetSliderMoved:(UISlider* )sender{
|
- (void)rightStickMinOffsetSliderMoved:(UISlider* )sender{
|
||||||
[self findDynamicLabelFromStack:(UIStackView*)sender.superview].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
|
[self findDynamicLabelFromStack:(UIStackView*)sender.superview].text = [NSString stringWithFormat:@" %d ", (int16_t)sender.value];
|
||||||
if(settingsViewJustExpanded) return;
|
if(settingsViewJustExpanded) return;
|
||||||
LiSendControllerEvent(0, 0, 0, 0, 0, sender.value, 0);
|
LiSendControllerEvent(0, 0, 0, 0, 0, sender.value, 0);
|
||||||
OnScreenWidgetView.gamepadArrivalReported = true;
|
ControllerUtil.gamepadArrivalReported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)invokeOscLayout{
|
- (void)invokeOscLayout{
|
||||||
@@ -4247,8 +4247,10 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
|
|
||||||
CGFloat settingsMenuOffset = _rememberFoldStateSwitch.isOn ? _scrollView.contentOffset.y : 0;
|
CGFloat settingsMenuOffset = _rememberFoldStateSwitch.isOn ? _scrollView.contentOffset.y : 0;
|
||||||
|
|
||||||
NSInteger height = self.mainFrameViewController.settingsExpandedInStreamView ? currentSettings.height.intValue : [self getChosenStreamHeight];
|
NSInteger height = self.mainFrameViewController.isStreaming ? currentSettings.height.intValue : [self getChosenStreamHeight];
|
||||||
NSInteger width = self.mainFrameViewController.settingsExpandedInStreamView ? currentSettings.width.intValue : [self getChosenStreamWidth];
|
NSInteger width = self.mainFrameViewController.isStreaming ? currentSettings.width.intValue : [self getChosenStreamWidth];
|
||||||
|
|
||||||
|
// NSLog(@"saveSettings aspectRatio %d, %ld, %ld",self.mainFrameViewController.isStreaming, width, height);
|
||||||
|
|
||||||
NSInteger framerate = [self getChosenFrameRate];
|
NSInteger framerate = [self getChosenFrameRate];
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,9 @@
|
|||||||
@property (nonatomic, assign) CGPoint streamViewMagnifierContentOffset;
|
@property (nonatomic, assign) CGPoint streamViewMagnifierContentOffset;
|
||||||
@property (nonatomic, assign) CGFloat streamViewMagnifierZoomScale;
|
@property (nonatomic, assign) CGFloat streamViewMagnifierZoomScale;
|
||||||
|
|
||||||
|
@property(nonatomic, assign) bool touchDisabled;
|
||||||
|
@property(nonatomic, assign) bool singleTouchDisabled;
|
||||||
|
|
||||||
|
|
||||||
+ (StreamFrameViewController *)sharedInstance;
|
+ (StreamFrameViewController *)sharedInstance;
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
@interface AVDisplayCriteria()
|
@interface AVDisplayCriteria()
|
||||||
@property(readonly) int videoDynamicRange;
|
@property(readonly) int videoDynamicRange;
|
||||||
@property(readonly, nonatomic) float refreshRate;
|
@property(readonly, nonatomic) float refreshRate;
|
||||||
|
|
||||||
- (id)initWithRefreshRate:(float)arg1 videoDynamicRange:(int)arg2;
|
- (id)initWithRefreshRate:(float)arg1 videoDynamicRange:(int)arg2;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -127,6 +128,7 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
MicHandler* micHandler;
|
MicHandler* micHandler;
|
||||||
MotionHandler *_motionHandler;
|
MotionHandler *_motionHandler;
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
UITapGestureRecognizer *_menuTapGestureRecognizer;
|
UITapGestureRecognizer *_menuTapGestureRecognizer;
|
||||||
UITapGestureRecognizer *_menuDoubleTapGestureRecognizer;
|
UITapGestureRecognizer *_menuDoubleTapGestureRecognizer;
|
||||||
@@ -857,12 +859,15 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
viewIsBeingResized = false;
|
viewIsBeingResized = false;
|
||||||
_magnifierViewportInteractionActive = false;
|
_magnifierViewportInteractionActive = false;
|
||||||
|
|
||||||
|
_touchDisabled = false;
|
||||||
|
_singleTouchDisabled = false;
|
||||||
|
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
[self.navigationController setNavigationBarHidden:YES animated:YES];
|
[self.navigationController setNavigationBarHidden:YES animated:YES];
|
||||||
|
|
||||||
[UIApplication sharedApplication].idleTimerDisabled = YES;
|
[UIApplication sharedApplication].idleTimerDisabled = YES;
|
||||||
|
|
||||||
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
|
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
|
||||||
|
|
||||||
_stageLabel = [[UILabel alloc] init];
|
_stageLabel = [[UILabel alloc] init];
|
||||||
@@ -898,9 +903,9 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
|
|
||||||
toolBoxViewController = [[ToolboxViewController alloc] init];
|
toolBoxViewController = [[ToolboxViewController alloc] init];
|
||||||
toolBoxViewController.specialEntryDelegate = self;
|
toolBoxViewController.specialEntryDelegate = self;
|
||||||
|
|
||||||
_isRestoringFromPiP = NO;
|
_isRestoringFromPiP = NO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
_settings.externalDisplayMode.intValue:
|
_settings.externalDisplayMode.intValue:
|
||||||
0 - stage manager
|
0 - stage manager
|
||||||
@@ -915,12 +920,12 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
[self reConfigStreamViewRealtime]; // call this method again to make sure all gestures are configured & added to the superview(self.view), including the gestures added from inside the streamview.
|
[self reConfigStreamViewRealtime]; // call this method again to make sure all gestures are configured & added to the superview(self.view), including the gestures added from inside the streamview.
|
||||||
|
|
||||||
if([self isFirstStreaming] || GenericUtils.isFirstStreamingOnMac) [self popFirstStreamingTip];
|
if([self isFirstStreaming] || GenericUtils.isFirstStreamingOnMac) [self popFirstStreamingTip];
|
||||||
|
|
||||||
#if TARGET_OS_TV
|
#if TARGET_OS_TV
|
||||||
if (!_menuTapGestureRecognizer || !_menuDoubleTapGestureRecognizer || !_playPauseTapGestureRecognizer) {
|
if (!_menuTapGestureRecognizer || !_menuDoubleTapGestureRecognizer || !_playPauseTapGestureRecognizer) {
|
||||||
_menuTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(controllerPauseButtonPressed:)];
|
_menuTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(controllerPauseButtonPressed:)];
|
||||||
_menuTapGestureRecognizer.allowedPressTypes = @[@(UIPressTypeMenu)];
|
_menuTapGestureRecognizer.allowedPressTypes = @[@(UIPressTypeMenu)];
|
||||||
|
|
||||||
_playPauseTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(controllerPlayPauseButtonPressed:)];
|
_playPauseTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(controllerPlayPauseButtonPressed:)];
|
||||||
_playPauseTapGestureRecognizer.allowedPressTypes = @[@(UIPressTypePlayPause)];
|
_playPauseTapGestureRecognizer.allowedPressTypes = @[@(UIPressTypePlayPause)];
|
||||||
|
|
||||||
@@ -933,7 +938,7 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
[self.view addGestureRecognizer:_menuTapGestureRecognizer];
|
[self.view addGestureRecognizer:_menuTapGestureRecognizer];
|
||||||
[self.view addGestureRecognizer:_menuDoubleTapGestureRecognizer];
|
[self.view addGestureRecognizer:_menuDoubleTapGestureRecognizer];
|
||||||
[self.view addGestureRecognizer:_playPauseTapGestureRecognizer];
|
[self.view addGestureRecognizer:_playPauseTapGestureRecognizer];
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//[self configSwipeGestures]; // swipe & exit gesture configured here
|
//[self configSwipeGestures]; // swipe & exit gesture configured here
|
||||||
//[self configOscLayoutTool]; //_oscLayoutTapRecoginizer will be added or removed to the view here
|
//[self configOscLayoutTool]; //_oscLayoutTapRecoginizer will be added or removed to the view here
|
||||||
@@ -978,7 +983,7 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
selector:@selector(gameProfileSelectorClosed)
|
selector:@selector(gameProfileSelectorClosed)
|
||||||
name:@"GameProfileSelectorCloseNotification"
|
name:@"GameProfileSelectorCloseNotification"
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
selector:@selector(handleStreamAspectRatioChanged:)
|
selector:@selector(handleStreamAspectRatioChanged:)
|
||||||
name:@"StreamAspectRatioChanged"
|
name:@"StreamAspectRatioChanged"
|
||||||
@@ -1008,13 +1013,13 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
[self.view addSubview:_stageLabel];
|
[self.view addSubview:_stageLabel];
|
||||||
[self.view addSubview:_spinner];
|
[self.view addSubview:_spinner];
|
||||||
[self.view addSubview:_tipLabel];
|
[self.view addSubview:_tipLabel];
|
||||||
|
|
||||||
if ([_settings.renderingBackend intValue] == RENDER_METAL) {
|
if ([_settings.renderingBackend intValue] == RENDER_METAL) {
|
||||||
// Metal view for video
|
// Metal view for video
|
||||||
Log(LOG_I, @"StreamFrameViewController creating MetalViewController");
|
Log(LOG_I, @"StreamFrameViewController creating MetalViewController");
|
||||||
self.metalViewController = [[MetalViewController alloc] initWithFrame:self.view.bounds
|
self.metalViewController = [[MetalViewController alloc] initWithFrame:self.view.bounds
|
||||||
framerate:[self->_settings.framerate floatValue]
|
framerate:[self->_settings.framerate floatValue]
|
||||||
settings:self->_settings
|
settings:self->_settings
|
||||||
metricsHandler:self.imguiView.metricsHandler];
|
metricsHandler:self.imguiView.metricsHandler];
|
||||||
self.metalViewController.view.userInteractionEnabled = NO;
|
self.metalViewController.view.userInteractionEnabled = NO;
|
||||||
[self addChildViewController:self.metalViewController];
|
[self addChildViewController:self.metalViewController];
|
||||||
@@ -1022,14 +1027,10 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
[self.view insertSubview:self.metalViewController.view atIndex:0];
|
[self.view insertSubview:self.metalViewController.view atIndex:0];
|
||||||
[self.metalViewController didMoveToParentViewController:self];
|
[self.metalViewController didMoveToParentViewController:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
OnScreenWidgetView.gamepadArrivalReported = false;
|
|
||||||
|
|
||||||
OnScreenWidgetView.enableFolderAnimation = false;
|
ControllerUtil.gamepadArrivalReported = false;
|
||||||
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
|
|
||||||
dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
[OnScreenWidgetView disableFolderAnimationFor:2];
|
||||||
OnScreenWidgetView.enableFolderAnimation = true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyboardWillShow:(NSNotification *)notification{
|
- (void)keyboardWillShow:(NSNotification *)notification{
|
||||||
@@ -1074,6 +1075,7 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
_layoutOnScreenControlsVC.toolbarStackView.hidden = true;
|
_layoutOnScreenControlsVC.toolbarStackView.hidden = true;
|
||||||
_layoutOnScreenControlsVC.toolbarRootView.hidden = true;
|
_layoutOnScreenControlsVC.toolbarRootView.hidden = true;
|
||||||
ProfileSelectorLoadingMode loadingMode = pickProfile ? ProfileSelectorLoadingModePickProfile : ProfileSelectorLoadingModeSelectProfileFromStreamView;
|
ProfileSelectorLoadingMode loadingMode = pickProfile ? ProfileSelectorLoadingModePickProfile : ProfileSelectorLoadingModeSelectProfileFromStreamView;
|
||||||
|
_layoutOnScreenControlsVC.profileSelectorLoadingMode = loadingMode;
|
||||||
[self presentViewController:_layoutOnScreenControlsVC animated:NO completion:^{
|
[self presentViewController:_layoutOnScreenControlsVC animated:NO completion:^{
|
||||||
[self->_layoutOnScreenControlsVC presentProfileSelectorWith:loadingMode animated:false];
|
[self->_layoutOnScreenControlsVC presentProfileSelectorWith:loadingMode animated:false];
|
||||||
}];
|
}];
|
||||||
@@ -1198,6 +1200,7 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
// [self->_streamView reloadLegacyWidgets];
|
// [self->_streamView reloadLegacyWidgets];
|
||||||
[self reConfigStreamViewRealtimeAndReloadSettings:NO reloadOnscreenWidgets:_settings.onscreenControls.intValue == OnScreenControlsLevelCustom];
|
[self reConfigStreamViewRealtimeAndReloadSettings:NO reloadOnscreenWidgets:_settings.onscreenControls.intValue == OnScreenControlsLevelCustom];
|
||||||
// [self->_streamView reloadGameProfile:nil reloadWidgets:true]; //update keyboard buttons here
|
// [self->_streamView reloadGameProfile:nil reloadWidgets:true]; //update keyboard buttons here
|
||||||
|
[OnScreenWidgetView disableFolderAnimationFor:2];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleStreamAspectRatioChanged:(NSNotification *)notification {
|
- (void)handleStreamAspectRatioChanged:(NSNotification *)notification {
|
||||||
@@ -2111,8 +2114,8 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
[_streamView disablePencilHover];
|
[_streamView disablePencilHover];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAllowSingleTouchEnabled:(BOOL)enabled{
|
- (void)handleDisableSingleTouchButtonUp {
|
||||||
[_streamView setAllowSingleTouchEnabled:enabled];
|
[_streamView setAllowSingleTouchEnabled:!_singleTouchDisabled];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)replaceBrushWithShortcut:(NSString *)shortcut{
|
- (void)replaceBrushWithShortcut:(NSString *)shortcut{
|
||||||
@@ -2127,8 +2130,8 @@ static __weak StreamFrameViewController *VLSharedStreamFrameViewController = nil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)toggleTouchWithDisabled:(BOOL)disabled{
|
- (void)handleTouchDisableButtonUp {
|
||||||
[_streamView toggleTouchDisabled:disabled];
|
[_streamView toggleTouchDisabled:self.touchDisabled];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)presentPressureCurveVC{
|
- (void)presentPressureCurveVC{
|
||||||
|
|||||||
@@ -2648,30 +2648,30 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DhB-EF-mDt.text" : {
|
"DhB-EF-mDt.text" : {
|
||||||
"comment" : "Class = \"UILabel\"; text = \"Hover Mode\"; ObjectID = \"DhB-EF-mDt\";",
|
"comment" : "Class = \"UILabel\"; text = \"Pencil Mode\"; ObjectID = \"DhB-EF-mDt\";",
|
||||||
"extractionState" : "extracted_with_value",
|
"extractionState" : "extracted_with_value",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "new",
|
"state" : "new",
|
||||||
"value" : "Hover Mode"
|
"value" : "Pencil Mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "needs_review",
|
||||||
"value" : "悬停模式"
|
"value" : "悬停模式"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "needs_review",
|
||||||
"value" : "懸停模式"
|
"value" : "懸停模式"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "needs_review",
|
||||||
"value" : "懸停模式"
|
"value" : "懸停模式"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6311,31 +6311,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"t12-bo-icS.segmentTitles[0]" : {
|
"t12-bo-icS.segmentTitles[0]" : {
|
||||||
"comment" : "Class = \"UISegmentedControl\"; t12-bo-icS.segmentTitles[0] = \"Disabled\"; ObjectID = \"t12-bo-icS\";",
|
"comment" : "Class = \"UISegmentedControl\"; t12-bo-icS.segmentTitles[0] = \"Hovering Disabled\"; ObjectID = \"t12-bo-icS\";",
|
||||||
"extractionState" : "extracted_with_value",
|
"extractionState" : "extracted_with_value",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "new",
|
"state" : "new",
|
||||||
"value" : "Disabled"
|
"value" : "Hovering Disabled"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "关闭"
|
"value" : "关闭悬停"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "關閉"
|
"value" : "關閉懸停"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "關閉"
|
"value" : "關閉懸停"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6401,31 +6401,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"t12-bo-icS.segmentTitles[3]" : {
|
"t12-bo-icS.segmentTitles[3]" : {
|
||||||
"comment" : "Class = \"UISegmentedControl\"; t12-bo-icS.segmentTitles[3] = \"Both\"; ObjectID = \"t12-bo-icS\";",
|
"comment" : "Class = \"UISegmentedControl\"; t12-bo-icS.segmentTitles[3] = \"Touch\"; ObjectID = \"t12-bo-icS\";",
|
||||||
"extractionState" : "extracted_with_value",
|
"extractionState" : "extracted_with_value",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "new",
|
"state" : "new",
|
||||||
"value" : "Both"
|
"value" : "Touch"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "同时悬停"
|
"value" : "触控"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "同時懸停"
|
"value" : "觸控"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "同時懸停"
|
"value" : "觸控"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7284,4 +7284,4 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "1.0"
|
"version" : "1.0"
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user