Merge remote-tracking branch 'upstream/Integration' into feat/frame_pacing_metal
# Conflicts: # VoidLink/mul.lproj/iPad.xcstrings
This commit is contained in:
@@ -1396,7 +1396,7 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="z5Q-bW-WQ8" userLabel="widgetPanelStack" customClass="WidgetPanelStackView">
|
||||
<rect key="frame" x="325" y="156" width="650" height="343.5"/>
|
||||
<rect key="frame" x="325" y="156" width="650" height="379.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Profile:" textAlignment="center" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iel-xl-xd9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="650" height="37"/>
|
||||
@@ -1561,7 +1561,7 @@
|
||||
</label>
|
||||
<slider clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.93000000000000005" minValue="0.5" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="nzC-NF-fkv">
|
||||
<rect key="frame" x="158" y="0.0" width="494" height="31"/>
|
||||
<color key="tintColor" red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="tintColor" red="0.34534250659404359" green="0.68327885717542713" blue="0.76859849691390991" alpha="0.5" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<color key="maximumTrackTintColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</slider>
|
||||
</subviews>
|
||||
@@ -1588,10 +1588,44 @@
|
||||
<segment title="right button"/>
|
||||
</segments>
|
||||
<color key="tintColor" systemColor="systemGray3Color"/>
|
||||
<color key="selectedSegmentTintColor" red="0.23136288839999999" green="0.45776400810000001" blue="0.5149240678" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<color key="selectedSegmentTintColor" red="0.23087820410000001" green="0.4576539993" blue="0.51765710119999997" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LGW-oJ-5Zf" userLabel="slidableStack">
|
||||
<rect key="frame" x="0.0" y="348.5" width="650" height="31"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Slide Activated" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qNQ-fB-jhY" userLabel="uiLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="160" height="31"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="160" id="P7b-Jz-LEK"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<segmentedControl opaque="NO" alpha="0.76999998092651367" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="cKS-fy-Zpg">
|
||||
<rect key="frame" x="160" y="0.0" width="367" height="32"/>
|
||||
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<segments>
|
||||
<segment title="toggle"/>
|
||||
<segment title="slide & hold"/>
|
||||
<segment title="disabled"/>
|
||||
</segments>
|
||||
<color key="tintColor" systemColor="systemGray3Color"/>
|
||||
<color key="selectedSegmentTintColor" red="0.23087820410000001" green="0.4576539993" blue="0.51765710119999997" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
</segmentedControl>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dOF-FW-cBU" userLabel="uiLabel">
|
||||
<rect key="frame" x="527" y="0.0" width="123" height="31"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="123" id="hfV-um-PjK"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<constraints>
|
||||
@@ -1631,6 +1665,8 @@
|
||||
<outlet property="sensitivityYLabel" destination="NZO-BM-nef" id="baU-O4-Qp7"/>
|
||||
<outlet property="sensitivityYSlider" destination="2Wo-9z-DtK" id="Hw1-JZ-vir"/>
|
||||
<outlet property="sensitivityYStack" destination="CT5-Ap-Gh0" id="qY9-G9-b7r"/>
|
||||
<outlet property="slidableSelector" destination="cKS-fy-Zpg" id="uIq-60-t7E"/>
|
||||
<outlet property="slidableStack" destination="LGW-oJ-5Zf" id="Jn6-Mu-XYp"/>
|
||||
<outlet property="stickIndicatorOffsetLabel" destination="tG7-oX-P9b" id="jBx-ii-091"/>
|
||||
<outlet property="stickIndicatorOffsetSlider" destination="aPX-7o-N3l" id="gLv-c3-3JG"/>
|
||||
<outlet property="stickIndicatorOffsetStack" destination="zfD-bd-GEN" id="oeb-Vk-2mw"/>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<objects>
|
||||
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="Rtu-AT-Alw" customClass="AppCollectionView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="756"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="15" minimumInteritemSpacing="15" id="YcZ-cR-3tK">
|
||||
@@ -314,7 +314,7 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="BVp-3O-vZ7" userLabel="widgetPanelStack" customClass="WidgetPanelStackView">
|
||||
<rect key="frame" x="375" y="132" width="550" height="298.5"/>
|
||||
<rect key="frame" x="375" y="132" width="550" height="325.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Profile:" textAlignment="center" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f46-Pt-0Pv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="550" height="28"/>
|
||||
@@ -565,6 +565,43 @@
|
||||
<constraint firstAttribute="height" constant="20" id="Vgj-B6-LEU"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jE7-IB-GTS" userLabel="slidableStack">
|
||||
<rect key="frame" x="0.0" y="305.5" width="550" height="20"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Slide Activated" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="o9I-Gt-YRd" userLabel="uilabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="160" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="160" id="W2q-kp-7ce"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<segmentedControl opaque="NO" alpha="0.69999998807907104" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="ojp-aS-m8w">
|
||||
<rect key="frame" x="160" y="0.0" width="291" height="21"/>
|
||||
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<segments>
|
||||
<segment title="toggle"/>
|
||||
<segment title="slide & hold"/>
|
||||
<segment title="disabled"/>
|
||||
</segments>
|
||||
<color key="tintColor" systemColor="systemGray2Color"/>
|
||||
<color key="selectedSegmentTintColor" red="0.23136288839999999" green="0.45776400810000001" blue="0.5149240678" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
</segmentedControl>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KZ3-vJ-E8J" userLabel="uilabel">
|
||||
<rect key="frame" x="451" y="0.0" width="99" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="99" id="BZO-g1-Px9"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="Qap-bn-YnJ"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
@@ -597,6 +634,8 @@
|
||||
<outlet property="sensitivityYLabel" destination="R9C-JW-nkF" id="80R-jo-bcA"/>
|
||||
<outlet property="sensitivityYSlider" destination="W7r-eN-vZJ" id="xGy-E1-87k"/>
|
||||
<outlet property="sensitivityYStack" destination="50h-xK-Lq0" id="eOh-7i-9mS"/>
|
||||
<outlet property="slidableSelector" destination="ojp-aS-m8w" id="ACc-Sd-Edq"/>
|
||||
<outlet property="slidableStack" destination="jE7-IB-GTS" id="hKb-gp-eem"/>
|
||||
<outlet property="stickIndicatorOffsetLabel" destination="fcy-zp-LGa" id="lZP-Uv-mMH"/>
|
||||
<outlet property="stickIndicatorOffsetSlider" destination="DCr-vG-gM7" id="aYH-VM-p5l"/>
|
||||
<outlet property="stickIndicatorOffsetStack" destination="Ejp-Jq-phL" id="HNM-4A-VmN"/>
|
||||
@@ -1684,16 +1723,16 @@
|
||||
<image name="trash.fill" catalog="system" width="117" height="128"/>
|
||||
<image name="tray.full.fill" catalog="system" width="128" height="88"/>
|
||||
<systemColor name="linkColor">
|
||||
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBrownColor">
|
||||
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGray2Color">
|
||||
<color red="0.68235294117647061" green="0.68235294117647061" blue="0.69803921568627447" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.68235294120000001" green="0.68235294120000001" blue="0.69803921570000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemTealColor">
|
||||
<color red="0.18823529411764706" green="0.69019607843137254" blue="0.7803921568627451" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -90,6 +90,7 @@ import UIKit
|
||||
"OSCDOWN" : DOWN_FLAG,
|
||||
"OSCLEFT" : LEFT_FLAG,
|
||||
"OSCRIGHT" : RIGHT_FLAG,
|
||||
"DS4TOUCH" : TOUCHPAD_FLAG,
|
||||
"OSCL2" : 0,
|
||||
"L2" : 0,
|
||||
"LT" : 0,
|
||||
@@ -109,7 +110,7 @@ import UIKit
|
||||
"OSCBACK"
|
||||
]
|
||||
|
||||
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "MOUSEPAD", "DPAD", "TRACKBALL", "WASDPAD", "ARROWPAD"]
|
||||
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "DS4TOUCH", "MOUSEPAD", "DPAD", "TRACKBALL", "WASDPAD", "ARROWPAD"]
|
||||
@objc public static let stickTouchPads: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD"]
|
||||
@objc public static let nonVectorStickPads: [String] = ["LSPAD", "RSPAD"]
|
||||
@objc public static let specialOverlayButtonCmds: [String] = ["SETTINGS"]
|
||||
|
||||
@@ -363,8 +363,6 @@ static CGRect layoutViewBounds;
|
||||
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];
|
||||
@@ -376,8 +374,9 @@ static CGRect layoutViewBounds;
|
||||
CGPoint normalizedPosition = [self normalizeWidgetPosition:widgetView.center];
|
||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:widgetView.cmdString buttonType:CustomOnScreenWidget andPosition:normalizedPosition];
|
||||
buttonState.alias = widgetView.buttonLabel;
|
||||
buttonState.widthFactor = widgetView.widthFactor;
|
||||
buttonState.heightFactor = widgetView.heightFactor;
|
||||
buttonState.widthFactor = [self normalizeSizeWidthFactor:widgetView];
|
||||
NSLog(@"logging widthFactor %f", buttonState.widthFactor);
|
||||
buttonState.heightFactor = [self normalizeSizeHeightFactor:widgetView];
|
||||
buttonState.backgroundAlpha = widgetView.backgroundAlpha;
|
||||
buttonState.borderWidth = widgetView.borderWidth;
|
||||
buttonState.vibrationStyle = widgetView.vibrationStyle;
|
||||
@@ -388,6 +387,7 @@ static CGRect layoutViewBounds;
|
||||
buttonState.stickIndicatorOffset = widgetView.stickIndicatorOffset;
|
||||
buttonState.widgetShape = widgetView.shape;
|
||||
buttonState.minStickOffset = widgetView.minStickOffset;
|
||||
buttonState.slideMode = widgetView.slideMode;
|
||||
|
||||
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
||||
@@ -396,6 +396,15 @@ static CGRect layoutViewBounds;
|
||||
return buttonStatesEncoded;
|
||||
}
|
||||
|
||||
- (CGFloat)normalizeSizeWidthFactor:(OnScreenWidgetView* )widget{
|
||||
CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]);
|
||||
return widget.bounds.size.width/screenWidthInPoints * 10000;
|
||||
}
|
||||
|
||||
- (CGFloat)normalizeSizeHeightFactor:(OnScreenWidgetView* )widget{
|
||||
CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]);
|
||||
return widget.bounds.size.height/screenWidthInPoints * 10000;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Queries
|
||||
|
||||
@@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property NSString *alias;
|
||||
@property CGPoint position;
|
||||
@property (nonatomic, assign) BOOL isHidden;
|
||||
@property (nonatomic, assign) uint8_t slideMode;
|
||||
@property (nonatomic, assign) uint8_t buttonType;
|
||||
@property (nonatomic, assign) CGFloat widthFactor; // for OnScreenWidgetView
|
||||
@property (nonatomic, assign) CGFloat heightFactor; // for OnScreenWidgetView
|
||||
@@ -56,6 +57,13 @@ typedef NS_ENUM(NSInteger, MouseButtonAction) {
|
||||
rightButtonDown,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, ButtonSlideMode) {
|
||||
toggle,
|
||||
slideAndHold,
|
||||
disabled
|
||||
};
|
||||
|
||||
|
||||
|
||||
- (id) initWithButtonName:(NSString*)name buttonType:(uint8_t)buttonType andPosition:(CGPoint)position;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
[encoder encodeInt:self.buttonType forKey:@"buttonType"];
|
||||
[encoder encodeInt:self.vibrationStyle forKey:@"vibrationStyle"];
|
||||
[encoder encodeInt:self.mouseButtonAction forKey:@"mouseButtonAction"];
|
||||
[encoder encodeInt:self.slideMode forKey:@"slideMode"];
|
||||
[encoder encodeCGPoint:self.position forKey:@"position"];
|
||||
[encoder encodeBool:self.isHidden forKey:@"isHidden"];
|
||||
[encoder encodeFloat:self.widthFactor forKey:@"widthFactor"];
|
||||
@@ -57,6 +58,7 @@
|
||||
self.buttonType = [decoder decodeIntForKey:@"buttonType"];
|
||||
self.vibrationStyle = [decoder decodeIntForKey:@"vibrationStyle"];
|
||||
self.mouseButtonAction = [decoder decodeIntForKey:@"mouseButtonAction"];
|
||||
self.slideMode = [decoder containsValueForKey:@"slideMode"] ? [decoder decodeIntForKey:@"slideMode"] : 0;
|
||||
self.position = [decoder decodeCGPointForKey:@"position"];
|
||||
self.isHidden = [decoder decodeBoolForKey:@"isHidden"];
|
||||
self.widthFactor = [decoder decodeFloatForKey:@"widthFactor"];
|
||||
|
||||
@@ -53,7 +53,7 @@ static CGFloat screenWidthInPoints;
|
||||
} */
|
||||
|
||||
_lowestTouchPointHeight = screenHeightInPoints - lowestTouchPointYCoord;
|
||||
NSLog(@"gen _lowestTouchPointHeight %f markmark", _lowestTouchPointHeight);
|
||||
// NSLog(@"gen _lowestTouchPointHeight %f markmark", _lowestTouchPointHeight);
|
||||
if(_immediateTriggering){
|
||||
lowestTouchPointYCoord = 0.0; //reset for next recoginition
|
||||
self.state = UIGestureRecognizerStateRecognized;
|
||||
@@ -81,7 +81,7 @@ static CGFloat screenWidthInPoints;
|
||||
if((CACurrentMediaTime() - _gestureCapturedTime) < _tapDownTimeThreshold){
|
||||
lowestTouchPointYCoord = 0.0; //reset for next recognition
|
||||
self.state = UIGestureRecognizerStateRecognized;
|
||||
NSLog(@"gen _lowestTouchPointHeight %f markmark touchesEnd", _lowestTouchPointHeight);
|
||||
// NSLog(@"gen _lowestTouchPointHeight %f markmark touchesEnd", _lowestTouchPointHeight);
|
||||
}
|
||||
}
|
||||
if (allTouchesCount == [touches count]) _isOnScreenControllerBeingPressed = false; // need to reset this flag anyway, when all fingers are lefting
|
||||
|
||||
@@ -45,6 +45,11 @@ import UIKit
|
||||
@objc public var pressed: Bool
|
||||
@objc public var widthFactor: CGFloat = 1.0
|
||||
@objc public var heightFactor: CGFloat = 1.0
|
||||
@objc public var slideMode: Int = 0
|
||||
|
||||
@objc public var deNormalizedWidthFactor: CGFloat = 1.0
|
||||
@objc public var deNormalizedHeightFactor: CGFloat = 1.0
|
||||
|
||||
@objc public var borderWidth: CGFloat = 0.0
|
||||
@objc public var backgroundAlpha: CGFloat = 0.5
|
||||
@objc public var vibrationStyle: Int = 6
|
||||
@@ -131,8 +136,16 @@ import UIKit
|
||||
// border & visual effect
|
||||
private var minimumBorderAlpha: CGFloat = 0.19
|
||||
private var defaultBorderColor: CGColor = UIColor(white: 0.2, alpha: 0.3).cgColor
|
||||
private let moonlightPurple: CGColor = UIColor(red: 0.5, green: 0.5, blue: 1.0, alpha: 0.86).cgColor
|
||||
|
||||
private let voidlinkPurple: CGColor = UIColor(red: 0.5, green: 0.5, blue: 1.0, alpha: 0.86).cgColor
|
||||
|
||||
//slide buttons
|
||||
private var capturedTouches: NSMutableSet
|
||||
private let noTouch: UITouch = UITouch()
|
||||
|
||||
//controller touch pad
|
||||
private var pointerIdPool: Set<UInt32>
|
||||
private var pointerIdDict: Dictionary<ObjectIdentifier, UInt32>
|
||||
private var activePointerIds: Set<UInt32>
|
||||
|
||||
// whole button press down visual effect
|
||||
@objc public let buttonDownVisualEffectLayer = CAShapeLayer()
|
||||
@@ -180,6 +193,8 @@ import UIKit
|
||||
self.comboButtonStrings = ["OSCL3"]
|
||||
case "RSPAD", "RSVPAD":
|
||||
self.comboButtonStrings = ["OSCR3"]
|
||||
case "DS4TOUCH":
|
||||
self.comboButtonStrings = ["DS4TOUCH"]
|
||||
default: break
|
||||
}
|
||||
}
|
||||
@@ -223,6 +238,13 @@ import UIKit
|
||||
self.stickIndicatorOffset = 95
|
||||
self.sensitivityFactorX = 1.0
|
||||
self.sensitivityFactorY = 1.0
|
||||
self.capturedTouches = NSMutableSet()
|
||||
self.pointerIdDict = [:]
|
||||
self.pointerIdPool = []
|
||||
for i in 0...10 { // iPadOS supports up to 11 finger touches
|
||||
self.pointerIdPool.insert(UInt32(i))
|
||||
}
|
||||
self.activePointerIds = []
|
||||
super.init(frame: .zero)
|
||||
|
||||
upIndicator = createLrudDirectionLayer()
|
||||
@@ -319,7 +341,6 @@ import UIKit
|
||||
if self.widthFactor == 0 {self.widthFactor = 1.0}
|
||||
if self.heightFactor == 0 {self.heightFactor = 1.0}
|
||||
|
||||
|
||||
/*
|
||||
NSLayoutConstraint.activate([
|
||||
self.centerXAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: storedLocation.x),
|
||||
@@ -357,21 +378,46 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
func nearestEven(_ value: CGFloat) -> CGFloat {
|
||||
let rounded = round(value)
|
||||
if Int(rounded) % 2 == 0 {
|
||||
return rounded
|
||||
} else {
|
||||
let lowerEven = rounded - 1
|
||||
let upperEven = rounded + 1
|
||||
return abs(value - lowerEven) <= abs(value - upperEven) ? lowerEven : upperEven
|
||||
}
|
||||
}
|
||||
|
||||
private func denormalizeSize(sizeFactor:CGFloat) -> CGFloat {
|
||||
let screenWidthInPoints = UIScreen.main.bounds.width
|
||||
// return CGFloat(Int(sizeFactor/10000*screenWidthInPoints/2)*2);
|
||||
return nearestEven(sizeFactor/10000*screenWidthInPoints);
|
||||
}
|
||||
|
||||
private func changeAndActivateContraints(){
|
||||
let isNormalizedSizeFactor = self.widthFactor > 6;
|
||||
|
||||
if self.shape == "round"{ // we'll make custom osc buttons round & smaller
|
||||
NSLayoutConstraint.activate([
|
||||
self.widthAnchor.constraint(equalToConstant: CGFloat(Int(60 * self.widthFactor / 2) * 2)),
|
||||
self.heightAnchor.constraint(equalToConstant: CGFloat(Int(60 * self.widthFactor / 2) * 2)),])
|
||||
self.widthAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(60 * self.widthFactor / 2) * 2)),
|
||||
self.heightAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(60 * self.widthFactor / 2) * 2)),])
|
||||
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/60 : self.widthFactor;
|
||||
self.deNormalizedHeightFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/60 : self.widthFactor;
|
||||
}
|
||||
if self.shape == "square" {
|
||||
NSLayoutConstraint.activate([
|
||||
self.widthAnchor.constraint(equalToConstant: CGFloat(Int(70 * self.widthFactor / 2) * 2)),
|
||||
self.heightAnchor.constraint(equalToConstant: CGFloat(Int(65 * self.heightFactor / 2) * 2)),])
|
||||
self.widthAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(70 * self.widthFactor / 2) * 2)),
|
||||
self.heightAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(65 * self.heightFactor / 2) * 2)),])
|
||||
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/70 : self.widthFactor;
|
||||
self.deNormalizedHeightFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.heightFactor)/65 : self.heightFactor;
|
||||
}
|
||||
if self.shape == "largeSquare" { // override all shape strings
|
||||
NSLayoutConstraint.activate([
|
||||
self.widthAnchor.constraint(equalToConstant: CGFloat(Int(170 * self.widthFactor / 2) * 2)),
|
||||
self.heightAnchor.constraint(equalToConstant: CGFloat(Int(150 * self.heightFactor / 2) * 2)),])
|
||||
self.widthAnchor.constraint(equalToConstant:isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(170 * self.widthFactor / 2) * 2)),
|
||||
self.heightAnchor.constraint(equalToConstant:isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(150 * self.heightFactor / 2) * 2)),])
|
||||
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/170 : self.widthFactor;
|
||||
self.deNormalizedHeightFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.heightFactor)/150 : self.heightFactor;
|
||||
}
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
@@ -379,6 +425,11 @@ import UIKit
|
||||
label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10),
|
||||
label.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
label.centerYAnchor.constraint(equalTo: centerYAnchor),])
|
||||
|
||||
if self.shape != "round"{
|
||||
let shortSideLen = min(self.layer.bounds.size.width, self.layer.bounds.size.height)
|
||||
self.layer.cornerRadius = shortSideLen/2 < 16 ? shortSideLen/3.2 : 16
|
||||
}
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
@@ -464,7 +515,7 @@ import UIKit
|
||||
indicatorBorder.fillColor = UIColor.clear.cgColor
|
||||
let path = UIBezierPath(roundedRect: indicatorBorder.bounds, cornerRadius: indicatorBorder.cornerRadius)
|
||||
indicatorBorder.path = path.cgPath
|
||||
indicatorBorder.borderColor = moonlightPurple
|
||||
indicatorBorder.borderColor = voidlinkPurple
|
||||
|
||||
self.layer.superlayer?.addSublayer(indicatorBorder)
|
||||
indicatorBorder.position = CGPointMake(CGRectGetMinX(self.frame)+touchBeganLocation.x, CGRectGetMinY(self.frame)+touchBeganLocation.y)
|
||||
@@ -658,7 +709,7 @@ import UIKit
|
||||
indicatorBorder.fillColor = UIColor.clear.cgColor
|
||||
let path = UIBezierPath(roundedRect: indicatorBorder.bounds, cornerRadius: indicatorBorder.cornerRadius)
|
||||
indicatorBorder.path = path.cgPath
|
||||
indicatorBorder.borderColor = moonlightPurple
|
||||
indicatorBorder.borderColor = voidlinkPurple
|
||||
|
||||
return indicatorBorder
|
||||
}
|
||||
@@ -668,7 +719,15 @@ import UIKit
|
||||
self.layer.superlayer?.insertSublayer(indicatorLayer, below: self.layer)
|
||||
|
||||
// show the indicator based on the touchBeganLocation
|
||||
indicatorLayer.position = CGPointMake(CGRectGetMinX(self.frame)+touchBeganLocation.x, CGRectGetMinY(self.frame)+touchBeganLocation.y)
|
||||
let newPosition = CGPointMake(CGRectGetMinX(self.frame)+touchBeganLocation.x, CGRectGetMinY(self.frame)+touchBeganLocation.y)
|
||||
|
||||
if indicatorLayer.position != newPosition && vibrationOn {
|
||||
vibrationGenerator.prepare()
|
||||
vibrationGenerator.impactOccurred()
|
||||
// print("vibrationInstance: \(vibrationGenerator)")
|
||||
}
|
||||
|
||||
indicatorLayer.position = newPosition
|
||||
}
|
||||
|
||||
private func handleLrudTouchMove(){
|
||||
@@ -718,6 +777,7 @@ import UIKit
|
||||
}
|
||||
else{
|
||||
self.upIndicator.removeFromSuperlayer()
|
||||
self.upIndicator.position = CGPointMake(0, 0)
|
||||
switch touchPadString {
|
||||
case "WASDPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["W"]!,Int8(KEY_ACTION_UP), 0)
|
||||
case "ARROWPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["UP_ARROW"]!,Int8(KEY_ACTION_UP), 0)
|
||||
@@ -736,6 +796,7 @@ import UIKit
|
||||
}
|
||||
else{
|
||||
self.downIndicator.removeFromSuperlayer()
|
||||
self.downIndicator.position = CGPointMake(0, 0)
|
||||
switch touchPadString {
|
||||
case "WASDPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["S"]!,Int8(KEY_ACTION_UP), 0)
|
||||
case "ARROWPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["DOWN_ARROW"]!,Int8(KEY_ACTION_UP), 0)
|
||||
@@ -754,6 +815,7 @@ import UIKit
|
||||
}
|
||||
else{
|
||||
self.leftIndicator.removeFromSuperlayer()
|
||||
self.leftIndicator.position = CGPointMake(0, 0)
|
||||
switch touchPadString {
|
||||
case "WASDPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["A"]!,Int8(KEY_ACTION_UP), 0)
|
||||
case "ARROWPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["LEFT_ARROW"]!,Int8(KEY_ACTION_UP), 0)
|
||||
@@ -772,6 +834,7 @@ import UIKit
|
||||
}
|
||||
else{
|
||||
self.rightIndicator.removeFromSuperlayer()
|
||||
self.rightIndicator.position = CGPointMake(0, 0)
|
||||
switch touchPadString {
|
||||
case "WASDPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["D"]!,Int8(KEY_ACTION_UP), 0)
|
||||
case "ARROWPAD": LiSendKeyboardEvent(CommandManager.keyboardButtonMappings["RIGHT_ARROW"]!,Int8(KEY_ACTION_UP), 0)
|
||||
@@ -853,14 +916,14 @@ import UIKit
|
||||
|
||||
|
||||
//==== wholeButtonPress visual effect=============================================
|
||||
private func buttonDownEffect() {
|
||||
// setupBorderLayer()
|
||||
private func handleButtonDown() {
|
||||
if !OnScreenWidgetView.editMode {self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)}
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
// self.layer.borderWidth = 0
|
||||
buttonDownVisualEffectLayer.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) // update position every time we press down the button
|
||||
buttonDownVisualEffectLayer.borderWidth = self.buttonDownVisualEffectWidth // this will show the visual effect
|
||||
buttonDownVisualEffectLayer.borderColor = moonlightPurple
|
||||
buttonDownVisualEffectLayer.borderColor = voidlinkPurple
|
||||
if vibrationOn {
|
||||
vibrationGenerator.prepare()
|
||||
vibrationGenerator.impactOccurred()
|
||||
@@ -869,7 +932,8 @@ import UIKit
|
||||
CATransaction.commit()
|
||||
}
|
||||
|
||||
private func buttonUpVisualEffect() {
|
||||
private func handlebuttonUp() {
|
||||
if !OnScreenWidgetView.editMode {self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings)}
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
// self.layer.borderWidth = 1
|
||||
@@ -882,7 +946,7 @@ import UIKit
|
||||
private func setupButtonDownVisualEffectLayer() {
|
||||
self.buttonDownVisualEffectWidth = 8
|
||||
if self.shape == "round" {
|
||||
if widthFactor < 1.3 {self.buttonDownVisualEffectWidth = 15.3} // wider visual effect for osc buttons
|
||||
if deNormalizedWidthFactor < 1.3 {self.buttonDownVisualEffectWidth = 15.3} // wider visual effect for osc buttons
|
||||
else {self.buttonDownVisualEffectWidth = 9}
|
||||
}
|
||||
|
||||
@@ -1008,11 +1072,11 @@ import UIKit
|
||||
//==============================================================================
|
||||
// Touch event handling
|
||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
|
||||
self.touchBegan = true
|
||||
self.firstTouchMoved = false
|
||||
super.touchesBegan(touches, with: event)
|
||||
self.isMultipleTouchEnabled = self.touchPadString == "MOUSEPAD" // only enable multi-touch in mousePad mode
|
||||
// self.isMultipleTouchEnabled = self.touchPadString == "MOUSEPAD" // only enable multi-touch in mousePad mode
|
||||
self.isMultipleTouchEnabled = true
|
||||
|
||||
if !OnScreenWidgetView.editMode && self.touchPadString == "TRACKBALL" {
|
||||
stopTrackballMomentum()
|
||||
@@ -1073,6 +1137,11 @@ import UIKit
|
||||
self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings)
|
||||
}
|
||||
}
|
||||
case "DS4TOUCH":
|
||||
if quickDoubleTapDetected {
|
||||
self.l3r3Indicator = self.createAndShowl3r3Indicator()
|
||||
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -1093,25 +1162,15 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if !self.buttonString.isEmpty {
|
||||
// if there's no "+" in the keystring, treat it as a regular button:
|
||||
if CommandManager.oscButtonMappings.keys.contains(self.cmdString) {
|
||||
self.sendOscButtonDownEvent(keyString: self.cmdString)
|
||||
}
|
||||
if CommandManager.keyboardButtonMappings.keys.contains(self.cmdString) {
|
||||
LiSendLiSendKeyboardEvent(CommandManager.keyboardButtonMappings[self.cmdString]!,Int8(KEY_ACTION_DOWN), 0)
|
||||
}
|
||||
if CommandManager.mouseButtonMappings.keys.contains(self.cmdString) {
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), Int32(CommandManager.mouseButtonMappings[self.cmdString]!))
|
||||
}
|
||||
if self.widgetType == WidgetTypeEnum.touchPad && self.touchPadString == "DS4TOUCH" {
|
||||
self.handleControllerTouchesDown(touches: touches)
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// this will also deal with button events
|
||||
if self.widgetType == WidgetTypeEnum.button && !self.comboButtonStrings.isEmpty {
|
||||
self.buttonDownEffect()
|
||||
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)
|
||||
self.handleButtonDown()
|
||||
self.capturedTouches.union(touches)
|
||||
//self.handleButtonSliding(touches: touches)
|
||||
}
|
||||
|
||||
// legacy keyboard button combo connected by "+"
|
||||
@@ -1119,13 +1178,13 @@ import UIKit
|
||||
let keyboardCmdStrings = CommandManager.shared.extractKeyStringsFromComboCommand(from: self.cmdString)!
|
||||
CommandManager.shared.sendKeyComboCommand(keyboardCmdStrings: keyboardCmdStrings) // send multi-key command
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.03) { // reset shadow color immediately 50ms later
|
||||
self.buttonUpVisualEffect()
|
||||
self.handlebuttonUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
// here is in edit mode:
|
||||
else{
|
||||
self.buttonDownEffect()
|
||||
self.handleButtonDown()
|
||||
NotificationCenter.default.post(name: Notification.Name("OnScreenWidgetViewSelected"),object: self) // inform layout tool controller to fetch button size factors. self will be passed as the object of the notification
|
||||
}
|
||||
}
|
||||
@@ -1151,16 +1210,100 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
private func handleControllerTouchesDown(touches: Set<UITouch>) {
|
||||
for touch in touches{
|
||||
let availablePointerIds = pointerIdPool.subtracting(activePointerIds)
|
||||
if let pointerId = availablePointerIds.first {
|
||||
pointerIdDict[ObjectIdentifier(touch)] = pointerId
|
||||
let coordX = touch.location(in: self).x/self.bounds.width
|
||||
let coordY = touch.location(in: self).y/self.bounds.height
|
||||
LiSendControllerTouchEvent(0, UInt8(LI_TOUCH_EVENT_DOWN), pointerId, Float(coordX), Float(coordY), 1)
|
||||
activePointerIds.insert(pointerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleControllerTouchesMove(touches: Set<UITouch>) {
|
||||
for touch in touches{
|
||||
if let pointerId = pointerIdDict[ObjectIdentifier(touch)] {
|
||||
let coordX = touch.location(in: self).x/self.bounds.width
|
||||
let coordY = touch.location(in: self).y/self.bounds.height
|
||||
LiSendControllerTouchEvent(0, UInt8(LI_TOUCH_EVENT_MOVE), pointerId, Float(coordX), Float(coordY), 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleControllerTouchesUp(touches: Set<UITouch>) {
|
||||
for touch in touches{
|
||||
if let pointerId = pointerIdDict[ObjectIdentifier(touch)] {
|
||||
let coordX = touch.location(in: self).x/self.bounds.width
|
||||
let coordY = touch.location(in: self).y/self.bounds.height
|
||||
LiSendControllerTouchEvent(0, UInt8(LI_TOUCH_EVENT_UP), pointerId, Float(coordX), Float(coordY), 1)
|
||||
activePointerIds.remove(pointerId)
|
||||
pointerIdDict.removeValue(forKey: ObjectIdentifier(touch))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func handleButtonSlidingUp(touches: Set<UITouch>) {
|
||||
for touch in touches {
|
||||
for subview in self.superview?.subviews ?? [] {
|
||||
if let widget = subview as? OnScreenWidgetView{
|
||||
if !widget.capturedTouches.contains(touch) || widget.slideMode == ButtonSlideMode.disabled.rawValue {continue}
|
||||
widget.handlebuttonUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleButtonSliding(touches: Set<UITouch>) {
|
||||
for touch in touches {
|
||||
let locationInSuperView = touch.location(in: self.superview)
|
||||
for subview in self.superview?.subviews ?? [] {
|
||||
if let widget = subview as? OnScreenWidgetView{
|
||||
if widget.widgetType != WidgetTypeEnum.button {continue}
|
||||
let pointInSubview = widget.convert(locationInSuperView, from: self.superview)
|
||||
if widget.bounds.contains(pointInSubview){
|
||||
if widget.capturedTouches.contains(touch) || widget.slideMode == ButtonSlideMode.disabled.rawValue {continue}
|
||||
widget.capturedTouches.add(touch)
|
||||
widget.handleButtonDown()
|
||||
// print("UIButton: \(widget.buttonLabel) in, \(widget.touchPadString), \(CACurrentMediaTime())")
|
||||
}
|
||||
else{
|
||||
if !widget.capturedTouches.contains(touch) || widget.slideMode == ButtonSlideMode.disabled.rawValue {continue}
|
||||
// print("UIButton: \(widget.buttonLabel) out test, \(widget.touchPadString), \(CACurrentMediaTime())")
|
||||
if(widget.slideMode == ButtonSlideMode.toggle.rawValue){
|
||||
widget.capturedTouches.remove(touch)
|
||||
widget.handlebuttonUp()
|
||||
}
|
||||
if(widget.slideMode == ButtonSlideMode.slideAndHold.rawValue){
|
||||
// do nothing here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesMoved(touches, with: event)
|
||||
if !OnScreenWidgetView.editMode {
|
||||
handleTouchPadMoveEvent(touches, with: event)
|
||||
|
||||
if !self.touchPadString.isEmpty{
|
||||
handleTouchPadMoveEvent(touches, with: event)
|
||||
}
|
||||
|
||||
if !self.buttonString.isEmpty{
|
||||
if self.slideMode != ButtonSlideMode.disabled.rawValue {self.handleButtonSliding(touches: touches)}
|
||||
}
|
||||
|
||||
if CommandManager.specialOverlayButtonCmds.contains(self.cmdString){
|
||||
if let touch = touches.first {
|
||||
NSLog("touchTapTimeStamp %f", self.touchTapTimeStamp)
|
||||
if CACurrentMediaTime() - self.touchTapTimeStamp > 0.3 { // temporarily relocate special buttons
|
||||
self.moveByTouch(touch: touch)
|
||||
self.buttonUpVisualEffect()
|
||||
self.handlebuttonUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1195,7 +1338,6 @@ import UIKit
|
||||
|
||||
private func handleTouchPadMoveEvent (_ touches: Set<UITouch>, with event: UIEvent?){
|
||||
if touches.count == 1{ // don't use event.alltouches.count here, it will counts all touches
|
||||
|
||||
switch self.touchPadString{
|
||||
case "MOUSEPAD":
|
||||
DispatchQueue.global(qos: .userInteractive).async {
|
||||
@@ -1240,6 +1382,9 @@ import UIKit
|
||||
break
|
||||
}
|
||||
}
|
||||
if self.widgetType == WidgetTypeEnum.touchPad && self.touchPadString == "DS4TOUCH" {
|
||||
self.handleControllerTouchesMove(touches: touches)
|
||||
}
|
||||
}
|
||||
|
||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
@@ -1320,6 +1465,8 @@ import UIKit
|
||||
self.onScreenControls.releaseControllerButton(RIGHT_FLAG)
|
||||
self.onScreenControls.releaseControllerButton(UP_FLAG)
|
||||
self.onScreenControls.releaseControllerButton(DOWN_FLAG)
|
||||
case "DS4TOUCH":
|
||||
self.handleControllerTouchesUp(touches: touches)
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -1332,7 +1479,8 @@ import UIKit
|
||||
self.lrudIndicatorBall.removeFromSuperlayer()
|
||||
|
||||
if !OnScreenWidgetView.editMode && !self.cmdString.contains("+") && !self.comboButtonStrings.isEmpty { // if the command(keystring contains "+", it's a legacy multi-key command
|
||||
self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings)
|
||||
self.handleButtonSlidingUp(touches: touches)
|
||||
self.capturedTouches.minus(touches)
|
||||
}
|
||||
|
||||
if !OnScreenWidgetView.editMode && CommandManager.specialOverlayButtonCmds.contains(self.cmdString){
|
||||
@@ -1384,7 +1532,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
self.buttonUpVisualEffect()
|
||||
self.handlebuttonUp()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
|
||||
}*/
|
||||
|
||||
- (BOOL)isAdjacentTouches:(CGPoint)currentPoint from:(CGPoint)originalPoint {
|
||||
return hypotf(originalPoint.x - currentPoint.x, originalPoint.y - currentPoint.y) <= 100;
|
||||
return hypotf(originalPoint.x - currentPoint.x, originalPoint.y - currentPoint.y) <= 300;
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
|
||||
// we must use [event allTouches] to check if touchLockedForMouseMove is captured, because the UITouch object could be captured by upper layer of UIView(in cases like tap gestures), not passed to the touches callbacks in this class, but still available in [event allTouches]
|
||||
if(candidateTouch != nil && ![[event allTouches] containsObject:touchLockedForMouseMove]){
|
||||
touchLockedForMouseMove = candidateTouch;
|
||||
NSLog(@"Candidate touch for mouse movement locked");
|
||||
// NSLog(@"Candidate touch for mouse movement locked");
|
||||
mousePointerTimestamp = CACurrentMediaTime();
|
||||
initialMousePointerLocation = latestMousePointerLocation = [touchLockedForMouseMove locationInView:streamView];
|
||||
}
|
||||
@@ -278,7 +278,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
|
||||
if(!self->quickTapDetected){
|
||||
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||
}
|
||||
else NSLog(@"Left mouse button release cancelled, keep pressing down, turning into dragging...");
|
||||
// else NSLog(@"Left mouse button release cancelled, keep pressing down, turning into dragging...");
|
||||
|
||||
// do not release the button if we're still dragging, this will prevent the dragging from being interrupted.
|
||||
});
|
||||
|
||||
@@ -234,12 +234,12 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
}
|
||||
|
||||
- (void)keyboardWillShow:(NSNotification *)notification{
|
||||
NSLog(@"keyboard will show markmark %f", CACurrentMediaTime());
|
||||
// NSLog(@"keyboard will show markmark %f", CACurrentMediaTime());
|
||||
if(settings.liftStreamViewForKeyboard && !isInputingText){
|
||||
NSDictionary *userInfo = notification.userInfo;
|
||||
// Get the keyboard size from the notification
|
||||
CGRect keyboardFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
||||
NSLog(@"keyboard will show markmark, lowest height %f", keyboardToggleRecognizer.lowestTouchPointHeight);
|
||||
// NSLog(@"keyboard will show markmark, lowest height %f", keyboardToggleRecognizer.lowestTouchPointHeight);
|
||||
if(keyboardFrame.size.height < CGRectGetHeight([[UIScreen mainScreen] bounds]) * 0.25) return; // return in case of abnormal keyboard height
|
||||
HeightViewLiftedTo = keyboardFrame.size.height - keyboardToggleRecognizer.lowestTouchPointHeight + CGRectGetHeight([[UIScreen mainScreen] bounds]) * 0.1; // lift the StreamView to the height of lowest touch point of multi-finger tap gesture, while reserving the view of 1/10 screen height for remote typing.
|
||||
if(HeightViewLiftedTo < 0) HeightViewLiftedTo = 0; // set HeightViewLiftedTo to 0 if it is high enough and not going to be covered by keyboard.
|
||||
@@ -259,7 +259,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
|
||||
// this method also deals with recovering streamview when local keyboard is turned off
|
||||
- (void)keyboardWillHide{
|
||||
NSLog(@"keyboard will hide markmark %f", CACurrentMediaTime());
|
||||
// NSLog(@"keyboard will hide markmark %f", CACurrentMediaTime());
|
||||
|
||||
keyboardToggleRecognizer.numberOfTouchesRequired = settings.keyboardToggleFingers.intValue; // reset this number
|
||||
if(isInputingText){
|
||||
@@ -325,7 +325,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
|
||||
|
||||
- (void)toggleKeyboard{
|
||||
NSLog(@"toggleKeyboard markmark, %d", isInputingText);
|
||||
// NSLog(@"toggleKeyboard markmark, %d", isInputingText);
|
||||
if (isInputingText) {
|
||||
Log(LOG_D, @"Closing the keyboard");
|
||||
[keyInputField resignFirstResponder];
|
||||
@@ -499,6 +499,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
widgetView.trackballDecelerationRate = buttonState.decelerationRate;
|
||||
widgetView.stickIndicatorOffset = buttonState.stickIndicatorOffset;
|
||||
widgetView.minStickOffset = buttonState.minStickOffset;
|
||||
widgetView.slideMode = buttonState.slideMode;
|
||||
// Add the widgetView to the view controller's view
|
||||
[self->streamFrameTopLayerView addSubview:widgetView]; // add keyboard button to the stream frame view. must add it to the target view before setting location.
|
||||
buttonState.position = [self denormalizeWidgetPosition:buttonState.position];
|
||||
|
||||
@@ -93,6 +93,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (strong, nonatomic) IBOutlet UIStackView *mouseDownButtonStack;
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *mouseButtonDownSelector;
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UIStackView *slidableStack;
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *slidableSelector;
|
||||
|
||||
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIStackView *widgetPanelStack;
|
||||
|
||||
+31
-5
@@ -123,6 +123,7 @@
|
||||
widgetView.trackballDecelerationRate = buttonState.decelerationRate;
|
||||
widgetView.stickIndicatorOffset = buttonState.stickIndicatorOffset;
|
||||
widgetView.minStickOffset = buttonState.minStickOffset;
|
||||
widgetView.slideMode = buttonState.slideMode;
|
||||
// Add the widgetView to the view controller's view
|
||||
[self.view insertSubview:widgetView belowSubview:self.widgetPanelStack];
|
||||
buttonState.position = [self denormalizeWidgetPosition:buttonState.position];
|
||||
@@ -634,6 +635,7 @@
|
||||
newWidget.minStickOffset = [widgetInitParams[@"minStickOffsetString"] floatValue];
|
||||
[newWidget setVibrationWithStyle:widget.vibrationStyle];
|
||||
newWidget.mouseButtonAction = widget.mouseButtonAction;
|
||||
newWidget.slideMode = widget.slideMode;
|
||||
[self.view insertSubview:newWidget belowSubview:self.widgetPanelStack];
|
||||
|
||||
if(createNew) [newWidget setLocationWithPosition:CGPointMake(90, 130)];
|
||||
@@ -714,6 +716,13 @@
|
||||
[self->selectedWidgetView.crossMarkLayer removeFromSuperlayer];
|
||||
}
|
||||
|
||||
/*
|
||||
- (CGFloat)denormalizeSizeFactor:(CGFloat)sizeFactor{
|
||||
bool isNormalizedSizeFactor = sizeFactor > 6;
|
||||
return isNormalizedSizeFactor ? sizeFactor/10000*[UIScreen mainScreen].bounds.size.width
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)widgetViewTapped: (NSNotification *)notification{
|
||||
//self.undoButton.alpha = selectedWidgetView.layoutChanges.count>1 && !CGPointEqualToPoint(selectedWidgetView.layoutChanges.lastObject.CGPointValue, selectedWidgetView.initialCenter)? 1.0 : 0.3;
|
||||
|
||||
@@ -738,11 +747,14 @@
|
||||
|
||||
[self.layoutOSC updateGuidelinesForOnScreenWidget:self->selectedWidgetView]; // shows guideline immediately when widget is tapped
|
||||
// setup slider values
|
||||
[self.widgetSizeSlider setValue: self->selectedWidgetView.widthFactor];
|
||||
[self.widgetHeightSlider setValue: self->selectedWidgetView.heightFactor];
|
||||
[self.widgetSizeSlider setValue: self->selectedWidgetView.deNormalizedWidthFactor];
|
||||
[self.widgetHeightSlider setValue: self->selectedWidgetView.deNormalizedHeightFactor];
|
||||
[self.widgetAlphaSlider setValue: self->selectedWidgetView.backgroundAlpha];
|
||||
[self.widgetBorderWidthSlider setValue:self->selectedWidgetView.borderWidth];
|
||||
|
||||
self.slidableStack.hidden = selectedWidgetView.widgetType != WidgetTypeEnumButton;
|
||||
[self.slidableSelector setSelectedSegmentIndex:selectedWidgetView.slideMode];
|
||||
|
||||
bool showSensitivityFactorStack = selectedWidgetView.hasSensitivityTweak;
|
||||
bool showStickIndicatorOffsetStack = selectedWidgetView.hasStickIndicator;
|
||||
|
||||
@@ -772,10 +784,12 @@
|
||||
[self->selectedWidgetView updateStickIndicator];
|
||||
}
|
||||
[self autoFitLabel:self.widgetSizeLabel];
|
||||
[self.widgetSizeLabel setText:[LocalizationHelper localizedStringForKey:@"Size: %.2f", self->selectedWidgetView.widthFactor]];
|
||||
|
||||
|
||||
[self.widgetSizeLabel setText:[LocalizationHelper localizedStringForKey:@"Size: %.2f", self->selectedWidgetView.deNormalizedWidthFactor]];
|
||||
|
||||
[self autoFitLabel:self.widgetHeightLabel];
|
||||
[self.widgetHeightLabel setText:[LocalizationHelper localizedStringForKey:@"Height: %.2f", self->selectedWidgetView.heightFactor]];
|
||||
[self.widgetHeightLabel setText:[LocalizationHelper localizedStringForKey:@"Height: %.2f", self->selectedWidgetView.deNormalizedHeightFactor]];
|
||||
|
||||
[self autoFitLabel:self.widgetAlphaLabel];
|
||||
[self.widgetAlphaLabel setText:[LocalizationHelper localizedStringForKey:@"Alpha: %.2f", self->selectedWidgetView.backgroundAlpha]];
|
||||
@@ -797,6 +811,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)legacyOscLayerTapped: (NSNotification *)notification{
|
||||
[self enableCommonWidgetTools];
|
||||
CALayer* controllerLayer = (CALayer* )notification.object;
|
||||
@@ -891,6 +906,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)slideModeChanged:(UISegmentedControl* )sender{
|
||||
if(self->selectedWidgetView != nil && self->widgetViewSelected){
|
||||
selectedWidgetView.slideMode = _slidableSelector.selectedSegmentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)vibrationStyleChanged:(UISegmentedControl* )sender{
|
||||
bool vibraiontOn;
|
||||
if (@available(iOS 13.0, *)) {
|
||||
@@ -1036,13 +1057,18 @@
|
||||
self.stickIndicatorOffsetLabel.text = [LocalizationHelper localizedStringForKey:@"Indicator Offset"];
|
||||
self.stickIndicatorOffsetStack.hidden = YES;
|
||||
|
||||
[self.mouseButtonDownSelector addTarget:self action:@selector(mouseDownButtonChanged:) forControlEvents:(UIControlEventValueChanged)];
|
||||
NSDictionary *whiteFontAttributes = @{
|
||||
NSForegroundColorAttributeName: [UIColor whiteColor]
|
||||
};
|
||||
|
||||
[self.mouseButtonDownSelector addTarget:self action:@selector(mouseDownButtonChanged:) forControlEvents:(UIControlEventValueChanged)];
|
||||
[self.mouseButtonDownSelector setTitleTextAttributes:whiteFontAttributes forState:UIControlStateNormal];
|
||||
self.mouseDownButtonStack.hidden = YES;
|
||||
|
||||
[self.slidableSelector addTarget:self action:@selector(slideModeChanged:) forControlEvents:(UIControlEventValueChanged)];
|
||||
[self.slidableSelector setTitleTextAttributes:whiteFontAttributes forState:UIControlStateNormal];
|
||||
self.slidableStack.hidden = YES;
|
||||
|
||||
|
||||
if([self isIPhone]){
|
||||
[self.vibrationStyleSelector addTarget:self action:@selector(vibrationStyleChanged:) forControlEvents:(UIControlEventValueChanged)];
|
||||
|
||||
@@ -1918,7 +1918,7 @@ static NSMutableSet* hostList;
|
||||
}
|
||||
|
||||
- (void)updateHosts {
|
||||
Log(LOG_I, @"Updating hosts %f", CACurrentMediaTime());
|
||||
// Log(LOG_I, @"Updating hosts %f", CACurrentMediaTime());
|
||||
@synchronized (hostList) {
|
||||
// Sort the host list in alphabetical order
|
||||
NSArray* sortedHostList = [[hostList allObjects] sortedArrayUsingSelector:@selector(compareName:)];
|
||||
|
||||
@@ -1598,9 +1598,7 @@ BOOL isCustomResolution(int resolutionSelected) {
|
||||
}
|
||||
|
||||
[self findDynamicLabelFromStack:self.onScreenWidgetStack].text = [self isCustomOswEnabled] ? [LocalizationHelper localizedStringForKey:@"%d finger tap", self->oswLayoutFingers] : @"";
|
||||
//markmark
|
||||
[self handleOswGestureChange];
|
||||
}];
|
||||
[self handleOswGestureChange];}];
|
||||
|
||||
[alertController addAction:cancelAction];
|
||||
[alertController addAction:okAction];
|
||||
|
||||
@@ -1442,7 +1442,7 @@
|
||||
}
|
||||
|
||||
- (BOOL)prefersHomeIndicatorAutoHidden {
|
||||
if ( [_streamView getCurrentOscState] == OnScreenControlsLevelOff &&
|
||||
if ( [_controllerSupport getConnectedGamepadCount] > 0 && [_streamView getCurrentOscState] == OnScreenControlsLevelOff &&
|
||||
_userIsInteracting == NO) {
|
||||
// Autohide the home bar when a gamepad is connected
|
||||
// and the on-screen controls are disabled. We can't
|
||||
|
||||
@@ -1099,6 +1099,96 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cKS-fy-Zpg.segmentTitles[0]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; cKS-fy-Zpg.segmentTitles[0] = \"toggle\"; ObjectID = \"cKS-fy-Zpg\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "toggle"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑出时松开"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑出時鬆開"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑出時鬆開"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cKS-fy-Zpg.segmentTitles[1]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; cKS-fy-Zpg.segmentTitles[1] = \"slide & hold\"; ObjectID = \"cKS-fy-Zpg\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "slide & hold"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑动时按下"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑動時按下"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑動時按下"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cKS-fy-Zpg.segmentTitles[2]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; cKS-fy-Zpg.segmentTitles[2] = \"disabled\"; ObjectID = \"cKS-fy-Zpg\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "disabled"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "关闭"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "關閉"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "關閉\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"CpY-Sb-BDc.title" : {
|
||||
"comment" : "Class = \"UIBarButtonItem\"; title = \"Import\"; ObjectID = \"CpY-Sb-BDc\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
@@ -1201,6 +1291,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dOF-FW-cBU.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \" \"; ObjectID = \"dOF-FW-cBU\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : " "
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dpd-Bw-aHE.segmentTitles[0]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; dpd-Bw-aHE.segmentTitles[0] = \"No\"; ObjectID = \"dpd-Bw-aHE\";",
|
||||
"extractionState" : "stale",
|
||||
@@ -2797,6 +2899,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"qNQ-fB-jhY.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Slide Activated\"; ObjectID = \"qNQ-fB-jhY\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "Slide Activated"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑动触发"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑動觸發"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑動觸發"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Qs9-iS-YoW.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Divider Position\"; ObjectID = \"Qs9-iS-YoW\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
|
||||
@@ -1783,6 +1783,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"KZ3-vJ-E8J.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \" \"; ObjectID = \"KZ3-vJ-E8J\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : " "
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lwy-Nu-hQj.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"External Display Mode\"; ObjectID = \"lwy-Nu-hQj\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
@@ -1975,6 +1987,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"o9I-Gt-YRd.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Slide Activated\"; ObjectID = \"o9I-Gt-YRd\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "Slide Activated"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑动触发"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑動觸發"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑動觸發"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"oBs-zz-ZQv.segmentTitles[0]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; oBs-zz-ZQv.segmentTitles[0] = \"Slide From Left Edge\"; ObjectID = \"oBs-zz-ZQv\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
@@ -2035,6 +2077,96 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ojp-aS-m8w.segmentTitles[0]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; ojp-aS-m8w.segmentTitles[0] = \"toggle\"; ObjectID = \"ojp-aS-m8w\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "toggle"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑出时松开"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑出時鬆開"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑出時鬆開"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ojp-aS-m8w.segmentTitles[1]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; ojp-aS-m8w.segmentTitles[1] = \"slide & hold\"; ObjectID = \"ojp-aS-m8w\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "slide & hold"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑动时按下"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑動時按下"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "滑動時按下"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ojp-aS-m8w.segmentTitles[2]" : {
|
||||
"comment" : "Class = \"UISegmentedControl\"; ojp-aS-m8w.segmentTitles[2] = \"disabled\"; ObjectID = \"ojp-aS-m8w\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "disabled"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "关闭"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "關閉"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "關閉"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ozU-7C-qKE.text" : {
|
||||
"comment" : "Class = \"UILabel\"; text = \"Button Down\"; ObjectID = \"ozU-7C-qKE\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
|
||||
Reference in New Issue
Block a user