diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..d1e2c3b1 Binary files /dev/null and b/.DS_Store differ diff --git a/Limelight/Base.lproj/iPad.storyboard b/Limelight/Base.lproj/iPad.storyboard new file mode 100644 index 00000000..5ee58d31 --- /dev/null +++ b/Limelight/Base.lproj/iPad.storyboard @@ -0,0 +1,1070 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Limelight/Base.lproj/iPhone.storyboard b/Limelight/Base.lproj/iPhone.storyboard new file mode 100644 index 00000000..d63898b9 --- /dev/null +++ b/Limelight/Base.lproj/iPhone.storyboard @@ -0,0 +1,1069 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h new file mode 100644 index 00000000..3c72d91d --- /dev/null +++ b/Limelight/ViewControllers/SettingsViewController.h @@ -0,0 +1,78 @@ +// +// SettingsViewController.h +// Moonlight +// +// Created by Diego Waxemberg on 10/27/14. +// Copyright (c) 2014 Moonlight Stream. All rights reserved. +// + +#import +#import "AppDelegate.h" +#import "CustomOSCViewControl/LayoutOnScreenControlsViewController.h" +#import "MainFrameViewController.h" +#import "CustomEdgeSlideGestureRecognizer.h" + +@interface SettingsViewController : UIViewController +@property (strong, nonatomic) IBOutlet UILabel *bitrateLabel; +@property (strong, nonatomic) IBOutlet UISlider *bitrateSlider; +@property (strong, nonatomic) IBOutlet UISegmentedControl *framerateSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *resolutionSelector; +@property (strong, nonatomic) IBOutlet UIView *resolutionDisplayView; +@property (strong, nonatomic) IBOutlet UILabel *touchModeLabel; +@property (strong, nonatomic) IBOutlet UISegmentedControl *touchModeSelector; +@property (strong, nonatomic) IBOutlet UILabel *onscreenControllerLabel; +@property (strong, nonatomic) IBOutlet UISegmentedControl *onscreenControlSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *motionModeSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *largerStickLR1Selector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *optimizeSettingsSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *multiControllerSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *swapABXYButtonsSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *audioOnPCSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *codecSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *yuv444Selector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *hdrSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *framePacingSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *btMouseSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *reverseMouseWheelDirectionSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *statsOverlaySelector; +@property (strong, nonatomic) IBOutlet UIScrollView *scrollView; +@property (strong, nonatomic) IBOutlet UILabel *keyboardToggleFingerNumLabel; +@property (strong, nonatomic) IBOutlet UISlider *keyboardToggleFingerNumSlider; +@property (strong, nonatomic) IBOutlet UISegmentedControl *liftStreamViewForKeyboardSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *showKeyboardToolbarSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *slideToSettingsScreenEdgeSelector; + +@property (strong, nonatomic) IBOutlet UILabel *oscTapExlusionAreaSizeLabel; +@property (strong, nonatomic) IBOutlet UISlider *oscTapExlusionAreaSizeSlider; +@property (strong, nonatomic) IBOutlet UILabel *slideToSettingsScreenEdgeUILabel; +@property (strong, nonatomic) IBOutlet UISegmentedControl *cmdToolScreenEdgeSelector; +@property (strong, nonatomic) IBOutlet UILabel *slideToSettingsDistanceUILabel; +@property (strong, nonatomic) IBOutlet UISlider *slideToMenuDistanceSlider; +@property (strong, nonatomic) IBOutlet UISlider *pointerVelocityModeDividerSlider; +@property (strong, nonatomic) IBOutlet UILabel *pointerVelocityModeDividerUILabel; +@property (strong, nonatomic) IBOutlet UISlider *touchPointerVelocityFactorSlider; +@property (strong, nonatomic) IBOutlet UILabel *touchPointerVelocityFactorUILabel; +@property (strong, nonatomic) IBOutlet UISlider *mousePointerVelocityFactorSlider; +@property (strong, nonatomic) IBOutlet UILabel *mousePointerVelocityFactorUILabel; +@property (strong, nonatomic) IBOutlet UISegmentedControl *unlockDisplayOrientationSelector; +@property (strong, nonatomic) IBOutlet UIButton *backToStreamingButton; +@property (strong, nonatomic) LayoutOnScreenControlsViewController *layoutOnScreenControlsVC; +@property (nonatomic, strong) MainFrameViewController *mainFrameViewController; + +@property (strong, nonatomic) IBOutlet UISegmentedControl *externalDisplayModeSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *localMousePointerModeSelector; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + +// This is okay because it's just an enum and access uses @available checks +@property(nonatomic) UIUserInterfaceStyle overrideUserInterfaceStyle; + +#pragma clang diagnostic pop + +- (void) saveSettings; ++ (bool) isLandscapeNow; +- (void)updateResolutionTable; +- (void) widget:(UISlider*)widget setEnabled:(bool)enabled; + +@end diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m new file mode 100644 index 00000000..7017a841 --- /dev/null +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -0,0 +1,1142 @@ +// +// SettingsViewController.m +// Moonlight +// +// Created by Diego Waxemberg on 10/27/14. +// Copyright (c) 2014 Moonlight Stream. All rights reserved. +// + +#import "SettingsViewController.h" +#import "TemporarySettings.h" +#import "DataManager.h" + +#import +#import +#import + +#import "LocalizationHelper.h" + +@implementation SettingsViewController { + NSInteger _bitrate; + NSInteger _lastSelectedResolutionIndex; + bool justEnteredSettingsViewDoNotOpenOscLayoutTool; + uint16_t oscLayoutFingers; + CustomEdgeSlideGestureRecognizer *slideToCloseSettingsViewRecognizer; +} + +@dynamic overrideUserInterfaceStyle; + +//static NSString* bitrateFormat; +static const int bitrateTable[] = { + 500, + 1000, + 1500, + 2000, + 2500, + 3000, + 4000, + 5000, + 6000, + 7000, + 8000, + 9000, + 10000, + 11000, + 12000, + 13000, + 14000, + 15000, + 16000, + 17000, + 18000, + 19000, + 20000, + 21000, + 22000, + 23000, + 24000, + 25000, + 26000, + 27000, + 28000, + 29000, + 30000, + 31000, + 32000, + 33000, + 34000, + 35000, + 36000, + 37000, + 38000, + 39000, + 40000, + 41000, + 42000, + 43000, + 44000, + 45000, + 46000, + 47000, + 48000, + 49000, + 50000, + 50000, + 51000, + 52000, + 53000, + 54000, + 55000, + 56000, + 57000, + 58000, + 59000, + 60000, + 61000, + 62000, + 63000, + 64000, + 65000, + 66000, + 67000, + 68000, + 69000, + 70000, + 80000, + 90000, + 100000, + 110000, + 120000, + 130000, + 140000, + 150000, + 160000, + 170000, + 180000, + 200000, + 220000, + 240000, + 260000, + 280000, + 300000, + 320000, + 340000, + 360000, + 380000, + 400000, + 420000, + 440000, + 460000, + 480000, + 500000, +}; + +const int RESOLUTION_TABLE_SIZE = 7; +const int RESOLUTION_TABLE_CUSTOM_INDEX = RESOLUTION_TABLE_SIZE - 1; +CGSize resolutionTable[RESOLUTION_TABLE_SIZE]; + +-(int)getSliderValueForBitrate:(NSInteger)bitrate { + int i; + + for (i = 0; i < (sizeof(bitrateTable) / sizeof(*bitrateTable)); i++) { + if (bitrate <= bitrateTable[i]) { + return i; + } + } + + // Return the last entry in the table + return i - 1; +} + +// This view is rooted at a ScrollView. To make it scrollable, +// we'll update content size here. +-(void)viewDidLayoutSubviews { + CGFloat highestViewY = 0; + + // Enumerate the scroll view's subviews looking for the + // highest view Y value to set our scroll view's content + // size. + for (UIView* view in self.scrollView.subviews) { + // UIScrollViews have 2 default child views + // which represent the horizontal and vertical scrolling + // indicators. Ignore any views we don't recognize. + if (![view isKindOfClass:[UILabel class]] && + ![view isKindOfClass:[UISegmentedControl class]] && + ![view isKindOfClass:[UISlider class]]) { + continue; + } + + CGFloat currentViewY = view.frame.origin.y + view.frame.size.height; + if (currentViewY > highestViewY) { + highestViewY = currentViewY; + } + } + + // Add a bit of padding so the view doesn't end right at the button of the display + self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width, + highestViewY + 20); +} + +// Adjust the subviews for the safe area on the iPhone X. +- (void)viewSafeAreaInsetsDidChange { + [super viewSafeAreaInsetsDidChange]; + + if (@available(iOS 11.0, *)) { + for (UIView* view in self.view.subviews) { + // HACK: The official safe area is much too large for our purposes + // so we'll just use the presence of any safe area to indicate we should + // pad by 20. + if (self.view.safeAreaInsets.left >= 20 || self.view.safeAreaInsets.right >= 20) { + view.frame = CGRectMake(view.frame.origin.x + 20, view.frame.origin.y, view.frame.size.width, view.frame.size.height); + } + } + } +} + +BOOL isCustomResolution(CGSize res) { + if (res.width == 0 && res.height == 0) { + return NO; + } + + for (int i = 0; i < RESOLUTION_TABLE_CUSTOM_INDEX; i++) { + + if ((res.width == resolutionTable[i].width && res.height == resolutionTable[i].height) || (res.height == resolutionTable[i].width && res.width == resolutionTable[i].height)) { + return NO; + } + } + + return YES; +} + ++ (bool)isLandscapeNow { + return CGRectGetWidth([[UIScreen mainScreen]bounds]) > CGRectGetHeight([[UIScreen mainScreen]bounds]); +} + +- (bool)isFullScreenRequired { + NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; + NSNumber *requiresFullScreen = infoDictionary[@"UIRequiresFullScreen"]; + + if (requiresFullScreen != nil) { + return [requiresFullScreen boolValue]; + } + // Default behavior if the key is not set + return true; +} + +- (bool)isAirPlayEnabled{ + return [self.externalDisplayModeSelector selectedSegmentIndex] == 1; +} + +- (void)updateResolutionTable{ + UIWindow *window = UIApplication.sharedApplication.windows.firstObject; + CGFloat screenScale = window.screen.scale; + CGFloat safeAreaWidth = (window.frame.size.width - window.safeAreaInsets.left - window.safeAreaInsets.right) * screenScale; + CGFloat appWindowWidth = window.frame.size.width * screenScale; + CGFloat appWindowHeight = window.frame.size.height * screenScale; + if([self isAirPlayEnabled] && UIScreen.screens.count > 1){ + CGRect bounds = [UIScreen.screens.lastObject bounds]; + screenScale = [UIScreen.screens.lastObject scale]; + appWindowWidth = bounds.size.width * screenScale; + appWindowHeight = bounds.size.height * screenScale; + } + bool needSwapWidthAndHeight = appWindowWidth > appWindowHeight; + + resolutionTable[4] = CGSizeMake(safeAreaWidth, appWindowHeight); + + for(uint8_t i=0;i<7;i++){ + CGFloat longSideLen = resolutionTable[i].height > resolutionTable[i].width ? resolutionTable[i].height : resolutionTable[i].width; + CGFloat shortSideLen = resolutionTable[i].height < resolutionTable[i].width ? resolutionTable[i].height : resolutionTable[i].width; + if(needSwapWidthAndHeight) resolutionTable[i] = CGSizeMake(longSideLen, shortSideLen); + else resolutionTable[i] = CGSizeMake(shortSideLen, longSideLen); + } + + resolutionTable[5] = CGSizeMake(appWindowWidth, appWindowHeight); + + [self updateResolutionDisplayViewText]; +} + +// this will also be called back when device orientation changes +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { + [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + double delayInSeconds = 0.2; + // Convert the delay into a dispatch_time_t value + dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); + // Perform some task after the delay + dispatch_after(delayTime, dispatch_get_main_queue(), ^{// Code to execute after the delay + [self updateResolutionTable]; + }); +} + +- (void)viewDidAppear:(BOOL)animated{ + [super viewDidAppear:animated]; + [self updateResolutionTable]; + NSLog(@"Resolution table updated"); +} + + +- (void)deviceOrientationDidChange{ + double delayInSeconds = 1.0; + // Convert the delay into a dispatch_time_t value + dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); + // Perform some task after the delay + dispatch_after(delayTime, dispatch_get_main_queue(), ^{ + // Code to execute after the delay + // [self updateResolutionTable]; + // since we have viewWillTransitionToSize being called back both when orientation changed & app window size changed, resoltion update is dprecated here + }); +} + + +- (void)simulateSettingsButtonPress{ + [self.mainFrameViewController simulateSettingsButtonPress]; +} + + +- (void)viewDidDisappear:(BOOL)animated{ + [super viewDidDisappear:animated]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"SettingsViewClosedNotification" object:self]; // notify other view that settings view just closed +} + +- (void)pushDownExistingWidgets{ + // Calculate the height needed for the exit button + CGFloat exitButtonHeight = 50.0; // Adjust as needed + CGFloat topOffset = exitButtonHeight; // Space needed for the exit button + // Iterate through subviews of self.view and adjust their frames + for (UIView *subview in self.view.subviews) { + CGRect frame = subview.frame; + frame.origin.y += topOffset; + subview.frame = frame; + } +} + +- (IBAction)exitButtonTapped:(id)sender { + [self->_mainFrameViewController simulateSettingsButtonPress]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"SessionDisconnectedBySettingsViewNotification" object:self]; +} + +- (IBAction)backToStreamingButtonTapped:(id)sender { + [self simulateSettingsButtonPress]; +} + + +/* +- (void)addExitButtonOnTop{ + UIButton *exitButton = [UIButton buttonWithType:UIButtonTypeSystem]; + [exitButton setTitle:@"Exit" forState:UIControlStateNormal]; + [exitButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // Set font color + exitButton.backgroundColor = [UIColor clearColor]; // Set background color + exitButton.titleLabel.font = [UIFont boldSystemFontOfSize:16.0]; // Set font size and style + exitButton.layer.cornerRadius = 8.0; // Optional: Round corners if desired + exitButton.clipsToBounds = YES; // Ensure rounded corners are applied properly + [exitButton addTarget:self action:@selector(exitButtonTapped) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:exitButton]; + exitButton.frame = CGRectMake(0, 20, 200, 50); // Adjust Y and height as needed +}*/ + +- (void)edgeSwiped { + [self simulateSettingsButtonPress]; +} + +- (void)viewDidLoad { + //[self pushDownExistingWidgets]; + //[self addExitButtonOnTop]; + + self->slideToCloseSettingsViewRecognizer = [[CustomEdgeSlideGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)]; + slideToCloseSettingsViewRecognizer.edges = UIRectEdgeLeft; + slideToCloseSettingsViewRecognizer.normalizedThresholdDistance = 0.0; + slideToCloseSettingsViewRecognizer.EDGE_TOLERANCE = 10; + slideToCloseSettingsViewRecognizer.immediateTriggering = true; + slideToCloseSettingsViewRecognizer.delaysTouchesBegan = NO; + slideToCloseSettingsViewRecognizer.delaysTouchesEnded = NO; + [self.view addGestureRecognizer:slideToCloseSettingsViewRecognizer]; + + justEnteredSettingsViewDoNotOpenOscLayoutTool = true; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(deviceOrientationDidChange) // handle orientation change since i made portrait mode available + name:UIDeviceOrientationDidChangeNotification + object:nil]; + + // Always run settings in dark mode because we want the light fonts + if (@available(iOS 13.0, tvOS 13.0, *)) { + self.overrideUserInterfaceStyle = UIUserInterfaceStyleDark; + } + + DataManager* dataMan = [[DataManager alloc] init]; + TemporarySettings* currentSettings = [dataMan getSettings]; + + // Ensure we pick a bitrate that falls exactly onto a slider notch + _bitrate = bitrateTable[[self getSliderValueForBitrate:[currentSettings.bitrate intValue]]]; + + // Get the size of the screen with and without safe area insets + UIWindow *window = UIApplication.sharedApplication.windows.firstObject; + CGFloat screenScale = window.screen.scale; + CGFloat safeAreaWidth = (window.frame.size.width - window.safeAreaInsets.left - window.safeAreaInsets.right) * screenScale; + CGFloat fullScreenWidth = window.frame.size.width * screenScale; + CGFloat fullScreenHeight = window.frame.size.height * screenScale; + + self.resolutionDisplayView.layer.cornerRadius = 10; + self.resolutionDisplayView.clipsToBounds = YES; + UITapGestureRecognizer *resolutionDisplayViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(resolutionDisplayViewTapped:)]; + [self.resolutionDisplayView addGestureRecognizer:resolutionDisplayViewTap]; + + resolutionTable[0] = CGSizeMake(640, 360); + resolutionTable[1] = CGSizeMake(1280, 720); + resolutionTable[2] = CGSizeMake(1920, 1080); + resolutionTable[3] = CGSizeMake(3840, 2160); + resolutionTable[4] = CGSizeMake(safeAreaWidth, fullScreenHeight); + resolutionTable[5] = CGSizeMake(fullScreenWidth, fullScreenHeight); + resolutionTable[6] = CGSizeMake([currentSettings.width integerValue], [currentSettings.height integerValue]); // custom initial value + [self updateResolutionTable]; + + // Don't populate the custom entry unless we have a custom resolution + if (!isCustomResolution(resolutionTable[6])) { + resolutionTable[6] = CGSizeMake(0, 0); + } + + NSInteger framerate; + switch ([currentSettings.framerate integerValue]) { + case 30: + framerate = 0; + break; + default: + case 60: + framerate = 1; + break; + case 120: + framerate = 2; + break; + } + + NSInteger resolution = currentSettings.resolutionSelected.integerValue; + if(resolution >= RESOLUTION_TABLE_SIZE){ + resolution = 0; + } + + // Only show the 120 FPS option if we have a > 60-ish Hz display + bool enable120Fps = false; + if (@available(iOS 10.3, tvOS 10.3, *)) { + if ([UIScreen mainScreen].maximumFramesPerSecond > 62) { + enable120Fps = true; + } + } + if (!enable120Fps) { + [self.framerateSelector removeSegmentAtIndex:2 animated:NO]; + } + + // Disable codec selector segments for unsupported codecs +#if defined(__IPHONE_16_0) || defined(__TVOS_16_0) + if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_AV1)) +#endif + { + [self.codecSelector removeSegmentAtIndex:2 animated:NO]; + } + if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) { + [self.codecSelector removeSegmentAtIndex:1 animated:NO]; + + // Only enable the 4K option for "recent" devices. We'll judge that by whether + // they support HEVC decoding (A9 or later). + [self.resolutionSelector setEnabled:NO forSegmentAtIndex:3]; + } + switch (currentSettings.preferredCodec) { + case CODEC_PREF_AUTO: + [self.codecSelector setSelectedSegmentIndex:self.codecSelector.numberOfSegments - 1]; + break; + + case CODEC_PREF_AV1: + [self.codecSelector setSelectedSegmentIndex:2]; + break; + + case CODEC_PREF_HEVC: + [self.codecSelector setSelectedSegmentIndex:1]; + break; + + case CODEC_PREF_H264: + [self.codecSelector setSelectedSegmentIndex:0]; + break; + } + + if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC) || !(AVPlayer.availableHDRModes & AVPlayerHDRModeHDR10)) { + [self.hdrSelector removeAllSegments]; + [self.hdrSelector insertSegmentWithTitle:[LocalizationHelper localizedStringForKey:@"Unsupported on this device"] atIndex:0 animated:NO]; + [self.hdrSelector setEnabled:NO]; + } + else { + [self.hdrSelector setSelectedSegmentIndex:currentSettings.enableHdr ? 1 : 0]; + } + + [self.yuv444Selector setSelectedSegmentIndex:currentSettings.enableYUV444 ? 1 : 0]; + [self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlayLevel.intValue]; + [self.btMouseSelector setSelectedSegmentIndex:currentSettings.btMouseSupport ? 1 : 0]; + [self.optimizeSettingsSelector setSelectedSegmentIndex:currentSettings.optimizeGames ? 1 : 0]; + [self.framePacingSelector setSelectedSegmentIndex:currentSettings.useFramePacing ? 1 : 0]; + [self.multiControllerSelector setSelectedSegmentIndex:currentSettings.multiController ? 1 : 0]; + [self.swapABXYButtonsSelector setSelectedSegmentIndex:currentSettings.swapABXYButtons ? 1 : 0]; + [self.audioOnPCSelector setSelectedSegmentIndex:currentSettings.playAudioOnPC ? 1 : 0]; + _lastSelectedResolutionIndex = resolution; + [self.resolutionSelector setSelectedSegmentIndex:resolution]; + [self.resolutionSelector addTarget:self action:@selector(newResolutionChosen) forControlEvents:UIControlEventValueChanged]; + [self.framerateSelector setSelectedSegmentIndex:framerate]; + [self.framerateSelector addTarget:self action:@selector(updateBitrate) forControlEvents:UIControlEventValueChanged]; + NSInteger motionMode = [currentSettings.motionMode integerValue]; + [self.motionModeSelector setSelectedSegmentIndex:motionMode]; + [self.bitrateSlider setMinimumValue:0]; + [self.bitrateSlider setMaximumValue:(sizeof(bitrateTable) / sizeof(*bitrateTable)) - 1]; + [self.bitrateSlider setValue:[self getSliderValueForBitrate:_bitrate] animated:YES]; + [self.bitrateSlider addTarget:self action:@selector(bitrateSliderMoved) forControlEvents:UIControlEventValueChanged]; + [self updateBitrateText]; + [self updateResolutionDisplayViewText]; + + // Unlock Display Orientation setting + bool unlockDisplayOrientationSelectorEnabled = [self isFullScreenRequired];//need "requires fullscreen" enabled in the app bunddle to make runtime orientation limitation woring + if(unlockDisplayOrientationSelectorEnabled) [self.unlockDisplayOrientationSelector setSelectedSegmentIndex:currentSettings.unlockDisplayOrientation ? 1 : 0]; + else [self.unlockDisplayOrientationSelector setSelectedSegmentIndex:1]; // can't lock screen orientation in this mode = Display Orientation always unlocked + [self.unlockDisplayOrientationSelector setEnabled:unlockDisplayOrientationSelectorEnabled]; + + + // lift streamview setting + [self.liftStreamViewForKeyboardSelector setSelectedSegmentIndex:currentSettings.liftStreamViewForKeyboard ? 1 : 0];// Load old setting + + // showkeyboard toolbar setting + [self.showKeyboardToolbarSelector setSelectedSegmentIndex:currentSettings.showKeyboardToolbar ? 1 : 0];// Load old setting + + // reverse mouse wheel direction setting + [self.reverseMouseWheelDirectionSelector setSelectedSegmentIndex:currentSettings.reverseMouseWheelDirection ? 1 : 0];// Load old setting + + // slide to menu settings + [self.slideToSettingsScreenEdgeSelector setSelectedSegmentIndex:[self getSelectorIndexFromScreenEdge:(uint32_t)currentSettings.slideToSettingsScreenEdge.integerValue]]; + // Load old setting + [self.cmdToolScreenEdgeSelector setEnabled:false]; + [self.slideToSettingsScreenEdgeSelector addTarget:self action:@selector(slideToSettingsScreenEdgeChanged) forControlEvents:UIControlEventValueChanged]; + [self slideToSettingsScreenEdgeChanged]; + + [self.slideToMenuDistanceSlider setValue:currentSettings.slideToSettingsDistance.floatValue]; + [self.slideToMenuDistanceSlider addTarget:self action:@selector(slideToMenuDistanceSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. + [self slideToMenuDistanceSliderMoved]; + + + + //TouchMode & OSC Related Settings: + + // pointer veloc setting, will be enable/disabled by touchMode + [self.pointerVelocityModeDividerSlider setValue: (uint8_t)(currentSettings.pointerVelocityModeDivider.floatValue * 100) animated:YES]; // Load old setting. + [self.pointerVelocityModeDividerSlider addTarget:self action:@selector(pointerVelocityModeDividerSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. + [self pointerVelocityModeDividerSliderMoved]; + + // init pointer veloc setting, will be enable/disabled by touchMode + [self.touchPointerVelocityFactorSlider setValue: [self map_SliderValue_fromVelocFactor: currentSettings.touchPointerVelocityFactor.floatValue] animated:YES]; // Load old setting. + [self.touchPointerVelocityFactorSlider addTarget:self action:@selector(touchPointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. + [self touchPointerVelocityFactorSliderMoved]; + + // init relative touch mouse pointer veloc setting, will be enable/disabled by touchMode + [self.mousePointerVelocityFactorSlider setValue:[self map_SliderValue_fromVelocFactor: currentSettings.mousePointerVelocityFactor.floatValue] animated:YES]; // Load old setting. + [self.mousePointerVelocityFactorSlider addTarget:self action:@selector(mousePointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. + [self mousePointerVelocityFactorSliderMoved]; + + + // these settings will be affected by onscreenControl & touchMode, must be loaded before them. + // NSLog(@"osc tool fingers setting test: %d", currentSettings.oscLayoutToolFingers.intValue); + self->oscLayoutFingers = (uint16_t)currentSettings.oscLayoutToolFingers.intValue; // load old setting of oscLayoutFingers + [self.keyboardToggleFingerNumSlider setValue:(CGFloat)currentSettings.keyboardToggleFingers.intValue animated:YES]; // Load old setting. old setting was converted to uint16_t before saving. + [self.keyboardToggleFingerNumSlider addTarget:self action:@selector(keyboardToggleFingerNumSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. + [self keyboardToggleFingerNumSliderMoved]; + + // this setting will be affected by touchMode, must be loaded before them. + NSInteger onscreenControlsLevel = [currentSettings.onscreenControls integerValue]; + [self.onscreenControlSelector setSelectedSegmentIndex:onscreenControlsLevel]; + [self.onscreenControlSelector addTarget:self action:@selector(onscreenControlChanged) forControlEvents:UIControlEventValueChanged]; + [self onscreenControlChanged]; + [self.largerStickLR1Selector setSelectedSegmentIndex:currentSettings.largerStickLR1 ? 1 : 0]; // load old setting of largerStickLR1 + + // tap exclusion area size for custom OSC, must be loaded before touchMode & osc selector. + [self.oscTapExlusionAreaSizeSlider setValue:currentSettings.oscTapExlusionAreaSize.floatValue * 100 animated:YES]; // Load old setting. + [self.oscTapExlusionAreaSizeSlider addTarget:self action:@selector(oscTapExlusionAreaSizeSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. + [self oscTapExlusionAreaSizeSliderMoved]; + + + // [self.touchModeSelector setSelectedSegmentIndex:currentSettings.absoluteTouchMode ? 1 : 0]; + // this part will enable/disable oscSelector & the largerStickLR1 selector + [self.touchModeSelector setSelectedSegmentIndex:currentSettings.touchMode.intValue]; //Load old touchMode setting + [self.touchModeSelector addTarget:self action:@selector(touchModeChanged) forControlEvents:UIControlEventValueChanged]; + [self touchModeChanged]; + + + // init CustomOSC stuff + /* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */ + self.layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init]; + BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone); + if (isIPhone) { + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil]; + self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"]; + } + else { + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPad" bundle:nil]; + self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"]; + self.layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationFullScreen; + } + + [self.externalDisplayModeSelector setSelectedSegmentIndex:currentSettings.externalDisplayMode.integerValue]; + [self.localMousePointerModeSelector setSelectedSegmentIndex:currentSettings.localMousePointerMode.integerValue]; +} + +- (void)slideToSettingsScreenEdgeChanged{ + if([self.slideToSettingsScreenEdgeSelector selectedSegmentIndex] == 0) [self.cmdToolScreenEdgeSelector setSelectedSegmentIndex:1]; + else [self.cmdToolScreenEdgeSelector setSelectedSegmentIndex:0]; +} + + +- (void)updateTouchModeLabel{ + NSString* labelText; + switch([self.touchModeSelector selectedSegmentIndex]){ + case RELATIVE_TOUCH: + labelText = [LocalizationHelper localizedStringForKey:@"Touch Mode - Double Tap to Drag, OSC Available"];break; + case REGULAR_NATIVE_TOUCH: + labelText = [LocalizationHelper localizedStringForKey:@"Touch Mode - With OSC & Mouse Support"];break; + case PURE_NATIVE_TOUCH: + labelText = [LocalizationHelper localizedStringForKey:@"Touch Mode - No OSC & Mouse Support"];break; + case ABSOLUTE_TOUCH: + labelText = [LocalizationHelper localizedStringForKey:@"Touch Mode - For MacOS Direct Touch"];break; + } + [self.touchModeLabel setText:labelText]; +} + +- (void)showCustomOSCTip { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Rebase in Stream View"] + message:[LocalizationHelper localizedStringForKey:@"Tap %d fingers to change layout in stream view, or change the number of fingers required to:", self->oscLayoutFingers] + preferredStyle:UIAlertControllerStyleAlert]; + + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.placeholder = [LocalizationHelper localizedStringForKey:@"%d", self->oscLayoutFingers]; + textField.keyboardType = UIKeyboardTypeNumberPad; + }]; + + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Cancel"] + style:UIAlertActionStyleCancel + handler:nil]; + + UIAlertAction *okAction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"OK"] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + UITextField *textField = alertController.textFields.firstObject; + NSString *inputText = textField.text; + NSInteger fingers = [inputText integerValue]; + if (inputText.length > 0 && fingers >= 4) { + self->oscLayoutFingers = (uint16_t) fingers; + NSLog(@"OK button tapped with %d fingers", (uint16_t)fingers); + } else { + NSLog(@"OK button tapped with no change"); + } + + // Continue execution after the alert is dismissed + if (!self->_mainFrameViewController.settingsExpandedInStreamView) { + [self invokeOscLayout]; // Don't open osc layout tool immediately during streaming + } + + [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"Tap %d Fingers to Change OSC Layout in Stream View", self->oscLayoutFingers]]; //update the osc label + [self keyboardToggleFingerNumSliderMoved]; //update keyboard toggle number; + }]; + + [alertController addAction:cancelAction]; + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; +} + + + +- (bool) isOnScreenControllerOrButtonEnabled{ + return ([self.touchModeSelector selectedSegmentIndex] == RELATIVE_TOUCH || [self.touchModeSelector selectedSegmentIndex] == REGULAR_NATIVE_TOUCH || [self.touchModeSelector selectedSegmentIndex] == ABSOLUTE_TOUCH) && [self.onscreenControlSelector selectedSegmentIndex] != OnScreenControlsLevelOff; +} + + + +- (void)onscreenControlChanged{ + + BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone); + if (isIPhone) { + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil]; + self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"]; + } + else { + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPad" bundle:nil]; + self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"]; + self.layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationFullScreen; + } + + bool customOscEnabled = [self isOnScreenControllerOrButtonEnabled] && [self.onscreenControlSelector selectedSegmentIndex] == OnScreenControlsLevelCustom; + // [self widget:self.keyboardToggleFingerNumSlider setEnabled:!customOscEnabled]; + [self widget:self.oscTapExlusionAreaSizeSlider setEnabled:customOscEnabled]; + if(customOscEnabled && !justEnteredSettingsViewDoNotOpenOscLayoutTool) { + // [self.keyboardToggleFingerNumSlider setValue:3.0]; + // [self keyboardToggleFingerNumSliderMoved]; + [self keyboardToggleFingerNumSliderMoved]; // go to exclude 5 fingers + [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"Tap %d Fingers to Change OSC Layout in Stream View", self->oscLayoutFingers]]; + [self showCustomOSCTip]; + justEnteredSettingsViewDoNotOpenOscLayoutTool = false; + //if (self.layoutOnScreenControlsVC.isBeingPresented == NO) + } + else{ + [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"On-Screen Controls & Widgets"]]; + } + justEnteredSettingsViewDoNotOpenOscLayoutTool = false; +} + +- (void)invokeOscLayout{ + [self presentViewController:self.layoutOnScreenControlsVC animated:YES completion:nil]; +} + + +- (void) pointerVelocityModeDividerSliderMoved { + [self.pointerVelocityModeDividerUILabel setText:[LocalizationHelper localizedStringForKey:@"Touch Pointer Velocity: Scaled on %d%% of Right Screen", 100 - (uint8_t)self.pointerVelocityModeDividerSlider.value]]; +} + +- (void) touchPointerVelocityFactorSliderMoved { + [self.touchPointerVelocityFactorUILabel setText:[LocalizationHelper localizedStringForKey: @"Touch Pointer Velocity: %d%%", [self map_velocFactorDisplay_fromSliderValue: self.touchPointerVelocityFactorSlider.value]]]; // Update label display +} + + +// veloc factor upto 700% +- (uint16_t) map_velocFactorDisplay_fromSliderValue:(CGFloat)sliderValue{ + uint16_t velocFactorDisplay = 0; + if(sliderValue > 200) velocFactorDisplay = 200 + ((uint16_t)sliderValue % 200) * 5; + else velocFactorDisplay = (uint16_t) sliderValue; + return velocFactorDisplay; +} + +// veloc factor upto 700% + +- (CGFloat) map_SliderValue_fromVelocFactor:(CGFloat)velocFactor{ + CGFloat sliderValue = 0.0f; + if(velocFactor < 2.0f) sliderValue = velocFactor * 100; + else sliderValue = (velocFactor - 2.0) * 100 / 5 + 200; + return sliderValue; +} + +- (void) mousePointerVelocityFactorSliderMoved { + [self.mousePointerVelocityFactorUILabel setText:[LocalizationHelper localizedStringForKey: @"Mouse Pointer Velocity: %d%%", [self map_velocFactorDisplay_fromSliderValue: self.mousePointerVelocityFactorSlider.value]]]; // Update label display +} + +- (uint32_t) getScreenEdgeFromSelector { + switch (self.slideToSettingsScreenEdgeSelector.selectedSegmentIndex) { + case 0: return UIRectEdgeLeft; + case 1: return UIRectEdgeRight; + case 2: return UIRectEdgeLeft|UIRectEdgeRight; + default: return UIRectEdgeLeft; + } +} + +- (uint32_t) getSelectorIndexFromScreenEdge: (uint32_t)edge { + switch (edge) { + case UIRectEdgeLeft: return 0; + case UIRectEdgeRight: return 1; + case UIRectEdgeLeft|UIRectEdgeRight: return 2; + default: return 0; + } + return 0; +} + +- (void) widget:(UISlider*)widget setEnabled:(bool)enabled{ + [widget setEnabled:enabled]; + if(enabled){ + widget.alpha = 1.0; + [widget setValue:widget.value + 0.0001]; // this is for low iOS version (like iOS14), only setting this minor value change is able to make widget visibility clear + } + else widget.alpha = 0.5; // this is for updating widget visibility on low iOS version like mini5 ios14 +} + +- (void) touchModeChanged { + // Disable On-Screen Controls & Widgets in non-relative touch mode + bool oscSelectorEnabled = [self.touchModeSelector selectedSegmentIndex] == RELATIVE_TOUCH || [self.touchModeSelector selectedSegmentIndex] == REGULAR_NATIVE_TOUCH || [self.touchModeSelector selectedSegmentIndex] == ABSOLUTE_TOUCH; + bool customOscEnabled = [self isOnScreenControllerOrButtonEnabled] && [self.onscreenControlSelector selectedSegmentIndex] == OnScreenControlsLevelCustom; + bool isNativeTouch = [self.touchModeSelector selectedSegmentIndex] == PURE_NATIVE_TOUCH || [self.touchModeSelector selectedSegmentIndex] == REGULAR_NATIVE_TOUCH; + + [self.onscreenControlSelector setEnabled:oscSelectorEnabled]; + [self.largerStickLR1Selector setEnabled:oscSelectorEnabled]; // this selector stay aligned with oscSelector + + [self widget:self.pointerVelocityModeDividerSlider setEnabled:isNativeTouch]; // pointer velocity scaling works only in native touch mode. + [self widget:self.touchPointerVelocityFactorSlider setEnabled:isNativeTouch]; // pointer velocity scaling works only in native touch mode. + [self widget:self.mousePointerVelocityFactorSlider setEnabled:[self.touchModeSelector selectedSegmentIndex] == RELATIVE_TOUCH]; // mouse velocity scaling works only in relative touch mode. + [self widget:self.oscTapExlusionAreaSizeSlider setEnabled:customOscEnabled]; + + // number of touches required to toggle keyboard will be fixed to 3 when OSC is enabled. + // [self widget:self.keyboardToggleFingerNumSlider setEnabled: !customOscEnabled]; // cancel OSC limitation for regular native touch, + // when CustomOSC is enabled: + if(customOscEnabled) { + // [self.keyboardToggleFingerNumSlider setValue:3.0]; + // [self.keyboardToggleFingerNumLabel setText:[LocalizationHelper localizedStringForKey:@"To Toggle Local Keyboard: Tap %d Fingers", (uint16_t)self.keyboardToggleFingerNumSlider.value]]; + [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"Tap %d Fingers to Change OSC Layout in Stream View", self->oscLayoutFingers]]; + [self keyboardToggleFingerNumSliderMoved]; // go exclude 5 fingers + //if (self.layoutOnScreenControlsVC.isBeingPresented == NO) + } + else{ + [self.onscreenControllerLabel setText:[LocalizationHelper localizedStringForKey: @"On-Screen Controls & Widgets"]]; + } + [self updateTouchModeLabel]; +} + +- (void) updateBitrate { + NSInteger fps = [self getChosenFrameRate]; + NSInteger width = [self getChosenStreamWidth]; + NSInteger height = [self getChosenStreamHeight]; + NSInteger defaultBitrate; + + // This logic is shamelessly stolen from Moonlight Qt: + // https://github.com/moonlight-stream/moonlight-qt/blob/master/app/settings/streamingpreferences.cpp + + // Don't scale bitrate linearly beyond 60 FPS. It's definitely not a linear + // bitrate increase for frame rate once we get to values that high. + float frameRateFactor = (fps <= 60 ? fps : (sqrtf(fps / 60.f) * 60.f)) / 30.f; + + // TODO: Collect some empirical data to see if these defaults make sense. + // We're just using the values that the Shield used, as we have for years. + struct { + NSInteger pixels; + int factor; + } resTable[] = { + { 640 * 360, 1 }, + { 854 * 480, 2 }, + { 1280 * 720, 5 }, + { 1920 * 1080, 10 }, + { 2560 * 1440, 20 }, + { 3840 * 2160, 40 }, + { -1, -1 } + }; + + // Calculate the resolution factor by linear interpolation of the resolution table + float resolutionFactor; + NSInteger pixels = width * height; + for (int i = 0;; i++) { + if (pixels == resTable[i].pixels) { + // We can bail immediately for exact matches + resolutionFactor = resTable[i].factor; + break; + } + else if (pixels < resTable[i].pixels) { + if (i == 0) { + // Never go below the lowest resolution entry + resolutionFactor = resTable[i].factor; + } + else { + // Interpolate between the entry greater than the chosen resolution (i) and the entry less than the chosen resolution (i-1) + resolutionFactor = ((float)(pixels - resTable[i-1].pixels) / (resTable[i].pixels - resTable[i-1].pixels)) * (resTable[i].factor - resTable[i-1].factor) + resTable[i-1].factor; + } + break; + } + else if (resTable[i].pixels == -1) { + // Never go above the highest resolution entry + resolutionFactor = resTable[i-1].factor; + break; + } + } + + defaultBitrate = round(resolutionFactor * frameRateFactor) * 1000; + _bitrate = MIN(defaultBitrate, 100000); + [self.bitrateSlider setValue:[self getSliderValueForBitrate:_bitrate] animated:YES]; + + [self updateBitrateText]; +} + +- (void) newResolutionChosen { + BOOL lastSegmentSelected = [self.resolutionSelector selectedSegmentIndex] + 1 == [self.resolutionSelector numberOfSegments]; + if (lastSegmentSelected) { + [self promptCustomResolutionDialog]; + } + else { + [self updateBitrate]; + [self updateResolutionDisplayViewText]; + _lastSelectedResolutionIndex = [self.resolutionSelector selectedSegmentIndex]; + } + [self updateResolutionTable]; +} + +- (void) promptCustomResolutionDialog { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey: @"Enter Custom Resolution"] message:nil preferredStyle:UIAlertControllerStyleAlert]; + + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.placeholder = [LocalizationHelper localizedStringForKey:@"Video Width"]; + textField.clearButtonMode = UITextFieldViewModeAlways; + textField.borderStyle = UITextBorderStyleRoundedRect; + textField.keyboardType = UIKeyboardTypeNumberPad; + + if (resolutionTable[RESOLUTION_TABLE_CUSTOM_INDEX].width == 0) { + textField.text = @""; + } + else { + textField.text = [NSString stringWithFormat:@"%d", (int) resolutionTable[RESOLUTION_TABLE_CUSTOM_INDEX].width]; + } + }]; + + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.placeholder = [LocalizationHelper localizedStringForKey:@"Video Height"]; + textField.clearButtonMode = UITextFieldViewModeAlways; + textField.borderStyle = UITextBorderStyleRoundedRect; + textField.keyboardType = UIKeyboardTypeNumberPad; + + if (resolutionTable[RESOLUTION_TABLE_CUSTOM_INDEX].height == 0) { + textField.text = @""; + } + else { + textField.text = [NSString stringWithFormat:@"%d", (int) resolutionTable[RESOLUTION_TABLE_CUSTOM_INDEX].height]; + } + }]; + + [alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + NSArray * textfields = alertController.textFields; + UITextField *widthField = textfields[0]; + UITextField *heightField = textfields[1]; + + long width = [widthField.text integerValue]; + long height = [heightField.text integerValue]; + if (width <= 0 || height <= 0) { + // Restore the previous selection + [self.resolutionSelector setSelectedSegmentIndex:self->_lastSelectedResolutionIndex]; + return; + } + + // H.264 maximum + int maxResolutionDimension = 4096; + if (@available(iOS 11.0, tvOS 11.0, *)) { + if (VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) { + // HEVC maximum + maxResolutionDimension = 8192; + } + } + + // Cap to maximum valid dimensions + width = MIN(width, maxResolutionDimension); + height = MIN(height, maxResolutionDimension); + + // Cap to minimum valid dimensions + width = MAX(width, 256); + height = MAX(height, 256); + + resolutionTable[RESOLUTION_TABLE_CUSTOM_INDEX] = CGSizeMake(width, height); + [self updateBitrate]; + [self updateResolutionDisplayViewText]; + self->_lastSelectedResolutionIndex = [self.resolutionSelector selectedSegmentIndex]; + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Custom Resolution Selected"] message: [LocalizationHelper localizedStringForKey:@"Custom resolutions are not officially supported by GeForce Experience, so it will not set your host display resolution. You will need to set it manually while in game.\n\nResolutions that are not supported by your client or host PC may cause streaming errors."] preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]]; + [self presentViewController:alertController animated:YES completion:nil]; + }]]; + + [alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Cancel"] style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { + // Restore the previous selection + [self.resolutionSelector setSelectedSegmentIndex:self->_lastSelectedResolutionIndex]; + }]]; + + [self presentViewController:alertController animated:YES completion:nil]; +} + +- (void)resolutionDisplayViewTapped:(UITapGestureRecognizer *)sender { + NSURL *url = [NSURL URLWithString:@"https://moonlight-stream.org/custom-resolution"]; + if ([[UIApplication sharedApplication] canOpenURL:url]) { + [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil]; + } +} + +- (void) updateResolutionDisplayViewText { + NSInteger width = [self getChosenStreamWidth]; + NSInteger height = [self getChosenStreamHeight]; + CGFloat viewFrameWidth = self.resolutionDisplayView.frame.size.width; + CGFloat viewFrameHeight = self.resolutionDisplayView.frame.size.height; + CGFloat padding = 10; + CGFloat fontSize = [UIFont smallSystemFontSize]; + + for (UIView *subview in self.resolutionDisplayView.subviews) { + [subview removeFromSuperview]; + } + UILabel *label1 = [[UILabel alloc] init]; + label1.text = [LocalizationHelper localizedStringForKey:@"Set PC/Game resolution:"]; + label1.font = [UIFont systemFontOfSize:fontSize]; + [label1 sizeToFit]; + label1.frame = CGRectMake(padding, (viewFrameHeight - label1.frame.size.height) / 2, label1.frame.size.width, label1.frame.size.height); + + UILabel *label2 = [[UILabel alloc] init]; + label2.text = [NSString stringWithFormat:@"%ld x %ld", (long)width, (long)height]; + [label2 sizeToFit]; + label2.frame = CGRectMake(viewFrameWidth - label2.frame.size.width - padding, (viewFrameHeight - label2.frame.size.height) / 2, label2.frame.size.width, label2.frame.size.height); + + [self.resolutionDisplayView addSubview:label1]; + [self.resolutionDisplayView addSubview:label2]; +} + +- (void) oscTapExlusionAreaSizeSliderMoved{ + [self.oscTapExlusionAreaSizeLabel setText:[LocalizationHelper localizedStringForKey:@"Tap Exclusion Area Size for Custom OSC: %d%%", (uint16_t)self.oscTapExlusionAreaSizeSlider.value]]; +} + +- (void) keyboardToggleFingerNumSliderMoved{ + // bool oscEnabled = [self isOnScreenControllerOrButtonEnabled]; + bool customOscEnabled = [self isOnScreenControllerOrButtonEnabled] && [self.onscreenControlSelector selectedSegmentIndex] == OnScreenControlsLevelCustom; + + CGFloat sliderValue = self.keyboardToggleFingerNumSlider.value; + if(customOscEnabled){ + // exclude self->oscLayoutFingers when custom osc is enabled + if(sliderValue > self->oscLayoutFingers - 1 && sliderValue < self->oscLayoutFingers) [self.keyboardToggleFingerNumSlider setValue: self->oscLayoutFingers - 1]; + if(sliderValue >= self->oscLayoutFingers && sliderValue < self->oscLayoutFingers + 1) [self.keyboardToggleFingerNumSlider setValue: self->oscLayoutFingers + 1]; + } + + sliderValue = self.keyboardToggleFingerNumSlider.value; + if(sliderValue > 10.5f) [self.keyboardToggleFingerNumLabel setText:[LocalizationHelper localizedStringForKey:@"Local Keyboard Toggle Disabled"]]; + else [self.keyboardToggleFingerNumLabel setText:[LocalizationHelper localizedStringForKey:@"To Toggle Local Keyboard: Tap %d Fingers", (uint16_t)sliderValue]]; // Initiate label display, exclude 5 fingers. +} + +- (void) slideToMenuDistanceSliderMoved{ + [self.slideToSettingsDistanceUILabel setText:[LocalizationHelper localizedStringForKey:@"Slide Distance for in-Stream Menu: %.2f * screen-width", self.slideToMenuDistanceSlider.value]]; +} + +- (void) bitrateSliderMoved { + assert(self.bitrateSlider.value < (sizeof(bitrateTable) / sizeof(*bitrateTable))); + _bitrate = bitrateTable[(int)self.bitrateSlider.value]; + [self updateBitrateText]; +} + +- (void) updateBitrateText { + // Display bitrate in Mbps + if(_bitrate / 1000. > 50.0) [self.bitrateLabel setText:[LocalizationHelper localizedStringForKey:@"Bitrate: %.1f Mbps - Use High Bitrates with Caution!", _bitrate / 1000.]]; + else [self.bitrateLabel setText:[LocalizationHelper localizedStringForKey:@"Bitrate: %.1f Mbps", _bitrate / 1000.]]; +} + +- (NSInteger) getChosenFrameRate { + switch ([self.framerateSelector selectedSegmentIndex]) { + case 0: + return 30; + case 1: + return 60; + case 2: + return 120; + default: + abort(); + } +} + +- (uint32_t) getChosenCodecPreference { + // Auto is always the last segment + if (self.codecSelector.selectedSegmentIndex == self.codecSelector.numberOfSegments - 1) { + return CODEC_PREF_AUTO; + } + else { + switch (self.codecSelector.selectedSegmentIndex) { + case 0: + return CODEC_PREF_H264; + + case 1: + return CODEC_PREF_HEVC; + + case 2: + return CODEC_PREF_AV1; + + default: + abort(); + } + } +} + +- (NSInteger) getChosenStreamHeight { + // because the 4k resolution can be removed + BOOL lastSegmentSelected = [self.resolutionSelector selectedSegmentIndex] + 1 == [self.resolutionSelector numberOfSegments]; + if (lastSegmentSelected) { + return resolutionTable[RESOLUTION_TABLE_CUSTOM_INDEX].height; + } + + return resolutionTable[[self.resolutionSelector selectedSegmentIndex]].height; +} + +- (NSInteger) getChosenStreamWidth { + // because the 4k resolution can be removed + BOOL lastSegmentSelected = [self.resolutionSelector selectedSegmentIndex] + 1 == [self.resolutionSelector numberOfSegments]; + if (lastSegmentSelected) { + return resolutionTable[RESOLUTION_TABLE_CUSTOM_INDEX].width; + } + + return resolutionTable[[self.resolutionSelector selectedSegmentIndex]].width; +} + +- (void) saveSettings { + DataManager* dataMan = [[DataManager alloc] init]; + NSInteger framerate = [self getChosenFrameRate]; + NSInteger height = [self getChosenStreamHeight]; + NSInteger width = [self getChosenStreamWidth]; + NSInteger onscreenControls = [self.onscreenControlSelector selectedSegmentIndex]; + NSInteger motionMode = [self.motionModeSelector selectedSegmentIndex]; + NSInteger keyboardToggleFingers = (uint16_t)self.keyboardToggleFingerNumSlider.value; + NSInteger oscLayoutToolFingers = (uint16_t)self->oscLayoutFingers; + // NSLog(@"saveSettings keyboardToggleFingers %d", (uint16_t)keyboardToggleFingers); + CGFloat slideToSettingsDistance = self.slideToMenuDistanceSlider.value; + uint32_t slideToSettingsScreenEdge = [self getScreenEdgeFromSelector]; + CGFloat pointerVelocityModeDivider = (CGFloat)(uint8_t)self.pointerVelocityModeDividerSlider.value/100; + CGFloat touchPointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value]/100; + CGFloat mousePointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.mousePointerVelocityFactorSlider.value]/100; + + // CGFloat mousePointerVelocityFactor =(CGFloat)(uint16_t)self.mousePointerVelocityFactorSlider.value/100; + CGFloat oscTapExlusionAreaSize =(CGFloat)(uint16_t)self.oscTapExlusionAreaSizeSlider.value/100; + + BOOL reverseMouseWheelDirection = [self.reverseMouseWheelDirectionSelector selectedSegmentIndex] == 1; + BOOL largerStickLR1 = [self.largerStickLR1Selector selectedSegmentIndex] == 1; + BOOL liftStreamViewForKeyboard = [self.liftStreamViewForKeyboardSelector selectedSegmentIndex] == 1; + BOOL showKeyboardToolbar = [self.showKeyboardToolbarSelector selectedSegmentIndex] == 1; + BOOL optimizeGames = [self.optimizeSettingsSelector selectedSegmentIndex] == 1; + BOOL multiController = [self.multiControllerSelector selectedSegmentIndex] == 1; + BOOL swapABXYButtons = [self.swapABXYButtonsSelector selectedSegmentIndex] == 1; + BOOL audioOnPC = [self.audioOnPCSelector selectedSegmentIndex] == 1; + uint32_t preferredCodec = [self getChosenCodecPreference]; + BOOL enableYUV444 = [self.yuv444Selector selectedSegmentIndex] == 1; + BOOL btMouseSupport = [self.btMouseSelector selectedSegmentIndex] == 1; + BOOL useFramePacing = [self.framePacingSelector selectedSegmentIndex] == 1; + // BOOL absoluteTouchMode = [self.touchModeSelector selectedSegmentIndex] == 1; + NSInteger touchMode = [self.touchModeSelector selectedSegmentIndex]; + NSInteger statsOverlayLevel = [self.statsOverlaySelector selectedSegmentIndex]; + BOOL statsOverlayEnabled = statsOverlayLevel != 0; + BOOL enableHdr = [self.hdrSelector selectedSegmentIndex] == 1; + BOOL unlockDisplayOrientation = [self.unlockDisplayOrientationSelector selectedSegmentIndex] == 1; + NSInteger resolutionSelected = [self.resolutionSelector selectedSegmentIndex]; + NSInteger externalDisplayMode = [self.externalDisplayModeSelector selectedSegmentIndex]; + NSInteger localMousePointerMode = [self.localMousePointerModeSelector selectedSegmentIndex]; + [dataMan saveSettingsWithBitrate:_bitrate + framerate:framerate + height:height + width:width + audioConfig:2 // Stereo + onscreenControls:onscreenControls + motionMode:motionMode + keyboardToggleFingers:keyboardToggleFingers + oscLayoutToolFingers:oscLayoutToolFingers + slideToSettingsScreenEdge:slideToSettingsScreenEdge + slideToSettingsDistance:slideToSettingsDistance + pointerVelocityModeDivider:pointerVelocityModeDivider + touchPointerVelocityFactor:touchPointerVelocityFactor + mousePointerVelocityFactor:mousePointerVelocityFactor + oscTapExlusionAreaSize:oscTapExlusionAreaSize + reverseMouseWheelDirection:reverseMouseWheelDirection + largerStickLR1:largerStickLR1 + liftStreamViewForKeyboard:liftStreamViewForKeyboard + showKeyboardToolbar:showKeyboardToolbar + optimizeGames:optimizeGames + multiController:multiController + swapABXYButtons:swapABXYButtons + audioOnPC:audioOnPC + preferredCodec:preferredCodec + enableYUV444:enableYUV444 + useFramePacing:useFramePacing + enableHdr:enableHdr + btMouseSupport:btMouseSupport + // absoluteTouchMode:absoluteTouchMode + touchMode:touchMode + statsOverlayLevel:statsOverlayLevel + statsOverlayEnabled:statsOverlayEnabled + unlockDisplayOrientation:unlockDisplayOrientation + resolutionSelected:resolutionSelected + externalDisplayMode:externalDisplayMode + localMousePointerMode:localMousePointerMode]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + + +#pragma mark - Navigation + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { +} + +@end diff --git a/VoidLink.xcodeproj/project.pbxproj b/VoidLink.xcodeproj/project.pbxproj index bf03b900..077a0157 100644 --- a/VoidLink.xcodeproj/project.pbxproj +++ b/VoidLink.xcodeproj/project.pbxproj @@ -7,11 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 18341A042DEB662C0094E5F2 /* FixedTintImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18341A032DEB662C0094E5F2 /* FixedTintImageView.m */; }; - 187F4B282E04658A00EECC59 /* WidgetPanelStackView.m in Sources */ = {isa = PBXBuildFile; fileRef = 187F4B272E04658A00EECC59 /* WidgetPanelStackView.m */; }; - 189AD29A2DE7446000E24B88 /* HostCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */; }; 840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; }; - 841BAC922DE35D6B00DA639E /* ThemeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 841BAC912DE35D6B00DA639E /* ThemeManager.m */; }; 84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */; }; 84351B0E2C29ACCB00A77989 /* LayoutOnScreenControls.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */; }; 84351B0F2C29ACCB00A77989 /* OnScreenButtonState.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B092C29ACCA00A77989 /* OnScreenButtonState.m */; }; @@ -22,7 +18,6 @@ 84351B2D2C29AD6100A77989 /* ToolBarContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B292C29AD6000A77989 /* ToolBarContainerView.m */; }; 84351B5C2C29ADBE00A77989 /* ProfileTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B592C29ADBE00A77989 /* ProfileTableViewCell.m */; }; 84351B5D2C29ADBE00A77989 /* ProfileTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84351B5B2C29ADBE00A77989 /* ProfileTableViewCell.xib */; }; - 843667F02D9D7173004A7D7F /* widgetTemplates.bin in Resources */ = {isa = PBXBuildFile; fileRef = 843667EF2D9D7173004A7D7F /* widgetTemplates.bin */; }; 843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */; }; 843CC7F62C1E7A1700BBC475 /* NativeTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 843CC7F52C1E7A1700BBC475 /* NativeTouchHandler.m */; }; 843E93BE2C41528700B1651F /* OrientationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843E93BD2C41528700B1651F /* OrientationHelper.swift */; }; @@ -30,10 +25,8 @@ 8454AC662C31907F00F0A302 /* iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8454AC682C31907F00F0A302 /* iPad.storyboard */; }; 8454AC6A2C319BDA00F0A302 /* iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8454AC6C2C319BDA00F0A302 /* iPhone.storyboard */; }; 84591A512BE1625E006AAB10 /* CustomEdgeSlideGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84591A502BE1625E006AAB10 /* CustomEdgeSlideGestureRecognizer.m */; }; - 847D2FDB2DDA015F00937A62 /* MenuSectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 847D2FDA2DDA015F00937A62 /* MenuSectionView.m */; }; - 848F456A2DDCD12500581E36 /* HostCardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 848F45692DDCD12500581E36 /* HostCardView.m */; }; 84E1CDEC2C4F67D300547904 /* CommandManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E1CDEB2C4F67D300547904 /* CommandManager.swift */; }; - 84E1CDEF2C4F688E00547904 /* ToolBoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E1CDEE2C4F688E00547904 /* ToolBoxViewController.swift */; }; + 84E1CDEF2C4F688E00547904 /* CommandManagerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E1CDEE2C4F688E00547904 /* CommandManagerViewController.swift */; }; 84E1CDFA2C4FE83400547904 /* SwiftLocalizationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E1CDF92C4FE83400547904 /* SwiftLocalizationHelper.swift */; }; 84FD0B512C31338D006B5BE5 /* LocalizationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 84FD0B502C31338D006B5BE5 /* LocalizationHelper.m */; }; 84FD0B542C3134A6006B5BE5 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 84FD0B532C3134A6006B5BE5 /* Localizable.xcstrings */; }; @@ -50,11 +43,11 @@ 9890CF6B203B7EE1006C4B06 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9890CF6A203B7EE1006C4B06 /* libxml2.tbd */; }; 9896219723D15C7000211983 /* X1Kit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9896219623D15C7000211983 /* X1Kit.swift */; }; 9897B6A1221260EF00966419 /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 9897B6A0221260EF00966419 /* Controller.m */; }; + 98A2E31229B5256E00CA17A7 /* OpenSSL.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98A2E31029B5256200CA17A7 /* OpenSSL.xcframework */; }; 98CFB82F1CAD481B0048EF74 /* libmoonlight-common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98AB2E841CAD46840089BB98 /* libmoonlight-common.a */; }; 98D5856D1C0EA79600F6CC00 /* TemporaryHost.m in Sources */ = {isa = PBXBuildFile; fileRef = 98D5856C1C0EA79600F6CC00 /* TemporaryHost.m */; }; 98D585701C0ED0E800F6CC00 /* TemporarySettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 98D5856F1C0ED0E800F6CC00 /* TemporarySettings.m */; }; DC1F5A07206436B20037755F /* ConnectionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1F5A06206436B20037755F /* ConnectionHelper.m */; }; - F74BEF9C2C1A705600224667 /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = F74BEF9B2C1A705600224667 /* OpenSSL */; }; FB1A674D2131E65900507771 /* KeyboardSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1A674C2131E65900507771 /* KeyboardSupport.m */; }; FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */; }; FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */; }; @@ -130,18 +123,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 18341A022DEB65AB0094E5F2 /* FixedTintImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FixedTintImageView.h; sourceTree = ""; }; - 18341A032DEB662C0094E5F2 /* FixedTintImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FixedTintImageView.m; sourceTree = ""; }; - 187F4B232E04633100EECC59 /* WidgetPanelStackView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WidgetPanelStackView.h; sourceTree = ""; }; - 187F4B272E04658A00EECC59 /* WidgetPanelStackView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WidgetPanelStackView.m; sourceTree = ""; }; - 189AD2962DE743B700E24B88 /* HostCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HostCollectionViewController.h; sourceTree = ""; }; - 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HostCollectionViewController.m; sourceTree = ""; }; - 18BF141D2E0D7A00009DEE4F /* VoidLink v1.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "VoidLink v1.0.xcdatamodel"; sourceTree = ""; }; + 566E9D2B2770B23A00EF7BFE /* Moonlight v1.7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.7.xcdatamodel"; sourceTree = ""; }; 693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomTapGestureRecognizer.h; sourceTree = ""; }; 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomTapGestureRecognizer.m; sourceTree = ""; }; - 841BAC8F2DE35BEC00DA639E /* ThemeManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThemeManager.h; sourceTree = ""; }; - 841BAC912DE35D6B00DA639E /* ThemeManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThemeManager.m; sourceTree = ""; }; 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnScreenWidgetView.swift; sourceTree = ""; }; 84351B062C29ACCA00A77989 /* OnScreenButtonState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnScreenButtonState.h; sourceTree = ""; }; 84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LayoutOnScreenControls.m; sourceTree = ""; }; @@ -160,7 +145,6 @@ 84351B592C29ADBE00A77989 /* ProfileTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProfileTableViewCell.m; sourceTree = ""; }; 84351B5A2C29ADBE00A77989 /* ProfileTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileTableViewCell.h; sourceTree = ""; }; 84351B5B2C29ADBE00A77989 /* ProfileTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ProfileTableViewCell.xib; sourceTree = ""; }; - 843667EF2D9D7173004A7D7F /* widgetTemplates.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = widgetTemplates.bin; path = PresetConfigs/widgetTemplates.bin; sourceTree = ""; }; 843CC7EE2C1E757D00BBC475 /* NativeTouchPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeTouchPointer.h; sourceTree = ""; }; 843CC7EF2C1E757D00BBC475 /* NativeTouchPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeTouchPointer.m; sourceTree = ""; }; 843CC7F42C1E778000BBC475 /* NativeTouchHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeTouchHandler.h; sourceTree = ""; }; @@ -174,18 +158,15 @@ 8454AC6D2C319BDA00F0A302 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/iPhone.xcstrings; sourceTree = ""; }; 84591A4F2BE16240006AAB10 /* CustomEdgeSlideGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomEdgeSlideGestureRecognizer.h; sourceTree = ""; }; 84591A502BE1625E006AAB10 /* CustomEdgeSlideGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomEdgeSlideGestureRecognizer.m; sourceTree = ""; }; - 847D2FD82DDA00C800937A62 /* MenuSectionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MenuSectionView.h; sourceTree = ""; }; - 847D2FDA2DDA015F00937A62 /* MenuSectionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MenuSectionView.m; sourceTree = ""; }; - 848F45682DDCD0D600581E36 /* HostCardView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HostCardView.h; sourceTree = ""; }; - 848F45692DDCD12500581E36 /* HostCardView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HostCardView.m; sourceTree = ""; }; - 84D8EB932C5146AD00FC10A9 /* VoidLink-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "VoidLink-Bridging-Header.h"; sourceTree = ""; }; + 84D8EB932C5146AD00FC10A9 /* Moonlight-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Moonlight-Bridging-Header.h"; sourceTree = ""; }; 84E1CDEB2C4F67D300547904 /* CommandManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandManager.swift; sourceTree = ""; }; - 84E1CDEE2C4F688E00547904 /* ToolBoxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolBoxViewController.swift; sourceTree = ""; }; + 84E1CDEE2C4F688E00547904 /* CommandManagerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandManagerViewController.swift; sourceTree = ""; }; 84E1CDF92C4FE83400547904 /* SwiftLocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftLocalizationHelper.swift; sourceTree = ""; }; 84FD0B4F2C313343006B5BE5 /* LocalizationHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalizationHelper.h; sourceTree = ""; }; 84FD0B502C31338D006B5BE5 /* LocalizationHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocalizationHelper.m; sourceTree = ""; }; 84FD0B532C3134A6006B5BE5 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 9803CCAB254F9EAF00EE185E /* ConnectionCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConnectionCallbacks.h; sourceTree = ""; }; + 98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.1.xcdatamodel"; sourceTree = ""; }; 98181BE82791275D00E43572 /* libSDL2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL2.a; path = libs/SDL2/lib/iOS/libSDL2.a; sourceTree = ""; }; 98181BEA2791278300E43572 /* libSDL2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL2.a; path = libs/SDL2/lib/tvOS/libSDL2.a; sourceTree = ""; }; 98181BEC2791281100E43572 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; @@ -193,11 +174,19 @@ 9819CC13254F107A008A7C8E /* RelativeTouchHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RelativeTouchHandler.m; sourceTree = ""; }; 9819CC20254F180F008A7C8E /* AbsoluteTouchHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AbsoluteTouchHandler.h; sourceTree = ""; }; 9819CC21254F180F008A7C8E /* AbsoluteTouchHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AbsoluteTouchHandler.m; sourceTree = ""; }; + 9819CC25254F2734008A7C8E /* Moonlight v1.6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.6.xcdatamodel"; sourceTree = ""; }; 9827E7A22514366900F25707 /* HapticContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HapticContext.m; sourceTree = ""; }; 9827E7A7251436EA00F25707 /* HapticContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HapticContext.h; sourceTree = ""; }; 9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = ""; }; 9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = ""; }; + 984CD023288A310D0097D2D4 /* Moonlight v1.8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.8.xcdatamodel"; sourceTree = ""; }; + 98517B1B21CE0A9000481377 /* Moonlight v1.3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.3.xcdatamodel"; sourceTree = ""; }; + 98608BDD22DC0C2C000E5672 /* Moonlight v1.4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.4.xcdatamodel"; sourceTree = ""; }; 9865DC3B2132922E0005B9B9 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.4.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; }; + 986CCE6C2133E45300168291 /* Moonlight v1.2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.2.xcdatamodel"; sourceTree = ""; }; + 986E28A528EA989100758361 /* Moonlight v1.9.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.9.xcdatamodel"; sourceTree = ""; }; + 9874E8962AE95E1D00130A3C /* Moonlight v1.10.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.10.xcdatamodel"; sourceTree = ""; }; + 98783FEA242EAC5D00F00EF4 /* Moonlight v1.5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.5.xcdatamodel"; sourceTree = ""; }; 98882A032AF60F5300C5A11C /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = libs/FFmpeg/lib/iOS/libavcodec.a; sourceTree = ""; }; 98882A042AF60F5300C5A11C /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = libs/FFmpeg/lib/iOS/libavutil.a; sourceTree = ""; }; 98882A052AF60F5300C5A11C /* libavformat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavformat.a; path = libs/FFmpeg/lib/iOS/libavformat.a; sourceTree = ""; }; @@ -210,6 +199,7 @@ 9896219623D15C7000211983 /* X1Kit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = X1Kit.swift; path = X1Kit/Sources/X1Kit/X1Kit.swift; sourceTree = ""; }; 9897B6A0221260EF00966419 /* Controller.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = ""; }; 9897B6A32212610800966419 /* Controller.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; + 98A2E31029B5256200CA17A7 /* OpenSSL.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = OpenSSL.xcframework; path = libs/OpenSSL.xcframework; sourceTree = ""; }; 98AB2E7F1CAD46830089BB98 /* moonlight-common.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "moonlight-common.xcodeproj"; path = "moonlight-common/moonlight-common.xcodeproj"; sourceTree = ""; }; 98B9CE6C27B2144B00B473C4 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS15.2.sdk/System/Library/Frameworks/AVKit.framework; sourceTree = DEVELOPER_DIR; }; 98D5856B1C0EA79600F6CC00 /* TemporaryHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryHost.h; path = Database/TemporaryHost.h; sourceTree = ""; }; @@ -230,7 +220,7 @@ FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ComputerScrollView.m; sourceTree = ""; }; FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppCollectionView.h; sourceTree = ""; }; FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppCollectionView.m; sourceTree = ""; }; - FB290CEE19B2C406004C83CF /* VoidLink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoidLink.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FB290CEE19B2C406004C83CF /* Moonlight-ZWM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Moonlight-ZWM.app"; sourceTree = BUILT_PRODUCTS_DIR; }; FB290CF119B2C406004C83CF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; FB290CF319B2C406004C83CF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; FB290CF519B2C406004C83CF /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -245,6 +235,7 @@ FB290D0819B2C406004C83CF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; FB4678EB1A50C40900377732 /* OnScreenControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnScreenControls.h; sourceTree = ""; }; FB4678EC1A50C40900377732 /* OnScreenControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OnScreenControls.m; sourceTree = ""; }; + FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Limelight 0.3.0.xcdatamodel"; sourceTree = ""; }; FB4678F81A55FFAD00377732 /* DiscoveryManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscoveryManager.h; sourceTree = ""; }; FB4678F91A55FFAD00377732 /* DiscoveryManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiscoveryManager.m; sourceTree = ""; }; FB4678FD1A565DAC00377732 /* WakeOnLanManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WakeOnLanManager.h; sourceTree = ""; }; @@ -254,8 +245,10 @@ FB4A23B71A9D3637004D2EF2 /* LoadingFrameViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LoadingFrameViewController.m; sourceTree = ""; }; FB53E1411BE5DC4400CD6ECE /* IdManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdManager.h; sourceTree = ""; }; FB53E1421BE5DC4400CD6ECE /* IdManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IdManager.m; sourceTree = ""; }; + FB53E1441BE5DCBC00CD6ECE /* Moonlight v1.0-2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.0-2.xcdatamodel"; sourceTree = ""; }; FB6549541A57907E001C8F39 /* DiscoveryWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscoveryWorker.h; sourceTree = ""; }; FB6549551A57907E001C8F39 /* DiscoveryWorker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiscoveryWorker.m; sourceTree = ""; }; + FB6549621A60B4A9001C8F39 /* Limelight 0.3.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Limelight 0.3.1.xcdatamodel"; sourceTree = ""; }; FB89460519F646E200339C8A /* CryptoManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoManager.h; sourceTree = ""; }; FB89460619F646E200339C8A /* CryptoManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoManager.m; sourceTree = ""; }; FB89460719F646E200339C8A /* mkcert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mkcert.c; sourceTree = ""; }; @@ -285,6 +278,83 @@ FB89462619F646E200339C8A /* StreamFrameViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamFrameViewController.h; sourceTree = ""; }; FB89462719F646E200339C8A /* StreamFrameViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamFrameViewController.m; sourceTree = ""; }; FB89463719F6473800339C8A /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = SOURCE_ROOT; }; + FB89469419F6AFB800339C8A /* aes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = aes.h; sourceTree = ""; }; + FB89469519F6AFB800339C8A /* asn1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asn1.h; sourceTree = ""; }; + FB89469619F6AFB800339C8A /* asn1_mac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asn1_mac.h; sourceTree = ""; }; + FB89469719F6AFB800339C8A /* asn1t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asn1t.h; sourceTree = ""; }; + FB89469819F6AFB800339C8A /* bio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bio.h; sourceTree = ""; }; + FB89469919F6AFB800339C8A /* blowfish.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = blowfish.h; sourceTree = ""; }; + FB89469A19F6AFB800339C8A /* bn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bn.h; sourceTree = ""; }; + FB89469B19F6AFB800339C8A /* buffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = ""; }; + FB89469C19F6AFB800339C8A /* camellia.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = camellia.h; sourceTree = ""; }; + FB89469D19F6AFB800339C8A /* cast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cast.h; sourceTree = ""; }; + FB89469E19F6AFB800339C8A /* cmac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cmac.h; sourceTree = ""; }; + FB89469F19F6AFB800339C8A /* cms.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cms.h; sourceTree = ""; }; + FB8946A019F6AFB800339C8A /* comp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = comp.h; sourceTree = ""; }; + FB8946A119F6AFB800339C8A /* conf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = conf.h; sourceTree = ""; }; + FB8946A219F6AFB800339C8A /* conf_api.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = conf_api.h; sourceTree = ""; }; + FB8946A319F6AFB800339C8A /* crypto.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = crypto.h; sourceTree = ""; }; + FB8946A419F6AFB800339C8A /* des.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = des.h; sourceTree = ""; }; + FB8946A519F6AFB800339C8A /* des_old.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = des_old.h; sourceTree = ""; }; + FB8946A619F6AFB800339C8A /* dh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dh.h; sourceTree = ""; }; + FB8946A719F6AFB800339C8A /* dsa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dsa.h; sourceTree = ""; }; + FB8946A819F6AFB800339C8A /* dso.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dso.h; sourceTree = ""; }; + FB8946A919F6AFB800339C8A /* dtls1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dtls1.h; sourceTree = ""; }; + FB8946AA19F6AFB800339C8A /* e_os2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = e_os2.h; sourceTree = ""; }; + FB8946AB19F6AFB800339C8A /* ebcdic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ebcdic.h; sourceTree = ""; }; + FB8946AC19F6AFB800339C8A /* ec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ec.h; sourceTree = ""; }; + FB8946AD19F6AFB800339C8A /* ecdh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ecdh.h; sourceTree = ""; }; + FB8946AE19F6AFB800339C8A /* ecdsa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ecdsa.h; sourceTree = ""; }; + FB8946AF19F6AFB800339C8A /* engine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = engine.h; sourceTree = ""; }; + FB8946B019F6AFB800339C8A /* err.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = err.h; sourceTree = ""; }; + FB8946B119F6AFB800339C8A /* evp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = evp.h; sourceTree = ""; }; + FB8946B219F6AFB800339C8A /* hmac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = hmac.h; sourceTree = ""; }; + FB8946B319F6AFB800339C8A /* idea.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = idea.h; sourceTree = ""; }; + FB8946B419F6AFB800339C8A /* krb5_asn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = krb5_asn.h; sourceTree = ""; }; + FB8946B519F6AFB800339C8A /* kssl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = kssl.h; sourceTree = ""; }; + FB8946B619F6AFB800339C8A /* lhash.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lhash.h; sourceTree = ""; }; + FB8946B719F6AFB800339C8A /* md4.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = md4.h; sourceTree = ""; }; + FB8946B819F6AFB800339C8A /* md5.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = ""; }; + FB8946B919F6AFB800339C8A /* mdc2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mdc2.h; sourceTree = ""; }; + FB8946BA19F6AFB800339C8A /* modes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = modes.h; sourceTree = ""; }; + FB8946BB19F6AFB800339C8A /* obj_mac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = obj_mac.h; sourceTree = ""; }; + FB8946BC19F6AFB800339C8A /* objects.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = objects.h; sourceTree = ""; }; + FB8946BD19F6AFB800339C8A /* ocsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ocsp.h; sourceTree = ""; }; + FB8946BE19F6AFB800339C8A /* opensslconf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opensslconf.h; sourceTree = ""; }; + FB8946BF19F6AFB800339C8A /* opensslv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opensslv.h; sourceTree = ""; }; + FB8946C019F6AFB800339C8A /* ossl_typ.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ossl_typ.h; sourceTree = ""; }; + FB8946C119F6AFB800339C8A /* pem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pem.h; sourceTree = ""; }; + FB8946C219F6AFB800339C8A /* pem2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pem2.h; sourceTree = ""; }; + FB8946C319F6AFB800339C8A /* pkcs12.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pkcs12.h; sourceTree = ""; }; + FB8946C419F6AFB800339C8A /* pkcs7.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pkcs7.h; sourceTree = ""; }; + FB8946C519F6AFB800339C8A /* pqueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pqueue.h; sourceTree = ""; }; + FB8946C619F6AFB800339C8A /* rand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rand.h; sourceTree = ""; }; + FB8946C719F6AFB800339C8A /* rc2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rc2.h; sourceTree = ""; }; + FB8946C819F6AFB800339C8A /* rc4.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rc4.h; sourceTree = ""; }; + FB8946C919F6AFB800339C8A /* ripemd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ripemd.h; sourceTree = ""; }; + FB8946CA19F6AFB800339C8A /* rsa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rsa.h; sourceTree = ""; }; + FB8946CB19F6AFB800339C8A /* safestack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = safestack.h; sourceTree = ""; }; + FB8946CC19F6AFB800339C8A /* seed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = seed.h; sourceTree = ""; }; + FB8946CD19F6AFB800339C8A /* sha.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sha.h; sourceTree = ""; }; + FB8946CE19F6AFB800339C8A /* srp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = srp.h; sourceTree = ""; }; + FB8946CF19F6AFB800339C8A /* srtp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = srtp.h; sourceTree = ""; }; + FB8946D019F6AFB800339C8A /* ssl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ssl.h; sourceTree = ""; }; + FB8946D119F6AFB800339C8A /* ssl2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ssl2.h; sourceTree = ""; }; + FB8946D219F6AFB800339C8A /* ssl23.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ssl23.h; sourceTree = ""; }; + FB8946D319F6AFB800339C8A /* ssl3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ssl3.h; sourceTree = ""; }; + FB8946D419F6AFB800339C8A /* stack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stack.h; sourceTree = ""; }; + FB8946D519F6AFB800339C8A /* symhacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = symhacks.h; sourceTree = ""; }; + FB8946D619F6AFB800339C8A /* tls1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tls1.h; sourceTree = ""; }; + FB8946D719F6AFB800339C8A /* ts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ts.h; sourceTree = ""; }; + FB8946D819F6AFB800339C8A /* txt_db.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = txt_db.h; sourceTree = ""; }; + FB8946D919F6AFB800339C8A /* ui.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ui.h; sourceTree = ""; }; + FB8946DA19F6AFB800339C8A /* ui_compat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ui_compat.h; sourceTree = ""; }; + FB8946DB19F6AFB800339C8A /* whrlpool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = whrlpool.h; sourceTree = ""; }; + FB8946DC19F6AFB800339C8A /* x509.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = x509.h; sourceTree = ""; }; + FB8946DD19F6AFB800339C8A /* x509_vfy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = x509_vfy.h; sourceTree = ""; }; + FB8946DE19F6AFB800339C8A /* x509v3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = x509v3.h; sourceTree = ""; }; + FB8946E019F6AFB800339C8A /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libcrypto.a; sourceTree = ""; }; + FB8946E119F6AFB800339C8A /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libssl.a; sourceTree = ""; }; FB8946E519F6AFB800339C8A /* opus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus.h; sourceTree = ""; }; FB8946E619F6AFB800339C8A /* opus_defines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_defines.h; sourceTree = ""; }; FB8946E719F6AFB800339C8A /* opus_multistream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = opus_multistream.h; sourceTree = ""; }; @@ -302,6 +372,7 @@ FB9AFD3C1A7E111600872C98 /* AppAssetResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppAssetResponse.m; sourceTree = ""; }; FB9AFD3E1A7E127D00872C98 /* AppListResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppListResponse.h; sourceTree = ""; }; FB9AFD3F1A7E127D00872C98 /* AppListResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppListResponse.m; sourceTree = ""; }; + FBB460391B50ACE400F3099C /* Moonlight v1.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.0.xcdatamodel"; sourceTree = ""; }; FBD1C8E01A8AD69E00C6703C /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = ""; }; FBD1C8E11A8AD71400C6703C /* Logger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Logger.m; sourceTree = ""; }; FBD3494119FC9C04002D2A60 /* AppAssetManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppAssetManager.h; sourceTree = ""; }; @@ -323,6 +394,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 98A2E31229B5256E00CA17A7 /* OpenSSL.xcframework in Frameworks */, 9890CF6B203B7EE1006C4B06 /* libxml2.tbd in Frameworks */, 98CFB82F1CAD481B0048EF74 /* libmoonlight-common.a in Frameworks */, FB8946ED19F6AFE800339C8A /* libopus.a in Frameworks */, @@ -330,7 +402,6 @@ FB290CF419B2C406004C83CF /* CoreGraphics.framework in Frameworks */, FB290CF819B2C406004C83CF /* CoreData.framework in Frameworks */, 98181BED2791281100E43572 /* CoreMotion.framework in Frameworks */, - F74BEF9C2C1A705600224667 /* OpenSSL in Frameworks */, 98882A072AF60F7200C5A11C /* libavformat.a in Frameworks */, FB290CF619B2C406004C83CF /* UIKit.framework in Frameworks */, FB290CF219B2C406004C83CF /* Foundation.framework in Frameworks */, @@ -364,8 +435,6 @@ 84351B2E2C29AD6600A77989 /* Cells */, 84351B282C29AD6000A77989 /* LayoutOnScreenControlsViewController.h */, 84351B252C29AD6000A77989 /* LayoutOnScreenControlsViewController.m */, - 187F4B232E04633100EECC59 /* WidgetPanelStackView.h */, - 187F4B272E04658A00EECC59 /* WidgetPanelStackView.m */, 84351B262C29AD6000A77989 /* OSCProfilesTableViewController.h */, 84351B272C29AD6000A77989 /* OSCProfilesTableViewController.m */, 84351B2A2C29AD6000A77989 /* ToolBarContainerView.h */, @@ -384,14 +453,6 @@ path = Cells; sourceTree = ""; }; - 843667ED2D9D70A3004A7D7F /* PresetConfigs */ = { - isa = PBXGroup; - children = ( - 843667EF2D9D7173004A7D7F /* widgetTemplates.bin */, - ); - name = PresetConfigs; - sourceTree = ""; - }; 84FD0B492C312C0B006B5BE5 /* Localization */ = { isa = PBXGroup; children = ( @@ -437,7 +498,7 @@ children = ( 9896219423D15C2900211983 /* X1Kit */, 98AB2E7F1CAD46830089BB98 /* moonlight-common.xcodeproj */, - FB290CF919B2C406004C83CF /* VoidLink */, + FB290CF919B2C406004C83CF /* Moonlight */, FB1A67542132419700507771 /* Moonlight TV */, FB290CF019B2C406004C83CF /* Frameworks */, FB290CEF19B2C406004C83CF /* Products */, @@ -447,7 +508,7 @@ FB290CEF19B2C406004C83CF /* Products */ = { isa = PBXGroup; children = ( - FB290CEE19B2C406004C83CF /* VoidLink.app */, + FB290CEE19B2C406004C83CF /* Moonlight-ZWM.app */, ); name = Products; sourceTree = ""; @@ -461,6 +522,7 @@ 98882A0B2AF60F9000C5A11C /* libavformat.a */, 98882A042AF60F5300C5A11C /* libavutil.a */, 98882A092AF60F9000C5A11C /* libavutil.a */, + 98A2E31029B5256200CA17A7 /* OpenSSL.xcframework */, 98B9CE6C27B2144B00B473C4 /* AVKit.framework */, 98181BEC2791281100E43572 /* CoreMotion.framework */, 98181BE82791275D00E43572 /* libSDL2.a */, @@ -479,10 +541,10 @@ name = Frameworks; sourceTree = ""; }; - FB290CF919B2C406004C83CF /* VoidLink */ = { + FB290CF919B2C406004C83CF /* Moonlight */ = { isa = PBXGroup; children = ( - 84D8EB932C5146AD00FC10A9 /* VoidLink-Bridging-Header.h */, + 84D8EB932C5146AD00FC10A9 /* Moonlight-Bridging-Header.h */, 84FD0B492C312C0B006B5BE5 /* Localization */, 8454AC682C31907F00F0A302 /* iPad.storyboard */, 8454AC6C2C319BDA00F0A302 /* iPhone.storyboard */, @@ -495,15 +557,7 @@ FBD3495F1A004453002D2A60 /* Database */, FB290CFA19B2C406004C83CF /* Supporting Files */, FB290D0219B2C406004C83CF /* AppDelegate.h */, - 18341A022DEB65AB0094E5F2 /* FixedTintImageView.h */, - 18341A032DEB662C0094E5F2 /* FixedTintImageView.m */, FB290D0319B2C406004C83CF /* AppDelegate.m */, - 848F45682DDCD0D600581E36 /* HostCardView.h */, - 848F45692DDCD12500581E36 /* HostCardView.m */, - 841BAC8F2DE35BEC00DA639E /* ThemeManager.h */, - 841BAC912DE35D6B00DA639E /* ThemeManager.m */, - 847D2FD82DDA00C800937A62 /* MenuSectionView.h */, - 847D2FDA2DDA015F00937A62 /* MenuSectionView.m */, FBDE86DE19F7A837001C18A8 /* UIComputerView.h */, FBDE86DF19F7A837001C18A8 /* UIComputerView.m */, FBDE86E419F82297001C18A8 /* UIAppView.h */, @@ -517,13 +571,13 @@ FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */, 843E93BD2C41528700B1651F /* OrientationHelper.swift */, ); - path = VoidLink; + name = Moonlight; + path = Limelight; sourceTree = ""; }; FB290CFA19B2C406004C83CF /* Supporting Files */ = { isa = PBXGroup; children = ( - 843667ED2D9D70A3004A7D7F /* PresetConfigs */, FB290CFB19B2C406004C83CF /* Limelight-Info.plist */, FB290CFC19B2C406004C83CF /* InfoPlist.strings */, FB290CFF19B2C406004C83CF /* main.m */, @@ -634,15 +688,13 @@ FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */, FB89462419F646E200339C8A /* MainFrameViewController.h */, FB89462519F646E200339C8A /* MainFrameViewController.m */, - 189AD2962DE743B700E24B88 /* HostCollectionViewController.h */, - 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */, FB89462619F646E200339C8A /* StreamFrameViewController.h */, FB89462719F646E200339C8A /* StreamFrameViewController.m */, FBD3494E19FF2174002D2A60 /* SettingsViewController.h */, FBD3494F19FF2174002D2A60 /* SettingsViewController.m */, FB4A23B61A9D3637004D2EF2 /* LoadingFrameViewController.h */, FB4A23B71A9D3637004D2EF2 /* LoadingFrameViewController.m */, - 84E1CDEE2C4F688E00547904 /* ToolBoxViewController.swift */, + 84E1CDEE2C4F688E00547904 /* CommandManagerViewController.swift */, ); path = ViewControllers; sourceTree = ""; @@ -650,11 +702,120 @@ FB89468F19F6AFB800339C8A /* libs */ = { isa = PBXGroup; children = ( + FB89469119F6AFB800339C8A /* openssl */, FB8946E219F6AFB800339C8A /* opus */, ); path = libs; sourceTree = ""; }; + FB89469119F6AFB800339C8A /* openssl */ = { + isa = PBXGroup; + children = ( + FB89469219F6AFB800339C8A /* include */, + FB8946DF19F6AFB800339C8A /* lib */, + ); + path = openssl; + sourceTree = ""; + }; + FB89469219F6AFB800339C8A /* include */ = { + isa = PBXGroup; + children = ( + FB89469319F6AFB800339C8A /* openssl */, + ); + path = include; + sourceTree = ""; + }; + FB89469319F6AFB800339C8A /* openssl */ = { + isa = PBXGroup; + children = ( + FB89469419F6AFB800339C8A /* aes.h */, + FB89469519F6AFB800339C8A /* asn1.h */, + FB89469619F6AFB800339C8A /* asn1_mac.h */, + FB89469719F6AFB800339C8A /* asn1t.h */, + FB89469819F6AFB800339C8A /* bio.h */, + FB89469919F6AFB800339C8A /* blowfish.h */, + FB89469A19F6AFB800339C8A /* bn.h */, + FB89469B19F6AFB800339C8A /* buffer.h */, + FB89469C19F6AFB800339C8A /* camellia.h */, + FB89469D19F6AFB800339C8A /* cast.h */, + FB89469E19F6AFB800339C8A /* cmac.h */, + FB89469F19F6AFB800339C8A /* cms.h */, + FB8946A019F6AFB800339C8A /* comp.h */, + FB8946A119F6AFB800339C8A /* conf.h */, + FB8946A219F6AFB800339C8A /* conf_api.h */, + FB8946A319F6AFB800339C8A /* crypto.h */, + FB8946A419F6AFB800339C8A /* des.h */, + FB8946A519F6AFB800339C8A /* des_old.h */, + FB8946A619F6AFB800339C8A /* dh.h */, + FB8946A719F6AFB800339C8A /* dsa.h */, + FB8946A819F6AFB800339C8A /* dso.h */, + FB8946A919F6AFB800339C8A /* dtls1.h */, + FB8946AA19F6AFB800339C8A /* e_os2.h */, + FB8946AB19F6AFB800339C8A /* ebcdic.h */, + FB8946AC19F6AFB800339C8A /* ec.h */, + FB8946AD19F6AFB800339C8A /* ecdh.h */, + FB8946AE19F6AFB800339C8A /* ecdsa.h */, + FB8946AF19F6AFB800339C8A /* engine.h */, + FB8946B019F6AFB800339C8A /* err.h */, + FB8946B119F6AFB800339C8A /* evp.h */, + FB8946B219F6AFB800339C8A /* hmac.h */, + FB8946B319F6AFB800339C8A /* idea.h */, + FB8946B419F6AFB800339C8A /* krb5_asn.h */, + FB8946B519F6AFB800339C8A /* kssl.h */, + FB8946B619F6AFB800339C8A /* lhash.h */, + FB8946B719F6AFB800339C8A /* md4.h */, + FB8946B819F6AFB800339C8A /* md5.h */, + FB8946B919F6AFB800339C8A /* mdc2.h */, + FB8946BA19F6AFB800339C8A /* modes.h */, + FB8946BB19F6AFB800339C8A /* obj_mac.h */, + FB8946BC19F6AFB800339C8A /* objects.h */, + FB8946BD19F6AFB800339C8A /* ocsp.h */, + FB8946BE19F6AFB800339C8A /* opensslconf.h */, + FB8946BF19F6AFB800339C8A /* opensslv.h */, + FB8946C019F6AFB800339C8A /* ossl_typ.h */, + FB8946C119F6AFB800339C8A /* pem.h */, + FB8946C219F6AFB800339C8A /* pem2.h */, + FB8946C319F6AFB800339C8A /* pkcs12.h */, + FB8946C419F6AFB800339C8A /* pkcs7.h */, + FB8946C519F6AFB800339C8A /* pqueue.h */, + FB8946C619F6AFB800339C8A /* rand.h */, + FB8946C719F6AFB800339C8A /* rc2.h */, + FB8946C819F6AFB800339C8A /* rc4.h */, + FB8946C919F6AFB800339C8A /* ripemd.h */, + FB8946CA19F6AFB800339C8A /* rsa.h */, + FB8946CB19F6AFB800339C8A /* safestack.h */, + FB8946CC19F6AFB800339C8A /* seed.h */, + FB8946CD19F6AFB800339C8A /* sha.h */, + FB8946CE19F6AFB800339C8A /* srp.h */, + FB8946CF19F6AFB800339C8A /* srtp.h */, + FB8946D019F6AFB800339C8A /* ssl.h */, + FB8946D119F6AFB800339C8A /* ssl2.h */, + FB8946D219F6AFB800339C8A /* ssl23.h */, + FB8946D319F6AFB800339C8A /* ssl3.h */, + FB8946D419F6AFB800339C8A /* stack.h */, + FB8946D519F6AFB800339C8A /* symhacks.h */, + FB8946D619F6AFB800339C8A /* tls1.h */, + FB8946D719F6AFB800339C8A /* ts.h */, + FB8946D819F6AFB800339C8A /* txt_db.h */, + FB8946D919F6AFB800339C8A /* ui.h */, + FB8946DA19F6AFB800339C8A /* ui_compat.h */, + FB8946DB19F6AFB800339C8A /* whrlpool.h */, + FB8946DC19F6AFB800339C8A /* x509.h */, + FB8946DD19F6AFB800339C8A /* x509_vfy.h */, + FB8946DE19F6AFB800339C8A /* x509v3.h */, + ); + path = openssl; + sourceTree = ""; + }; + FB8946DF19F6AFB800339C8A /* lib */ = { + isa = PBXGroup; + children = ( + FB8946E019F6AFB800339C8A /* libcrypto.a */, + FB8946E119F6AFB800339C8A /* libssl.a */, + ); + path = lib; + sourceTree = ""; + }; FB8946E219F6AFB800339C8A /* opus */ = { isa = PBXGroup; children = ( @@ -752,9 +913,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - FB290CED19B2C406004C83CF /* VoidLink */ = { + FB290CED19B2C406004C83CF /* Moonlight-ZWM */ = { isa = PBXNativeTarget; - buildConfigurationList = FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "VoidLink" */; + buildConfigurationList = FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "Moonlight-ZWM" */; buildPhases = ( FB290CEA19B2C406004C83CF /* Sources */, FB290CEB19B2C406004C83CF /* Frameworks */, @@ -765,9 +926,9 @@ dependencies = ( 98AB2E861CAD468B0089BB98 /* PBXTargetDependency */, ); - name = VoidLink; + name = "Moonlight-ZWM"; productName = Limelight; - productReference = FB290CEE19B2C406004C83CF /* VoidLink.app */; + productReference = FB290CEE19B2C406004C83CF /* Moonlight-ZWM.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -785,7 +946,7 @@ }; }; }; - buildConfigurationList = FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "VoidLink" */; + buildConfigurationList = FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "Moonlight" */; compatibilityVersion = "Xcode 8.0"; developmentRegion = en; hasScannedForEncodings = 0; @@ -797,9 +958,6 @@ "zh-HK", ); mainGroup = FB290CE519B2C406004C83CF; - packageReferences = ( - F74BEF9A2C1A705600224667 /* XCRemoteSwiftPackageReference "OpenSSL-Package" */, - ); productRefGroup = FB290CEF19B2C406004C83CF /* Products */; projectDirPath = ""; projectReferences = ( @@ -810,7 +968,7 @@ ); projectRoot = ""; targets = ( - FB290CED19B2C406004C83CF /* VoidLink */, + FB290CED19B2C406004C83CF /* Moonlight-ZWM */, ); }; /* End PBXProject section */ @@ -842,7 +1000,6 @@ FB89463819F6473800339C8A /* Launch Screen.xib in Resources */, 8454AC662C31907F00F0A302 /* iPad.storyboard in Resources */, 8454AC6A2C319BDA00F0A302 /* iPhone.storyboard in Resources */, - 843667F02D9D7173004A7D7F /* widgetTemplates.bin in Resources */, 84FD0B542C3134A6006B5BE5 /* Localizable.xcstrings in Resources */, 84351B5D2C29ADBE00A77989 /* ProfileTableViewCell.xib in Resources */, ); @@ -871,9 +1028,7 @@ 843E93BE2C41528700B1651F /* OrientationHelper.swift in Sources */, FB4678FF1A565DAC00377732 /* WakeOnLanManager.m in Sources */, 84E1CDEC2C4F67D300547904 /* CommandManager.swift in Sources */, - 847D2FDB2DDA015F00937A62 /* MenuSectionView.m in Sources */, FB53E1431BE5DC4400CD6ECE /* IdManager.m in Sources */, - 189AD29A2DE7446000E24B88 /* HostCollectionViewController.m in Sources */, 9897B6A1221260EF00966419 /* Controller.m in Sources */, 84351B112C29ACCB00A77989 /* OSCProfilesManager.m in Sources */, FB89462919F646E200339C8A /* mkcert.c in Sources */, @@ -891,18 +1046,15 @@ 84351B0F2C29ACCB00A77989 /* OnScreenButtonState.m in Sources */, FB89462B19F646E200339C8A /* StreamView.m in Sources */, 840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */, - 187F4B282E04658A00EECC59 /* WidgetPanelStackView.m in Sources */, FB4678FA1A55FFAD00377732 /* DiscoveryManager.m in Sources */, - 841BAC922DE35D6B00DA639E /* ThemeManager.m in Sources */, 98D5856D1C0EA79600F6CC00 /* TemporaryHost.m in Sources */, FB89463519F646E200339C8A /* MainFrameViewController.m in Sources */, FBD1C8E21A8AD71400C6703C /* Logger.m in Sources */, FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */, - 848F456A2DDCD12500581E36 /* HostCardView.m in Sources */, FB89463619F646E200339C8A /* StreamFrameViewController.m in Sources */, 9827E7A32514366900F25707 /* HapticContext.m in Sources */, 9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */, - 84E1CDEF2C4F688E00547904 /* ToolBoxViewController.swift in Sources */, + 84E1CDEF2C4F688E00547904 /* CommandManagerViewController.swift in Sources */, 844CD0EB2C7F8500004861A7 /* PureNativeTouchHandler.m in Sources */, 84351B102C29ACCB00A77989 /* OSCProfile.m in Sources */, 84351B2C2C29AD6100A77989 /* OSCProfilesTableViewController.m in Sources */, @@ -925,7 +1077,6 @@ FB9AFD3A1A7E05CE00872C98 /* ServerInfoResponse.m in Sources */, 84351B2B2C29AD6100A77989 /* LayoutOnScreenControlsViewController.m in Sources */, 84351B5C2C29ADBE00A77989 /* ProfileTableViewCell.m in Sources */, - 18341A042DEB662C0094E5F2 /* FixedTintImageView.m in Sources */, FB89463119F646E200339C8A /* StreamManager.m in Sources */, 84351B2D2C29AD6100A77989 /* ToolBarContainerView.m in Sources */, 988FCD41293B091B003050E2 /* KeyboardInputField.m in Sources */, @@ -984,7 +1135,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -1040,7 +1190,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -1097,10 +1246,10 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = x; - DEVELOPMENT_TEAM = FRL23UV4N9; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = 476L3GD396; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "VoidLink/Limelight-Prefix.pch"; + GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch"; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, @@ -1114,10 +1263,9 @@ "$(PROJECT_DIR)/Limelight/Localization", "$(PROJECT_DIR)/Limelight/Database", ); - INFOPLIST_FILE = "VoidLink/Limelight-Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = "VoidLink - beta"; + INFOPLIST_FILE = "Limelight/Limelight-Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = MoonlightZWM; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1134,14 +1282,14 @@ "$(PROJECT_DIR)/libs/SDL2/lib/iOS-Sim", "$(PROJECT_DIR)/libs/FFmpeg/lib/iOS-Sim", ); - MARKETING_VERSION = 0.0.1; - PRODUCT_BUNDLE_IDENTIFIER = com.voidlink.tf.debug7.iOS; + MARKETING_VERSION = 9.0.263; + PRODUCT_BUNDLE_IDENTIFIER = "com.moonlight-stream.Moonlight-ios-gyro-zwm"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = NO; - SWIFT_OBJC_BRIDGING_HEADER = "VoidLink/VoidLink-Bridging-Header.h"; - SWIFT_OBJC_INTERFACE_HEADER_NAME = "VoidLink-Swift.h"; + SWIFT_OBJC_BRIDGING_HEADER = "Limelight/Moonlight-Bridging-Header.h"; + SWIFT_OBJC_INTERFACE_HEADER_NAME = "Moonlight-Swift.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; @@ -1156,10 +1304,10 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = x; - DEVELOPMENT_TEAM = FRL23UV4N9; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = 476L3GD396; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "VoidLink/Limelight-Prefix.pch"; + GCC_PREFIX_HEADER = "Limelight/Limelight-Prefix.pch"; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, @@ -1173,10 +1321,9 @@ "$(PROJECT_DIR)/Limelight/Localization", "$(PROJECT_DIR)/Limelight/Database", ); - INFOPLIST_FILE = "VoidLink/Limelight-Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = "VoidLink - beta"; + INFOPLIST_FILE = "Limelight/Limelight-Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = MoonlightZWM; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1193,14 +1340,14 @@ "$(PROJECT_DIR)/libs/SDL2/lib/iOS-Sim", "$(PROJECT_DIR)/libs/FFmpeg/lib/iOS-Sim", ); - MARKETING_VERSION = 0.0.1; - PRODUCT_BUNDLE_IDENTIFIER = com.voidlink.tf.iOS; + MARKETING_VERSION = 9.0.263; + PRODUCT_BUNDLE_IDENTIFIER = "com.moonlight-stream.Moonlight-ios-gyro-zwm"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SKIP_INSTALL = NO; SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OBJC_BRIDGING_HEADER = "VoidLink/VoidLink-Bridging-Header.h"; - SWIFT_OBJC_INTERFACE_HEADER_NAME = "VoidLink-Swift.h"; + SWIFT_OBJC_BRIDGING_HEADER = "Limelight/Moonlight-Bridging-Header.h"; + SWIFT_OBJC_INTERFACE_HEADER_NAME = "Moonlight-Swift.h"; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; @@ -1211,7 +1358,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "VoidLink" */ = { + FB290CE919B2C406004C83CF /* Build configuration list for PBXProject "Moonlight" */ = { isa = XCConfigurationList; buildConfigurations = ( FB290D1E19B2C406004C83CF /* Debug */, @@ -1220,7 +1367,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "VoidLink" */ = { + FB290D2019B2C406004C83CF /* Build configuration list for PBXNativeTarget "Moonlight-ZWM" */ = { isa = XCConfigurationList; buildConfigurations = ( FB290D2119B2C406004C83CF /* Debug */, @@ -1231,33 +1378,27 @@ }; /* End XCConfigurationList section */ -/* Begin XCRemoteSwiftPackageReference section */ - F74BEF9A2C1A705600224667 /* XCRemoteSwiftPackageReference "OpenSSL-Package" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/krzyzanowskim/OpenSSL-Package.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 3.1.5004; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - F74BEF9B2C1A705600224667 /* OpenSSL */ = { - isa = XCSwiftPackageProductDependency; - package = F74BEF9A2C1A705600224667 /* XCRemoteSwiftPackageReference "OpenSSL-Package" */; - productName = OpenSSL; - }; -/* End XCSwiftPackageProductDependency section */ - /* Begin XCVersionGroup section */ FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */ = { isa = XCVersionGroup; children = ( - 18BF141D2E0D7A00009DEE4F /* VoidLink v1.0.xcdatamodel */, + 9874E8962AE95E1D00130A3C /* Moonlight v1.10.xcdatamodel */, + 986E28A528EA989100758361 /* Moonlight v1.9.xcdatamodel */, + 984CD023288A310D0097D2D4 /* Moonlight v1.8.xcdatamodel */, + 566E9D2B2770B23A00EF7BFE /* Moonlight v1.7.xcdatamodel */, + 9819CC25254F2734008A7C8E /* Moonlight v1.6.xcdatamodel */, + 98783FEA242EAC5D00F00EF4 /* Moonlight v1.5.xcdatamodel */, + 98608BDD22DC0C2C000E5672 /* Moonlight v1.4.xcdatamodel */, + 98517B1B21CE0A9000481377 /* Moonlight v1.3.xcdatamodel */, + 986CCE6C2133E45300168291 /* Moonlight v1.2.xcdatamodel */, + 98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */, + FB53E1441BE5DCBC00CD6ECE /* Moonlight v1.0-2.xcdatamodel */, + FBB460391B50ACE400F3099C /* Moonlight v1.0.xcdatamodel */, + FB6549621A60B4A9001C8F39 /* Limelight 0.3.1.xcdatamodel */, + FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */, FB290D0619B2C406004C83CF /* Limelight.xcdatamodel */, ); - currentVersion = 18BF141D2E0D7A00009DEE4F /* VoidLink v1.0.xcdatamodel */; + currentVersion = 9874E8962AE95E1D00130A3C /* Moonlight v1.10.xcdatamodel */; path = Limelight.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; diff --git a/VoidLink/.DS_Store b/VoidLink/.DS_Store new file mode 100644 index 00000000..e3c74898 Binary files /dev/null and b/VoidLink/.DS_Store differ diff --git a/VoidLink/Database/.DS_Store b/VoidLink/Database/.DS_Store new file mode 100644 index 00000000..0142a1b3 Binary files /dev/null and b/VoidLink/Database/.DS_Store differ diff --git a/VoidLink/Database/DataManager.h b/VoidLink/Database/DataManager.h index a989c334..d02e049c 100644 --- a/VoidLink/Database/DataManager.h +++ b/VoidLink/Database/DataManager.h @@ -47,6 +47,7 @@ typedef NS_ENUM(NSInteger, SettingsMenuMode) { width:(NSInteger)width audioConfig:(NSInteger)audioConfig onscreenControls:(NSInteger)onscreenControls + motionMode:(NSInteger)motionMode keyboardToggleFingers:(NSInteger)keyboardToggleFingers oscLayoutToolFingers:(NSInteger)oscLayoutToolFingers slideToSettingsScreenEdge:(NSInteger)slideToSettingsScreenEdge diff --git a/VoidLink/Database/DataManager.m b/VoidLink/Database/DataManager.m index 2de8f0ce..70ad8d60 100644 --- a/VoidLink/Database/DataManager.m +++ b/VoidLink/Database/DataManager.m @@ -61,6 +61,7 @@ width:(NSInteger)width audioConfig:(NSInteger)audioConfig onscreenControls:(NSInteger)onscreenControls + motionMode:(NSInteger)motionMode keyboardToggleFingers:(NSInteger)keyboardToggleFingers oscLayoutToolFingers:(NSInteger)oscLayoutToolFingers slideToSettingsScreenEdge:(NSInteger)slideToSettingsScreenEdge @@ -99,6 +100,7 @@ settingsToSave.width = [NSNumber numberWithInteger:width]; settingsToSave.audioConfig = [NSNumber numberWithInteger:audioConfig]; settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls]; + settingsToSave.motionMode = [NSNumber numberWithInteger:motionMode]; settingsToSave.keyboardToggleFingers = [NSNumber numberWithInteger:(uint16_t)keyboardToggleFingers]; settingsToSave.oscLayoutToolFingers = [NSNumber numberWithInteger:(uint16_t)oscLayoutToolFingers]; settingsToSave.slideToSettingsScreenEdge = [NSNumber numberWithInteger:(uint32_t)slideToSettingsScreenEdge]; diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h index 6a2e9f72..015884ca 100644 --- a/VoidLink/Database/TemporarySettings.h +++ b/VoidLink/Database/TemporarySettings.h @@ -25,6 +25,7 @@ @property (nonatomic, retain) NSNumber * width; @property (nonatomic, retain) NSNumber * audioConfig; @property (nonatomic, retain) NSNumber * onscreenControls; +@property (nonatomic, retain) NSNumber * motionMode; @property (nonatomic, retain) NSNumber * keyboardToggleFingers; @property (nonatomic, retain) NSNumber * oscLayoutToolFingers; @property (nonatomic, retain) NSNumber * slideToSettingsScreenEdge; diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m index 7a14d5f7..03d70d9e 100644 --- a/VoidLink/Database/TemporarySettings.m +++ b/VoidLink/Database/TemporarySettings.m @@ -89,6 +89,7 @@ self.multiController = settings.multiController; self.swapABXYButtons = settings.swapABXYButtons; self.onscreenControls = settings.onscreenControls; + self.motionMode = settings.motionMode; self.reverseMouseWheelDirection = settings.reverseMouseWheelDirection; self.asyncNativeTouchPriority = settings.asyncNativeTouchPriority; self.btMouseSupport = settings.btMouseSupport; diff --git a/VoidLink/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x-6.png b/VoidLink/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x-6.png new file mode 100644 index 00000000..cf7f81b3 Binary files /dev/null and b/VoidLink/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x-6.png differ diff --git a/VoidLink/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/VoidLink/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index cf7f81b3..13ce4929 100644 Binary files a/VoidLink/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/VoidLink/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/VoidLink/Input/.DS_Store b/VoidLink/Input/.DS_Store new file mode 100644 index 00000000..32e3e7ea Binary files /dev/null and b/VoidLink/Input/.DS_Store differ diff --git a/VoidLink/Input/Controller.h b/VoidLink/Input/Controller.h index 6e4511cf..acbbf9f7 100644 --- a/VoidLink/Input/Controller.h +++ b/VoidLink/Input/Controller.h @@ -10,6 +10,9 @@ @import GameController; @import CoreHaptics; +#if !TARGET_OS_TV + @import CoreMotion; +#endif @interface Controller : NSObject @@ -43,6 +46,12 @@ typedef struct { @property (nonatomic) NSTimer* _Nullable gyroTimer; @property (nonatomic) GCRotationRate lastGyroSample; +#if !TARGET_OS_TV +@property (nonatomic) CMMotionManager * _Nullable motionManager; +@property (nonatomic) CMAcceleration lastDeviceAccelSample; +@property (nonatomic) CMRotationRate lastDeviceGyroSample; +#endif + @property (nonatomic) NSTimer* _Nullable batteryTimer; @property (nonatomic) GCDeviceBatteryState lastBatteryState; @property (nonatomic) float lastBatteryLevel; diff --git a/VoidLink/Input/ControllerSupport.m b/VoidLink/Input/ControllerSupport.m index d50a4126..bf90bf1b 100644 --- a/VoidLink/Input/ControllerSupport.m +++ b/VoidLink/Input/ControllerSupport.m @@ -18,6 +18,9 @@ #include "Limelight.h" @import GameController; +#if !TARGET_OS_TV + @import CoreMotion; +#endif @import AudioToolbox; static const double MOUSE_SPEED_DIVISOR = 1.25; @@ -49,6 +52,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; char _controllerNumbers; bool _multiController; bool _swapABXYButtons; + int _motionMode; bool _captureMouse; } @@ -90,18 +94,111 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; - (void) setMotionEventState:(uint16_t)controllerNumber motionType:(uint8_t)motionType reportRateHz:(uint16_t)reportRateHz { + if (@available(iOS 14.0, tvOS 14.0, *)) { Controller* controller = [_controllers objectForKey:[NSNumber numberWithInteger:controllerNumber]]; - if (controller == nil) { - // No connected controller for this player - return; - } - - if (controller.gamepad.motion == nil) { - // No motion supported for this controller - return; - } - + #if !TARGET_OS_TV //tvOS has no device motion + NSInteger motionMode = _motionMode; //motionMode 0 = auto | 1 = always device | 2 = always controller + if(motionMode !=2 && controllerNumber < 2){ + if(controller == nil || controller.gamepad.motion == nil || motionMode == 1){ + //Player has no controller *or* no motion for controller 1 *or* wants to override controller 1 motion with device motion + //using device motion + if (controller == nil) { + // No connected controller for this player, use the _oscController instead + controller = _oscController; + } + if(!controller.motionManager) { + controller.motionManager = [[CMMotionManager alloc] init]; + } + + switch (motionType) { + case LI_MOTION_TYPE_ACCEL: + [controller.accelTimer invalidate]; + controller.accelTimer = nil; + + // Reset the last motion sample + CMAcceleration emptyDeviceAccelSample = {}; + controller.lastDeviceAccelSample = emptyDeviceAccelSample; + + {dispatch_sync(dispatch_get_main_queue(), ^{ + controller.accelTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / reportRateHz repeats:YES block:^(NSTimer *timer) { + // Don't send duplicate samples + CMAcceleration lastDeviceAccelSample = controller.lastDeviceAccelSample; + CMAcceleration deviceAccelSample = controller.motionManager.deviceMotion.userAcceleration; + //userAcceleration does not contain gravity, add gravity to x, y and z values: + deviceAccelSample.x += controller.motionManager.deviceMotion.gravity.x; + deviceAccelSample.y += controller.motionManager.deviceMotion.gravity.y; + deviceAccelSample.z += controller.motionManager.deviceMotion.gravity.z; + + if (memcmp(&deviceAccelSample, &lastDeviceAccelSample, sizeof(deviceAccelSample)) == 0) { + return; + } + controller.lastDeviceAccelSample = deviceAccelSample; + + // Convert g to m/s^2 + if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){ //check for landscape left or landscape right + LiSendControllerMotionEvent((uint8_t)controllerNumber, + LI_MOTION_TYPE_ACCEL, + deviceAccelSample.y * -9.80665f, + deviceAccelSample.z * -9.80665f, + deviceAccelSample.x * -9.80665f); + } + else{ + LiSendControllerMotionEvent((uint8_t)controllerNumber, + LI_MOTION_TYPE_ACCEL, + deviceAccelSample.y * +9.80665f, + deviceAccelSample.z * -9.80665f, + deviceAccelSample.x * +9.80665f); + } + }]; + });} + break; + case LI_MOTION_TYPE_GYRO: + [controller.gyroTimer invalidate]; + controller.gyroTimer = nil; + + // Reset the last motion sample + CMRotationRate emptyDeviceGyroSample = {}; + controller.lastDeviceGyroSample = emptyDeviceGyroSample; + + [controller.motionManager startDeviceMotionUpdates]; + + dispatch_sync(dispatch_get_main_queue(), ^{ + controller.gyroTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / reportRateHz repeats:YES block:^(NSTimer *timer) { + + // Don't send duplicate samples + CMRotationRate lastDeviceGyroSample = controller.lastDeviceGyroSample; + CMRotationRate deviceGyroSample = controller.motionManager.deviceMotion.rotationRate; + if (memcmp(&deviceGyroSample, &lastDeviceGyroSample, sizeof(deviceGyroSample)) == 0) { + return; + } + controller.lastDeviceGyroSample = deviceGyroSample; + + // Convert rad/s to deg/s + if(UIApplication.sharedApplication.windows.firstObject.windowScene.interfaceOrientation == 4){//check for landscape left or landscape right + LiSendControllerMotionEvent((uint8_t)controllerNumber, + LI_MOTION_TYPE_GYRO, + deviceGyroSample.y * 57.2957795f, + deviceGyroSample.z * 57.2957795f, + deviceGyroSample.x * 57.2957795f); + } + else{ + LiSendControllerMotionEvent((uint8_t)controllerNumber, + LI_MOTION_TYPE_GYRO, + deviceGyroSample.y * -57.2957795f, + deviceGyroSample.z * 57.2957795f, + deviceGyroSample.x * -57.2957795f); + } + + }]; + }); + break; + } + return; + } + } + #endif + switch (motionType) { case LI_MOTION_TYPE_ACCEL: [controller.accelTimer invalidate]; @@ -1108,6 +1205,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; _controllerNumbers = 0; _multiController = streamConfig.multiController; _swapABXYButtons = streamConfig.swapABXYButtons; + _motionMode = streamConfig.motionMode; _delegate = delegate; _oscController = [[Controller alloc] init]; @@ -1283,6 +1381,11 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; } [_controllers removeAllObjects]; + #if !TARGET_OS_TV + [self cleanupControllerMotion:_oscController]; + [_oscController.motionManager stopDeviceMotionUpdates]; + #endif + for (GCController* controller in [GCController controllers]) { if ([ControllerSupport isSupportedGamepad:controller]) { [self unregisterControllerCallbacks:controller]; diff --git a/VoidLink/Input/OnScreenControls.m b/VoidLink/Input/OnScreenControls.m index f245cf87..bd799889 100644 --- a/VoidLink/Input/OnScreenControls.m +++ b/VoidLink/Input/OnScreenControls.m @@ -13,6 +13,9 @@ #import "CustomTapGestureRecognizer.h" #import "Controller.h" #include "Limelight.h" +#if !TARGET_OS_TV + #import +#endif #import "OnScreenButtonState.h" #import "OSCProfilesManager.h" #import "DataManager.h" diff --git a/VoidLink/Limelight-Info.plist b/VoidLink/Limelight-Info.plist index 1a5aebb7..939e285e 100644 --- a/VoidLink/Limelight-Info.plist +++ b/VoidLink/Limelight-Info.plist @@ -58,6 +58,8 @@ NSLocalNetworkUsageDescription Moonlight uses the local network to connect to your gaming PC for streaming. + NSMotionUsageDescription + Moonlight uses the device Gyro and Acceleration data to emulate motion controls when streaming. UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents index 6f29093e..24f3f953 100644 --- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents +++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -21,17 +21,18 @@ - - + + + @@ -39,25 +40,23 @@ + - - - + - - \ No newline at end of file + diff --git a/VoidLink/Stream/.DS_Store b/VoidLink/Stream/.DS_Store new file mode 100644 index 00000000..f4754808 Binary files /dev/null and b/VoidLink/Stream/.DS_Store differ diff --git a/VoidLink/Stream/StreamConfiguration.h b/VoidLink/Stream/StreamConfiguration.h index 52d59cae..effdc62c 100644 --- a/VoidLink/Stream/StreamConfiguration.h +++ b/VoidLink/Stream/StreamConfiguration.h @@ -5,9 +5,6 @@ // Created by Diego Waxemberg on 10/20/14. // Copyright (c) 2014 Moonlight Stream. All rights reserved. // -// Modified by True砖家 since 2024.8.10 -// Copyright © 2024 True砖家 @ Bilibili. All rights reserved. -// @interface StreamConfiguration : NSObject @@ -30,7 +27,8 @@ @property BOOL optimizeGameSettings; @property BOOL playAudioOnPC; @property BOOL swapABXYButtons; -@property BOOL asyncNativeTouchPriority; +@property int motionMode; +@property BOOL largerStickLR1; @property int audioConfiguration; @property int supportedVideoFormats; @property BOOL multiController; diff --git a/VoidLink/Stream/StreamConfiguration.m b/VoidLink/Stream/StreamConfiguration.m index 306f9ced..11089f26 100644 --- a/VoidLink/Stream/StreamConfiguration.m +++ b/VoidLink/Stream/StreamConfiguration.m @@ -9,5 +9,5 @@ #import "StreamConfiguration.h" @implementation StreamConfiguration -@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444; +@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, motionMode, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444; @end diff --git a/VoidLink/ViewControllers/.DS_Store b/VoidLink/ViewControllers/.DS_Store new file mode 100644 index 00000000..96196bc6 Binary files /dev/null and b/VoidLink/ViewControllers/.DS_Store differ diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index 9369624a..900af2d2 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -4,9 +4,6 @@ // Created by Diego Waxemberg on 1/17/14. // Copyright (c) 2014 Moonlight Stream. All rights reserved. // -// Modified by True砖家 since 2024.6.29 -// Copyright © 2024 True砖家 @ Bilibili. All rights reserved. -// @import ImageIO; @@ -32,9 +29,7 @@ #import "LocalizationHelper.h" #import "CustomEdgeSlideGestureRecognizer.h" #import "DataManager.h" -#import "ThemeManager.h" -#import "FixedTintImageView.h" -#import "VoidLink-Swift.h" // not used yet. +#import "Moonlight-Swift.h" // not used yet. #if !TARGET_OS_TV #import "SettingsViewController.h" @@ -48,11 +43,6 @@ @implementation MainFrameViewController { UILabel* waterMark; - UIBarButtonItem* _addHostButton; - UIBarButtonItem* _helpButton; - UIBarButtonItem* _upButton; - - UILabel* hostViewTitleLabel; //CGFloat recordedScreenWidth; NSOperationQueue* _opQueue; TemporaryHost* _selectedHost; @@ -64,15 +54,11 @@ StreamConfiguration* _streamConfig; UIAlertController* _pairAlert; LoadingFrameViewController* _loadingFrame; + UIScrollView* hostScrollView; FrontViewPosition currentPosition; NSArray* _sortedAppList; NSCache* _boxArtCache; bool _background; - UIView* menuSeparator; - UIView* snapshot; - SettingsViewController* settingsViewController; - id navBarAppearanceStandard; - #if TARGET_OS_TV UITapGestureRecognizer* _menuRecognizer; #endif @@ -90,7 +76,7 @@ static NSMutableSet* hostList; self->_pairAlert = nil; [self->_discMan startDiscovery]; [self hideLoadingFrame: ^{ - [self switchToHostView]; + [self showHostSelectionView]; }]; }]]; [[self activeViewController] presentViewController:self->_pairAlert animated:YES completion:nil]; @@ -107,7 +93,7 @@ static NSMutableSet* hostList; [_discMan startDiscovery]; [self hideLoadingFrame: ^{ - [self switchToHostView]; + [self showHostSelectionView]; [[self activeViewController] presentViewController:failedDialog animated:YES completion:nil]; }]; } @@ -136,40 +122,32 @@ static NSMutableSet* hostList; }); } +- (void)disableUpButton { +#if !TARGET_OS_TV + [self->_upButton setTitle:nil]; + self.revealViewController.mainFrameIsInHostView = true; // to allow orientation change only in app view, tell top view controller the mainframe is not in host view + [self setNeedsUpdateAllowedOrientation]; +#endif +} + +- (void)enableUpButton { +#if !TARGET_OS_TV + [self->_upButton setTitle: [LocalizationHelper localizedStringForKey: @"Select New Host"]]; + self.revealViewController.mainFrameIsInHostView = false; // to allow orientation change only in app view, tell top view controller the mainframe is not in host view + [self setNeedsUpdateAllowedOrientation]; +#endif +} + - (void)updateTitle { - - if (@available(iOS 13.0, *)) { - NSDictionary* titleTextAttributes = @{ - NSFontAttributeName: [UIFont systemFontOfSize:20 weight:UIFontWeightMedium], - NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色 - }; - [navBarAppearanceStandard setValue:titleTextAttributes forKey:@"titleTextAttributes"]; - } - if (_selectedHost != nil) { self.title = _selectedHost.name; } else if ([hostList count] == 0) { - self.title = [LocalizationHelper localizedStringForKey: @"Searching for PCs on your network..."] ; } else { - if (@available(iOS 13.0, *)) { - NSDictionary* titleTextAttributes = @{ - NSFontAttributeName: [UIFont systemFontOfSize:22 weight:UIFontWeightMedium], - NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色 - }; - [navBarAppearanceStandard setValue:titleTextAttributes forKey:@"titleTextAttributes"]; - } - /* - self.navigationController.navigationBar.titleTextAttributes = @{ - NSFontAttributeName: [UIFont systemFontOfSize:24 weight:UIFontWeightSemibold], - NSForegroundColorAttributeName: [ThemeManager textColor] // 可选,设置标题颜色 - };*/ - self.title = [LocalizationHelper localizedStringForKey: @"Hosts" ]; - //self.title = nil; + self.title = [LocalizationHelper localizedStringForKey: @"Select Host" ]; } - [self applyNavBarAppearance]; } - (void)alreadyPaired { @@ -218,7 +196,7 @@ static NSMutableSet* hostList; [Utils addHelpOptionToDialog:applistAlert]; [applistAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]]; [self hideLoadingFrame: ^{ - [self switchToHostView]; + [self showHostSelectionView]; [[self activeViewController] presentViewController:applistAlert animated:YES completion:nil]; }]; host.state = StateOffline; @@ -319,7 +297,7 @@ static NSMutableSet* hostList; [self updateHostShortcuts]; } -- (void)switchToHostView { +- (void)showHostSelectionView { #if TARGET_OS_TV // Remove the menu button intercept to allow the app to exit // when at the host selection view. @@ -330,12 +308,11 @@ static NSMutableSet* hostList; _selectedHost = nil; _sortedAppList = nil; - // [self.collectionView removeFromSuperview]; // necessary for new scroll host view reloading mechanism - self.hostCollectionVC.view.hidden = NO; - self.collectionView.hidden = YES; [self updateTitle]; - self.navigationItem.rightBarButtonItems = @[_helpButton, _addHostButton]; - self.revealViewController.mainFrameIsInHostView = true; // to allow orientation change only in app view, tell top view controller the mainframe is not in host view + [self disableUpButton]; + [self.collectionView removeFromSuperview]; // necessary for new scroll host view reloading mechanism + [self.view setBackgroundColor:[UIColor darkGrayColor]]; + [self reloadScrollHostView]; // host view must be reloaded here } - (void) receivedAssetForApp:(TemporaryApp*)app { @@ -357,145 +334,41 @@ static NSMutableSet* hostList; [[self activeViewController] presentViewController:alert animated:YES completion:nil]; } -- (void)switchToAppView{ - //_appManager = [[AppAssetManager alloc] initWithCallback:self]; - [self.collectionView setCollectionViewLayout:self.collectionViewLayout]; - [self.collectionView reloadData]; //for new scroll host view reloading mechanism - // [self.view bringSubviewToFront:self.collectionView]; - self.hostCollectionVC.view.hidden = YES; - self.collectionView.hidden = NO; - self.collectionView.backgroundColor = [ThemeManager appBackgroundColor]; - //self.view.backgroundColor = [ThemeManager appBackgroundColor]; - - [self attachWaterMark]; - self.navigationItem.rightBarButtonItems = @[_upButton]; - self.revealViewController.mainFrameIsInHostView = false; - // [self disableNavigation]; - [self updateTitle]; - [self alreadyPaired]; - // self.navigationController.navigationBar.backgroundColor = [ThemeManager appBackgroundColor]; - // self.navigationController.navigationBar.translucent = NO; - //[self applyNavBarAppearance:navBarAppearance]; -} - -- (void)appButtonTappedForHost:(TemporaryHost *)host { - if (host.state != StateOnline) return; - _selectedHost = host; - if (host.state == StateOnline && host.pairState == PairStatePaired && host.appList.count > 0) { - [self switchToAppView]; - } -} - -- (void)launchButtonTappedForHost:(TemporaryHost *)host { - _selectedHost = host; - if (host.state == StateOnline && host.pairState == PairStatePaired && host.appList.count > 0) { - [self closeSettingViewAnimated:NO]; - [self switchToAppView]; - [self updateAppsForHost:_selectedHost]; - [self prepareToStreamApp:_sortedAppList.firstObject]; - [self performSegueWithIdentifier:@"createStreamFrame" sender:nil]; +- (void) hostClicked:(TemporaryHost *)host view:(UIView *)view { + // Treat clicks on offline hosts to be long clicks + // This shows the context menu with wake, delete, etc. rather + // than just hanging for a while and failing as we would in this + // code path. + if (host.state != StateOnline && view != nil) { + [self hostLongClicked:host view:view]; return; } -} - -- (void)wakeupButtonTappedForHost:(TemporaryHost *)host{ - _selectedHost = host; - if (host.state == StateOffline && host.pairState == PairStatePaired) { - UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Wake-On-LAN"] message:@"" preferredStyle:UIAlertControllerStyleAlert]; - [wolAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]]; - if (host.mac == nil || [host.mac isEqualToString:@"00:00:00:00:00:00"]) { - wolAlert.message = [LocalizationHelper localizedStringForKey: @"Host MAC unknown, unable to send WOL Packet"]; - } else { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [WakeOnLanManager wakeHost:host]; - }); - wolAlert.message = [LocalizationHelper localizedStringForKey:@"Successfully sent wake-up request. It may take a few moments for the PC to wake. If it never wakes up, ensure it's properly configured for Wake-on-LAN."]; - } - [[self activeViewController] presentViewController:wolAlert animated:YES completion:nil]; - } -} - -- (void)pairButtonTappedForHost:(TemporaryHost *)host{ - _selectedHost = host; - [self showLoadingFrame: ^{ - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - // Wait for the PC's status to be known - while (host.state == StateUnknown) { - sleep(1); - } - - // Don't bother polling if the server is already offline - if (host.state == StateOffline) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self hideLoadingFrame:^{ - [self switchToHostView]; - }]; - }); - return; - } - - HttpManager* hMan = [[HttpManager alloc] initWithHost:host]; - ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init]; - - // Exempt this host from discovery while handling the serverinfo request - [self->_discMan pauseDiscoveryForHost:host]; - [hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest:false] - fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]]; - [self->_discMan resumeDiscoveryForHost:host]; - - if (![serverInfoResp isStatusOk]) { - Log(LOG_W, @"Failed to get server info: %@", serverInfoResp.statusMessage); - dispatch_async(dispatch_get_main_queue(), ^{ - if (host != self->_selectedHost) { - [self hideLoadingFrame:nil]; - return; - } - - UIAlertController* applistAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Connection Failed"] - message:serverInfoResp.statusMessage - preferredStyle:UIAlertControllerStyleAlert]; - [Utils addHelpOptionToDialog:applistAlert]; - [applistAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]]; - - // Only display an alert if this was the result of a real - // user action, not just passively entering the foreground again - [self hideLoadingFrame: ^{ - [self switchToHostView]; - [[self activeViewController] presentViewController:applistAlert animated:YES completion:nil]; - }]; - - host.state = StateOffline; - }); - } else { - // Update the host object with this data - [serverInfoResp populateHost:host]; - // Only pair when this was the result of explicit user action - Log(LOG_I, @"Trying to pairTrying to pair"); - // Polling the server while pairing causes the server to screw up - [self->_discMan stopDiscoveryBlocking]; - PairManager* pMan = [[PairManager alloc] initWithManager:hMan clientCert:self->_clientCert callback:self]; - [self->_opQueue addOperation:pMan]; - - } - }); - }]; -} - - -- (void) noneUserInitiatedHostAction:(TemporaryHost *)host view:(UIView *)view { + Log(LOG_D, @"Clicked host: %@", host.name); _selectedHost = host; + [self updateTitle]; //_appManager = [[AppAssetManager alloc] initWithCallback:self]; [self.collectionView setCollectionViewLayout:self.collectionViewLayout]; [self.collectionView reloadData]; //for new scroll host view reloading mechanism [self.view addSubview:self.collectionView]; //for new scroll host view reloading mechanism + [self attachWaterMark]; + [self enableUpButton]; + [self disableNavigation]; #if TARGET_OS_TV // Intercept the menu key to go back to the host page [self.navigationController.view addGestureRecognizer:_menuRecognizer]; #endif - // 若未在线或未配对, 有以下: + // If we are online, paired, and have a cached app list, skip straight + // to the app grid without a loading frame. This is the fast path that users + // should hit most. Check for a valid view because we don't want to hit the fast + // path after coming back from streaming, since we need to fetch serverinfo too + // so that our active game data is correct. + if (host.state == StateOnline && host.pairState == PairStatePaired && host.appList.count > 0 && view != nil) { + [self alreadyPaired]; + return; + } [self showLoadingFrame: ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -508,7 +381,7 @@ static NSMutableSet* hostList; if (host.state == StateOffline) { dispatch_async(dispatch_get_main_queue(), ^{ [self hideLoadingFrame:^{ - [self switchToHostView]; + [self showHostSelectionView]; }]; }); return; @@ -540,8 +413,12 @@ static NSMutableSet* hostList; // Only display an alert if this was the result of a real // user action, not just passively entering the foreground again [self hideLoadingFrame: ^{ - [self switchToHostView]; + [self showHostSelectionView]; + if (view != nil) { + [[self activeViewController] presentViewController:applistAlert animated:YES completion:nil]; + } }]; + host.state = StateOffline; }); } else { @@ -551,11 +428,19 @@ static NSMutableSet* hostList; Log(LOG_I, @"Already Paired"); [self alreadyPaired]; } - else if (view == nil) { + // Only pair when this was the result of explicit user action + else if (view != nil) { + Log(LOG_I, @"Trying to pair"); + // Polling the server while pairing causes the server to screw up + [self->_discMan stopDiscoveryBlocking]; + PairManager* pMan = [[PairManager alloc] initWithManager:hMan clientCert:self->_clientCert callback:self]; + [self->_opQueue addOperation:pMan]; + } + else { // Not user action, so just return to host screen dispatch_async(dispatch_get_main_queue(), ^{ [self hideLoadingFrame:^{ - [self switchToHostView]; + [self showHostSelectionView]; }]; }); } @@ -564,7 +449,6 @@ static NSMutableSet* hostList; }]; } - - (UIViewController*) activeViewController { UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; @@ -575,14 +459,7 @@ static NSMutableSet* hostList; return topController; } -- (void)restoreTintColorForAllSubViews{ - for(UIView* view in self.view.subviews){ // iterates all on-screen widget views in StreamFrameView - view.tintAdjustmentMode = UIViewTintAdjustmentModeNormal; - } -} - -- (void)hostCardLongPressed:(TemporaryHost *)host view:(UIView *)view { - _selectedHost = host; +- (void)hostLongClicked:(TemporaryHost *)host view:(UIView *)view { Log(LOG_D, @"Long clicked host: %@", host.name); NSString* message; @@ -609,9 +486,8 @@ static NSMutableSet* hostList; } UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:message preferredStyle:UIAlertControllerStyleActionSheet]; - if (host.state != StateOnline) { - /*[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Wake PC"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){ + [longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Wake PC"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){ UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Wake-On-LAN"] message:@"" preferredStyle:UIAlertControllerStyleAlert]; [wolAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]]; if (host.mac == nil || [host.mac isEqualToString:@"00:00:00:00:00:00"]) { @@ -623,17 +499,16 @@ static NSMutableSet* hostList; wolAlert.message = [LocalizationHelper localizedStringForKey:@"Successfully sent wake-up request. It may take a few moments for the PC to wake. If it never wakes up, ensure it's properly configured for Wake-on-LAN."]; } [[self activeViewController] presentViewController:wolAlert animated:YES completion:nil]; - }]];*/ + }]]; } else if (host.pairState == PairStatePaired) { - /* [longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"View All Apps"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){ self->_showHiddenApps = YES; [self hostClicked:host view:view]; - }]]; */ + }]]; #if !TARGET_OS_TV - if (false) { + if (host.isNvidiaServerSoftware) { [longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"NVIDIA GameStream End-of-Service"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){ [Utils launchUrl:@"https://github.com/moonlight-stream/moonlight-docs/wiki/NVIDIA-GameStream-End-Of-Service-Announcement-FAQ"]; }]]; @@ -663,9 +538,7 @@ static NSMutableSet* hostList; UIAlertController* netTestAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Network Test Complete"] message:message preferredStyle:UIAlertControllerStyleAlert]; [netTestAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]]; - [[self activeViewController] presentViewController:netTestAlert animated:YES completion:^{ - [self restoreTintColorForAllSubViews]; - }]; + [[self activeViewController] presentViewController:netTestAlert animated:YES completion:nil]; }]; }); }); @@ -683,7 +556,6 @@ static NSMutableSet* hostList; #endif [longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Remove Host"] style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) { // host removed here [self->_discMan removeHostFromDiscovery:host]; - [self.hostCollectionVC removeHost:host]; DataManager* dataMan = [[DataManager alloc] init]; [dataMan removeHost:host]; @synchronized(hostList) { @@ -701,29 +573,13 @@ static NSMutableSet* hostList; [[self activeViewController] presentViewController:longClickAlert animated:YES completion:nil]; } -- (void) addHostTapped { - Log(LOG_D, @"Tapped add host"); - UIAlertController* alertController = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Add Host Manually"] - message:[LocalizationHelper localizedStringForKey:@"Enter IP address to add host manually"] - preferredStyle:UIAlertControllerStyleAlert]; - - [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { - textField.placeholder = @"192.168.0.100 or [2001:db8::1]"; - textField.keyboardType = UIKeyboardTypeASCIICapable; - textField.autocorrectionType = UITextAutocorrectionTypeNo; - textField.spellCheckingType = UITextSpellCheckingTypeNo; - }]; - - [alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Cancel"] - style:UIAlertActionStyleCancel - handler:nil]]; - - [alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction* action) { - UITextField *textField = alertController.textFields.firstObject; - NSString *hostAddress = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - +- (void) addHostClicked { + Log(LOG_D, @"Clicked add host"); + UIAlertController* alertController = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Add Host Manually"] message:[LocalizationHelper localizedStringForKey:@"If Moonlight doesn't find your local gaming PC automatically, enter the IP address of your PC"] preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Cancel"] style:UIAlertActionStyleCancel handler:nil]]; + [alertController addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){ + NSString* hostAddress = [((UITextField*)[[alertController textFields] objectAtIndex:0]).text trim]; + [self showLoadingFrame:^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [self->_discMan discoverHost:hostAddress withCallback:^(TemporaryHost* host, NSString* error){ @@ -756,6 +612,7 @@ static NSMutableSet* hostList; }); }]; }]]; + [alertController addTextFieldWithConfigurationHandler:nil]; [[self activeViewController] presentViewController:alertController animated:YES completion:nil]; } @@ -808,7 +665,8 @@ static NSMutableSet* hostList; _streamConfig.playAudioOnPC = streamSettings.playAudioOnPC; _streamConfig.useFramePacing = streamSettings.useFramePacing; _streamConfig.swapABXYButtons = streamSettings.swapABXYButtons; - _streamConfig.asyncNativeTouchPriority = streamSettings.asyncNativeTouchPriority; // new streamConfig segment + _streamConfig.motionMode = [streamSettings.motionMode intValue]; + _streamConfig.largerStickLR1 = streamSettings.largerStickLR1; // new streamConfig segment // multiController must be set before calling getConnectedGamepadMask _streamConfig.multiController = streamSettings.multiController; @@ -1063,30 +921,32 @@ static NSMutableSet* hostList; } #if !TARGET_OS_TV - -- (void)expandSettingsView { //simulate pressing the setting button, called from setting view controller. - if (currentPosition == FrontViewPositionLeft) { - [[self revealViewController] revealToggleAnimated:YES]; +// this method is deprecated +- (void)simulateSettingsButtonPressClose { //force expand settings view to update resolution table, and all setting includes current fullscreen resolution will be updated. + if (currentPosition == FrontViewPositionRight && _settingsButton.target && [_settingsButton.target respondsToSelector:_settingsButton.action]) { + [_settingsButton.target performSelector:_settingsButton.action withObject:_settingsButton]; } } -- (void)closeSettingViewAnimated:(BOOL)anaimated { //simulate pressing the setting button, called from setting view controller. - if (currentPosition != FrontViewPositionLeft) { - [[self revealViewController] revealToggleAnimated:anaimated]; +- (void)simulateSettingsButtonPress { //simulate pressing the setting button, called from setting view controller. + //if([self isIPhonePortrait]) return; // disable settings view expanding in iphone portrait mode since it's buggy. + if (_settingsButton.target && [_settingsButton.target respondsToSelector:_settingsButton.action]) { + [_settingsButton.target performSelector:_settingsButton.action withObject:_settingsButton]; } } - - (void)handleOrientationChange { - // UIDeviceOrientation targetOrientation = [[UIDevice currentDevice] orientation]; - // if([self isIPhone] && UIDeviceOrientationIsPortrait(targetOrientation)) [self simulateSettingsButtonPressClose]; // on iphone, force close settings views if target orietation is portrait. + UIDeviceOrientation targetOrientation = [[UIDevice currentDevice] orientation]; + if([self isIphone] && UIDeviceOrientationIsPortrait(targetOrientation)) [self simulateSettingsButtonPressClose]; // on iphone, force close settings views if target orietation is portrait. double delayInSeconds = 0.7; // Convert the delay into a dispatch_time_t value dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); // Perform some task after the delay dispatch_after(delayTime, dispatch_get_main_queue(), ^{// Code to execute after the delay // [self updateResolutionAccordingly]; - // [self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode. + [self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode. + if([self->_upButton title] == nil) [self reloadScrollHostView]; // title of the _upButton is a good flag for judging if we're on the Host selection view + //self->recordedScreenWidth = screenWidthInPoints; // kind of obselete, but i keep this in the code. }); } @@ -1099,67 +959,25 @@ static NSMutableSet* hostList; } } -- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { - settingsViewController = (SettingsViewController*)[revealController rearViewController]; - revealController.navBarMenuDelegate = settingsViewController; - if (position == FrontViewPositionLeft) { - self.navigationItem.leftBarButtonItems = @[_settingsButton]; - } - else { - self.navigationItem.leftBarButtonItems = @[]; - [settingsViewController updateTheme]; - } - - settingsViewController.mainFrameViewController = self; - // enable / disable widgets acoordingly: in streamview, disable, outside of streamview, enable. - if(self.settingsExpandedInStreamView) [revealController buttonsInStreaming]; - else [revealController buttonsNotInStreaming]; - - //[settingsViewController.resolutionSelector setEnabled:!self.settingsExpandedInStreamView]; - //settingsViewController.resolutionStack.hidden = self.settingsExpandedInStreamView; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.resolutionStack]; - //settingsViewController.fpsStack.hidden = self.settingsExpandedInStreamView; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.fpsStack]; - - [settingsViewController widget:settingsViewController.bitrateSlider setEnabled:!self.settingsExpandedInStreamView]; - //settingsViewController.bitrateStack.hidden = self.settingsExpandedInStreamView; - //settingsViewController.optimizeGamesStack.hidden = self.settingsExpandedInStreamView; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.optimizeGamesStack]; - - //settingsViewController.audioOnPcStack.hidden = self.settingsExpandedInStreamView; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.audioOnPcStack]; - - //settingsViewController.codecStack.hidden = self.settingsExpandedInStreamView; - //[settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.codecStack]; - [settingsViewController.codecSelector setEnabled:!_settingsExpandedInStreamView]; - - - // settingsViewController.yuv444Stack.hidden = self.settingsExpandedInStreamView; - // [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.yuv444Stack]; - [settingsViewController.yuv444Switch setEnabled:!_settingsExpandedInStreamView]; - - - //settingsViewController.HdrStack.hidden = self.settingsExpandedInStreamView; - // [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.HdrStack]; - [settingsViewController.hdrSwitch setEnabled:!_settingsExpandedInStreamView]; - - - //settingsViewController.framepacingStack.hidden = self.settingsExpandedInStreamView; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.framepacingStack]; - - //settingsViewController.citrixX1MouseStack.hidden = self.settingsExpandedInStreamView; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.citrixX1MouseStack]; - - //settingsViewController.externalDisplayModeStack.hidden = self.settingsExpandedInStreamView; - [settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.externalDisplayModeStack]; - - // [settingsViewController.unlockDisplayOrientationSelector setEnabled:!self.settingsExpandedInStreamView && [self isFullScreenRequired]];//need "requires fullscreen" enabled in the app bunddle to make runtime orientation limitation woring -} - (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { // If we moved back to the center position, we should save the settings SettingsViewController* settingsViewController = (SettingsViewController*)[revealController rearViewController]; settingsViewController.mainFrameViewController = self; + // enable / disable widgets acoordingly: in streamview, disable, outside of streamview, enable. + [settingsViewController.resolutionSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.framerateSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController widget:settingsViewController.bitrateSlider setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.optimizeSettingsSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.audioOnPCSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.codecSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.yuv444Selector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.hdrSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.framePacingSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.btMouseSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.externalDisplayModeSelector setEnabled:!self.settingsExpandedInStreamView]; + [settingsViewController.backToStreamingButton setEnabled:self.settingsExpandedInStreamView]; + // [settingsViewController.unlockDisplayOrientationSelector setEnabled:!self.settingsExpandedInStreamView && [self isFullScreenRequired]];//need "requires fullscreen" enabled in the app bunddle to make runtime orientation limitation woring if (position == FrontViewPositionLeft) { [settingsViewController saveSettings]; @@ -1208,6 +1026,7 @@ static NSMutableSet* hostList; [super viewSafeAreaInsetsDidChange]; [self adjustScrollViewForSafeArea:self.collectionView]; + [self adjustScrollViewForSafeArea:self->hostScrollView]; } - (void)waterMarkTapped { @@ -1232,7 +1051,7 @@ static NSMutableSet* hostList; - (void)attachWaterMark { // Create and configure the label - if(false){ + if(true){ [self->waterMark removeFromSuperview]; self->waterMark = [[UILabel alloc] init]; self->waterMark.translatesAutoresizingMaskIntoConstraints = NO; @@ -1240,6 +1059,7 @@ static NSMutableSet* hostList; self->waterMark.font = [UIFont systemFontOfSize:22]; self->waterMark.text = [LocalizationHelper localizedStringForKey:@"waterMarkText"]; CGFloat labelHeight = 60; + NSLog(@"fullscr: %d", [self isFullScreenRequired]); // the app is unable to automatically lock screen orientation in app window resizable mode(aka. not require fullscreen) // if(![self isFullScreenRequired]){ @@ -1271,7 +1091,7 @@ static NSMutableSet* hostList; } } -- (bool)isIPhone{ +- (bool)isIphone{ return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone); } @@ -1284,186 +1104,23 @@ static NSMutableSet* hostList; // return isPortrait; } -- (UIBarButtonItem *)createAddHostButton{ - // 创建按钮 - CGFloat buttonHeight = 30; - UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; - button.backgroundColor = [ThemeManager appPrimaryColor]; // #0A85FF - button.layer.cornerRadius = buttonHeight/2; - button.clipsToBounds = YES; - - // 设置图标(SF Symbol) - - if (@available(iOS 13.0, *)) { - UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:17 weight:UIImageSymbolWeightMedium]; - UIImage *image = [UIImage systemImageNamed:@"plus.circle" withConfiguration:config]; - [button setImage:image forState:UIControlStateNormal]; - [button setTitle:[LocalizationHelper localizedStringForKey:@" Add Host"] forState:UIControlStateNormal]; // 注意空格用于间隔 - } else { - [button setTitle:[LocalizationHelper localizedStringForKey:@"Add Host"] forState:UIControlStateNormal]; // 注意空格用于间隔 - } - // [button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; - - button.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; - // 文字颜色设置为 tintColor 控制 - button.tintColor = UIColor.whiteColor; - [button setTitleColor:button.tintColor forState:UIControlStateNormal]; - - // 设置按下时的 tintColor(变灰或淡) - UIColor *highlightColor = [ThemeManager textColorGray]; - [button setTitleColor:highlightColor forState:UIControlStateHighlighted]; - button.adjustsImageWhenHighlighted = YES; // 图标自动变淡 - - // 手动设定大小(如图中大约宽118高40) - button.frame = CGRectMake(0, 0, 130, buttonHeight); - - // 添加点击事件 - [button addTarget:self action:@selector(addHostTapped) forControlEvents:UIControlEventTouchUpInside]; - - // 创建 UIBarButtonItem - UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:button]; - return barItem; -} - -- (UIBarButtonItem *)createHelpButton{ - // 创建按钮 - CGFloat buttonHeight = 30; - UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; - button.backgroundColor = [UIColor clearColor]; // #0A85FF - // button.layer.cornerRadius = buttonHeight/2; - button.clipsToBounds = YES; - - // 设置图标(SF Symbol) - if (@available(iOS 13.0, *)) { - UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:buttonHeight*0.85 weight:UIImageSymbolWeightRegular]; - UIImage *image = [UIImage systemImageNamed:@"questionmark.circle" withConfiguration:config]; - [button setImage:image forState:UIControlStateNormal]; - [button setTitle:@"" forState:UIControlStateNormal]; // 注意空格用于间隔 - } else { - [button setTitle:[LocalizationHelper localizedStringForKey:@"About"] forState:UIControlStateNormal]; // 注意空格用于间隔 - } - // [button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; - - button.titleLabel.font = [UIFont systemFontOfSize:buttonHeight*0.6 weight:UIFontWeightMedium]; - // 文字颜色设置为 tintColor 控制 - button.tintColor = [ThemeManager appPrimaryColor]; - [button setTitleColor:button.tintColor forState:UIControlStateNormal]; - - button.frame = CGRectMake(0, 0, buttonHeight, buttonHeight); - - // 添加点击事件 - // [button addTarget:self action:@selector(addDeviceTapped) forControlEvents:UIControlEventTouchUpInside]; - - // 创建 UIBarButtonItem - UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:button]; - return barItem; -} - -- (CGFloat)getStandardNavBarHeight{ - return [self isIPhone] ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad; -} - -- (void)setupHostViewTitle{ - self->hostViewTitleLabel = [[UILabel alloc] init]; - - hostViewTitleLabel.translatesAutoresizingMaskIntoConstraints = NO; - hostViewTitleLabel.numberOfLines = 1; - hostViewTitleLabel.font = [UIFont systemFontOfSize:30 weight:UIFontWeightSemibold]; - hostViewTitleLabel.text = [LocalizationHelper localizedStringForKey:@"Hosts"]; - // CGFloat labelHeight = 60; - - - hostViewTitleLabel.textColor = [ThemeManager textColor]; - hostViewTitleLabel.textAlignment = NSTextAlignmentCenter; - // hostViewTitleLabel.backgroundColor = [UIColor clearColor]; - hostViewTitleLabel.userInteractionEnabled = NO; // Enable user interaction for tap gesture - // Add tap gesture recognizer to handle hyperlink action - [self.view addSubview:hostViewTitleLabel]; - // Set up constraints - [NSLayoutConstraint activateConstraints:@[ - [hostViewTitleLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:0], // Aligns the horizontal center of label to the horizontal center of view - [hostViewTitleLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:25], - [hostViewTitleLabel.heightAnchor constraintEqualToConstant:30], - [hostViewTitleLabel.widthAnchor constraintEqualToConstant:100], - ]]; -} - -- (void)applyNavBarAppearance{ - if (@available(iOS 13.0, *)) { - self.navigationController.navigationBar.standardAppearance.backgroundColor = [UIColor clearColor]; // old ios depend on this, do not remove - self.navigationController.navigationBar.standardAppearance = navBarAppearanceStandard; - self.navigationController.navigationBar.scrollEdgeAppearance = navBarAppearanceStandard; - } - else{ - self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; // old ios depend on this, do not remove - self.navigationController.navigationBar.barTintColor = [UIColor clearColor]; // ios 14 depend on this, do not remove - self.navigationController.navigationBar.barTintColor = [ThemeManager appBackgroundColor]; // ios 14 depend on this, do not remove - } -} - -- (void)setupNavBar{ - if (@available(iOS 13.0, *)) { - Class appearanceClass = NSClassFromString(@"UINavigationBarAppearance"); - navBarAppearanceStandard = [[appearanceClass alloc] init]; - [navBarAppearanceStandard performSelector:@selector(configureWithOpaqueBackground)]; // 不透明 - [navBarAppearanceStandard setValue:[ThemeManager appBackgroundColor] forKey:@"backgroundColor"]; // 设置你需要的背景色 - [navBarAppearanceStandard setValue:nil forKey:@"shadowColor"]; // 设置你需要的背景色 - NSDictionary* titleTextAttributes = @{ - NSForegroundColorAttributeName: [ThemeManager textColor] - }; - [navBarAppearanceStandard setValue:titleTextAttributes forKey:@"titleTextAttributes"]; - [navBarAppearanceStandard setValue:[UIColor clearColor] forKey:@"shadowColor"]; - [navBarAppearanceStandard setValue:nil forKey:@"backgroundImage"]; - - //navBarAppearanceStandard.backgroundImage = nil; - } - [self applyNavBarAppearance]; - - self->_addHostButton = [self createAddHostButton]; - self->_helpButton = [self createHelpButton]; - //[self setupHostViewTitle]; - - - - self.navigationItem.rightBarButtonItems = @[_helpButton, _addHostButton]; // 顺序:右边靠右的是第一个 - - // Set the side bar button action. When it's tapped, it'll show the sidebar. - - [_settingsButton setTarget:self.revealViewController]; - [_settingsButton setAction:@selector(revealToggle:)]; - if (@available(iOS 13.0, *)) { - [_settingsButton setTitle:nil]; - UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:23 weight:UIImageSymbolWeightMedium ]; - UIImage *image = [[UIImage systemImageNamed:@"sidebar.left" withConfiguration:config] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - [_settingsButton setImage:image]; - _settingsButton.imageInsets = UIEdgeInsetsMake(10, 10, 0, 0); - } else { - [_settingsButton setTitle:[LocalizationHelper localizedStringForKey:@"Settings"]]; - } - - // Set the host name button action. When it's tapped, it'll show the host selection view. - _upButton = [[UIBarButtonItem alloc] init]; - [self->_upButton setTitle: [LocalizationHelper localizedStringForKey: @"Select New Host"]]; - [_upButton setTarget:self]; - [_upButton setAction:@selector(switchToHostView)]; -} - -- (void)viewDidLoad{ - [ThemeManager setUserInterfaceStyle:UIUserInterfaceStyleUnspecified]; +- (void)viewDidLoad +{ [super viewDidLoad]; //[OrientationHelper updateOrientationToLandscape]; - // self.navigationController.delegate = self; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(deviceOrientationDidChange) // handle orientation change since i made portrait mode available - name:UIDeviceOrientationDidChangeNotification - object:nil]; - #if !TARGET_OS_TV self.settingsExpandedInStreamView = false; // init this flag self.revealViewController.isStreaming = false; //init this flag for rvlVC self.revealViewController.mainFrameIsInHostView = true; - [self setupNavBar]; + // Set the side bar button action. When it's tapped, it'll show the sidebar. + [_settingsButton setTarget:self.revealViewController]; + [_settingsButton setAction:@selector(revealToggle:)]; + + // Set the host name button action. When it's tapped, it'll show the host selection view. + [_upButton setTarget:self]; + [_upButton setAction:@selector(showHostSelectionView)]; + [self disableUpButton]; // Set the gesture if(![self isIPhonePortrait]) [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; // to prevent buggy settings view in iphone portrait mode; @@ -1484,7 +1141,7 @@ static NSMutableSet* hostList; self.collectionView.remembersLastFocusedIndexPath = YES; _menuRecognizer = [[UITapGestureRecognizer alloc] init]; - [_menuRecognizer addTarget:self action: @selector(switchToHostView)]; + [_menuRecognizer addTarget:self action: @selector(showHostSelectionView)]; _menuRecognizer.allowedPressTypes = [[NSArray alloc] initWithObjects:[NSNumber numberWithLong:UIPressTypeMenu], nil]; self.navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]; @@ -1511,6 +1168,7 @@ static NSMutableSet* hostList; _boxArtCache = [[NSCache alloc] init]; //recordedScreenWidth = CGRectGetWidth([[UIScreen mainScreen] bounds]); + hostScrollView = [[ComputerScrollView alloc] init]; CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]); CGFloat screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]); @@ -1524,6 +1182,10 @@ static NSMutableSet* hostList; realViewFrameHeight = tmpLength; } + // implementations for initializing hostScrollView from original moonlight-iOS + hostScrollView.frame = CGRectMake(0, self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height, realViewFrameWidth, realViewFrameHeight / 2); + [hostScrollView setShowsHorizontalScrollIndicator:NO]; + hostScrollView.delaysContentTouches = NO; self.collectionView.delaysContentTouches = NO; self.collectionView.allowsMultipleSelection = NO; @@ -1536,12 +1198,12 @@ static NSMutableSet* hostList; [self.collectionView addGestureRecognizer:cellLongPress]; #endif + [self retrieveSavedHosts]; + _discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self]; [self updateTitle]; - // [self.view addSubview:hostScrollView]; - - // if ([hostList count] == 1) [self hostClicked:[hostList anyObject] view:nil]; // auto click for single host - + [self.view addSubview:hostScrollView]; + if ([hostList count] == 1) [self hostClicked:[hostList anyObject] view:nil]; // auto click for single host //if([SettingsViewController isLandscapeNow] != _streamConfig.width > _streamConfig.height) //[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app. //[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app. @@ -1549,20 +1211,47 @@ static NSMutableSet* hostList; // SettingsViewController* settingsViewController = (SettingsViewController*)[self.revealViewController rearViewController]; // [settingsViewController updateResolutionTable]; - - UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleMenuResize:)]; - [self.view addGestureRecognizer:longPress]; - - - UIStoryboard *storyboard = [UIStoryboard storyboardWithName:[self isIPhone]?@"iPhone":@"iPad" bundle:nil]; - SettingsViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"settingsViewController"]; - // 强制加载视图 - __unused UIView *view = viewController.view; } --(void)viewDidLayoutSubviews{ - [super viewDidLayoutSubviews]; - [self updateHosts]; +-(void)handleRealOrientationChange{ + +} + +-(void)reloadScrollHostView{ + [hostScrollView removeFromSuperview]; // mandatory for scroll view refresh after orientation change and clicking "select new host" + CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]); + CGFloat screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]); + + // deal with scroll host view reload after device orientation change here: + bool isLandscape = screenWidthInPoints > screenHeightInPoints; + CGFloat realViewFrameWidth = self.view.frame.size.width > self.view.frame.size.height ? self.view.frame.size.width : self.view.frame.size.height; + CGFloat realViewFrameHeight = self.view.frame.size.width < self.view.frame.size.height ? self.view.frame.size.width : self.view.frame.size.height; + if(!isLandscape) { + CGFloat tmpLength = realViewFrameWidth; + realViewFrameWidth = realViewFrameHeight; + realViewFrameHeight = tmpLength; + } + + hostScrollView.frame = CGRectMake(0, self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height, realViewFrameWidth, realViewFrameHeight / 2); + [hostScrollView setShowsHorizontalScrollIndicator:NO]; + hostScrollView.delaysContentTouches = NO; + + self.collectionView.delaysContentTouches = NO; + self.collectionView.allowsMultipleSelection = NO; + #if !TARGET_OS_TV + self.collectionView.multipleTouchEnabled = NO; + #else + // This is the only way to get long press events on a UICollectionViewCell :( + UILongPressGestureRecognizer* cellLongPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleCollectionViewLongPress:)]; + cellLongPress.delaysTouchesBegan = YES; + [self.collectionView addGestureRecognizer:cellLongPress]; + #endif + + // the reloadScrollHostView method cannnot copy what all viewDidLoad does for initializing the host scroll view, the following 2 lines of codes must be annotated, or there'll be issues with deleting hosts. + //[self retrieveSavedHosts]; + //_discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self]; + [self updateTitle]; + [self.view addSubview:hostScrollView]; } // this will also be called back when device orientation changes @@ -1622,6 +1311,9 @@ static NSMutableSet* hostList; } } } + + + [dataMan saveData]; } @@ -1659,7 +1351,7 @@ static NSMutableSet* hostList; // This will refresh the applist when a paired host is selected if (_selectedHost != nil && _selectedHost.pairState == PairStatePaired) { - [self noneUserInitiatedHostAction:_selectedHost view:nil]; + [self hostClicked:_selectedHost view:nil]; } } } @@ -1689,7 +1381,7 @@ static NSMutableSet* hostList; if (matchingHost != nil && _selectedHost != matchingHost) { // Navigate to the host page - [self noneUserInitiatedHostAction:matchingHost view:nil]; + [self hostClicked:matchingHost view:nil]; } } } @@ -1714,9 +1406,6 @@ static NSMutableSet* hostList; - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:NO]; - - // [self setupHostViewTitle]; - // [self reloadScrollHostView]; //remove this for proper test [self attachWaterMark]; #if !TARGET_OS_TV @@ -1727,16 +1416,16 @@ static NSMutableSet* hostList; [[self revealViewController] setPrimaryViewController:self]; self.revealViewController.isStreaming = false; // tell the revealViewController streaming is finished - //[self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode. + [self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode. //recordedScreenWidth = CGRectGetWidth([[UIScreen mainScreen] bounds]); // Get the screen's bounds (in points), update recorded screen width #endif - [self.navigationController setNavigationBarHidden:NO animated:NO]; + [self.navigationController setNavigationBarHidden:NO animated:YES]; // Hide 1px border line UIImage* fakeImage = [[UIImage alloc] init]; - // [self.navigationController.navigationBar setShadowImage:fakeImage]; - // [self.navigationController.navigationBar setBackgroundImage:fakeImage forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault]; + [self.navigationController.navigationBar setShadowImage:fakeImage]; + [self.navigationController.navigationBar setBackgroundImage:fakeImage forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault]; // Check for a pending shortcut action when appearing [self handlePendingShortcutAction]; @@ -1760,13 +1449,7 @@ static NSMutableSet* hostList; - (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:NO]; - - /* this makes background color works*/ - for (UIView *subview in self.view.subviews) { - [subview removeFromSuperview]; // 暂时移除所有子视图 - } - + [super viewWillAppear:animated]; // We can get here on home press while streaming // since the stream view segues to us just before @@ -1779,24 +1462,13 @@ static NSMutableSet* hostList; // this view via an error dialog from the stream // view, so we won't get a return to active notification // for that which would normally fire beginForegroundRefresh. - self.view.backgroundColor = [ThemeManager appBackgroundColor]; - self.hostCollectionVC.view.backgroundColor = [ThemeManager appBackgroundColor]; - self.collectionView.backgroundColor = [ThemeManager appBackgroundColor]; - - [self.view addSubview:self.collectionView]; - [self initHostCollection]; - [self switchToHostView]; - - [self retrieveSavedHosts]; - - _discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self]; - [self beginForegroundRefresh]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; + // when discovery stops, we must create a new instance because // you cannot restart an NSOperation when it is finished [_discMan stopDiscovery]; @@ -1876,32 +1548,19 @@ static NSMutableSet* hostList; - (void)updateHosts { Log(LOG_I, @"Updating hosts..."); + [[hostScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + UIComputerView* addComp = [[UIComputerView alloc] initForAddWithCallback:self]; + UIComputerView* compView; + float prevEdge = -1; @synchronized (hostList) { // Sort the host list in alphabetical order NSArray* sortedHostList = [[hostList allObjects] sortedArrayUsingSelector:@selector(compareName:)]; for (TemporaryHost* comp in sortedHostList) { - if(comp.state == StateOnline || comp.pairState == PairStatePaired) [self.hostCollectionVC addHost:comp]; + compView = [[UIComputerView alloc] initWithComputer:comp andCallback:self]; + compView.center = CGPointMake([self getCompViewX:compView addComp:addComp prevEdge:prevEdge], hostScrollView.frame.size.height / 2); + prevEdge = compView.frame.origin.x + compView.frame.size.width; + [hostScrollView addSubview:compView]; - - // new host card test - // if([comp.name isEqualToString: @"ASRockPC"]) { - /* - if([comp.name isEqualToString: @"ASRockPC"]) { - //if([comp.name isEqualToString: @"PianoServer"]) { - //if([comp.name isEqualToString: @"TrueZj"]) { - HostCardView *testCard = [[HostCardView alloc] initWithHost:comp]; - - [self.view addSubview:testCard]; - // [testCard resizeBySizeFactor:3]; - [NSLayoutConstraint activateConstraints:@[ - [testCard.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant:0], - [testCard.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor constant:150], - ]]; - - }*/ - // - - // Start jobs to decode the box art in advance for (TemporaryApp* app in comp.appList) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ @@ -1916,22 +1575,32 @@ static NSMutableSet* hostList; // Update the title in case we now have a PC [self updateTitle]; + + prevEdge = [self getCompViewX:addComp addComp:addComp prevEdge:prevEdge]; + addComp.center = CGPointMake(prevEdge, hostScrollView.frame.size.height / 2); + + [hostScrollView addSubview:addComp]; + [hostScrollView setContentSize:CGSizeMake(prevEdge + addComp.frame.size.width, hostScrollView.frame.size.height)]; +} + +- (float) getCompViewX:(UIComputerView*)comp addComp:(UIComputerView*)addComp prevEdge:(float)prevEdge { + float padding; + +#if TARGET_OS_TV + padding = 100; +#else + padding = addComp.frame.size.width / 2; +#endif + + if (prevEdge == -1) { + return hostScrollView.frame.origin.x + comp.frame.size.width / 2 + padding; + } else { + return prevEdge + comp.frame.size.width / 2 + padding; + } } // This function forces immediate decoding of the UIImage, rather // than the default lazy decoding that results in janky scrolling. --(void)deviceOrientationDidChange{ - if(self.collectionView.superview == nil) return; - [NSLayoutConstraint activateConstraints:@[ - [self.collectionView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], - [self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor], - [self.collectionView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor], - [self.collectionView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor], - //[self.collectionView.heightAnchor constraintEqualToConstant:_headerViewHeight] - ]]; -} - - + (UIImage*) loadBoxArtForCaching:(TemporaryApp*)app { UIImage* boxArt; @@ -1996,6 +1665,7 @@ static NSMutableSet* hostList; _sortedAppList = visibleAppList; } + [hostScrollView removeFromSuperview]; [self.collectionView reloadData]; } @@ -2013,7 +1683,7 @@ static NSMutableSet* hostList; [cell.subviews.firstObject removeFromSuperview]; // Remove a view that was previously added [cell addSubview:appView]; - // [self.settingsButton setEnabled:![self isIPhonePortrait]]; // update settings button after host is clicked & appview loaded + [self.settingsButton setEnabled:![self isIPhonePortrait]]; // update settings button after host is clicked & appview loaded // Shadow opacity is controlled inside UIAppView based on whether the app // is hidden or not during the update cycle. UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:cell.bounds]; @@ -2052,90 +1722,10 @@ static NSMutableSet* hostList; [_boxArtCache removeAllObjects]; } -- (UIView* )findMenuSeparator{ - BOOL shouldBreak = NO; - UIView* seperator=self.view; - while(seperator && !shouldBreak) { - for(UIView* view in seperator.subviews) { - if([view.accessibilityIdentifier isEqualToString:@"menuSeparator"]) { - seperator = view; - shouldBreak = YES; - break; - } - } - if (shouldBreak) break; - seperator = seperator.superview; - } - return seperator; -} - -- (void)handleMenuResize:(UILongPressGestureRecognizer *)gesture { - CGPoint locationInView = [gesture locationInView:self.view]; - CGPoint locationInSuperView = [gesture locationInView:self.revealViewController.view]; - CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; - CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; - - menuSeparator = [self findMenuSeparator]; - if(menuSeparator.hidden || menuSeparator == nil) return; - - if(gesture.state == UIGestureRecognizerStateBegan){ - if(locationInView.x < 30) { - snapshot = [[UIView alloc] init]; - snapshot.backgroundColor = [ThemeManager appPrimaryColor]; - screenHeight = [UIScreen mainScreen].bounds.size.height; - snapshot.frame = CGRectMake(locationInSuperView.x,0, 2, screenHeight); - [self.revealViewController.view addSubview:snapshot]; - } - return; - } - - bool isPortrait = screenHeight>screenWidth; - - CGFloat limitedWidth = MIN(MAX(locationInSuperView.x, isPortrait ? 200 : 280),isPortrait ? screenWidth*0.75 : screenWidth/2); - if(gesture.state == UIGestureRecognizerStateChanged){ - if(snapshot) snapshot.center = CGPointMake(limitedWidth, snapshot.center.y); - } - if(gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled){ - [snapshot removeFromSuperview]; - self.revealViewController.rearViewRevealWidth = limitedWidth; - [self.revealViewController setupNavigationBar]; - if(self.revealViewController.isStreaming) [self.revealViewController buttonsInStreaming]; - else [self.revealViewController buttonsNotInStreaming]; - DataManager* dataMan = [[DataManager alloc] init]; - Settings* settings = [dataMan retrieveSettings]; - settings.settingsMenuWidth = [NSNumber numberWithFloat:self.revealViewController.rearViewRevealWidth]; - [dataMan saveData]; - - - double delayInSeconds = 0.02; - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(popTime, dispatch_get_main_queue(), ^{ - [self->settingsViewController hideDynamicLabelsWhenOverlapped:self->settingsViewController.parentStack]; - }); - } -} - - - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES]; } -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ - /* - NSLog(@"%f touchesMoved", CACurrentMediaTime()); - UITouch* touch = touches.anyObject; - CGPoint touchPoint = [touch locationInView:self.view.superview]; - if(snapshot){ - snapshot.center = CGPointMake(touchPoint.x, snapshot.center.y); - } - */ -} - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ - [snapshot removeFromSuperview]; -} - - - (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder]; return YES; @@ -2173,42 +1763,4 @@ static NSMutableSet* hostList; #endif } - -- (CGSize)getHostCardSize{ - CGSize cardSize; - if([self isIPhone]) cardSize.height = 0.37*MIN(CGRectGetHeight([[UIScreen mainScreen] bounds]),CGRectGetWidth([[UIScreen mainScreen] bounds])); - else cardSize.height = 0.25*MIN(CGRectGetHeight([[UIScreen mainScreen] bounds]),CGRectGetWidth([[UIScreen mainScreen] bounds])); - TemporaryHost* dummyHost = [[TemporaryHost alloc] init]; - HostCardView* dummyCard = [[HostCardView alloc] initWithHost:dummyHost]; - cardSize.width = cardSize.height * (dummyCard.size.width/dummyCard.size.height); - // cardSize.width = - return cardSize; -} - -- (void)initHostCollection{ - // 初始化 HostCollectionViewController - self.hostCollectionVC = [[HostCollectionViewController alloc] init]; - self.hostCollectionVC.cellSize = [self getHostCardSize]; - self.hostCollectionVC.interItemMinimumSpacing = 25; - self.hostCollectionVC.minimumLineSpacing = 25; - // 添加为子控制器 - [self addChildViewController:self.hostCollectionVC]; - [self.view addSubview:self.hostCollectionVC.view]; - - // 设置其布局(Auto Layout 示例) - // CGFloat hostCollectionViewPadding = 75; - CGFloat leftPadding = [self isIPhone] ? 30 : 0; - self.hostCollectionVC.view.translatesAutoresizingMaskIntoConstraints = NO; - [NSLayoutConstraint activateConstraints:@[ - [self.hostCollectionVC.view.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:0], - [self.hostCollectionVC.view.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:leftPadding], - [self.hostCollectionVC.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:0], - // [self.hostCollectionVC.view.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:0] //? - ]]; - - // 通知子控制器已添加完成 - [self.hostCollectionVC didMoveToParentViewController:self]; - -} - @end diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings index ef6dcd39..29ec991e 100644 --- a/VoidLink/mul.lproj/iPad.xcstrings +++ b/VoidLink/mul.lproj/iPad.xcstrings @@ -1,61 +1,121 @@ { "sourceLanguage" : "en", "strings" : { - "2Bp-XZ-cCw.text" : { - "comment" : "Class = \"UILabel\"; text = \"Async Native Touch\"; ObjectID = \"2Bp-XZ-cCw\";", + "0bl-Hh-8ot.text" : { + "comment" : "Class = \"UILabel\"; text = \"Player 1 Motion Mode\"; ObjectID = \"0bl-Hh-8ot\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Async Native Touch" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "异步多点触控" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "异步多点触控" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "异步多点触控" + "value" : "Player 1 Motion Mode" } } } }, - "2w1-Vw-GVy.text" : { - "comment" : "Class = \"UILabel\"; text = \"HDR\"; ObjectID = \"2w1-Vw-GVy\";", + "2Bp-XZ-cCw.text" : { + "comment" : "Class = \"UILabel\"; text = \"Larger Sticks & L1/R1 Buttons\"; ObjectID = \"2Bp-XZ-cCw\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "HDR" + "value" : "Larger Sticks & L1/R1 Buttons" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "更大的摇杆和L1/R1按键" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "更大的摇杆和L1/R1按键" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "更大的摇杆和L1/R1按键" + } + } + } + }, + "2Jx-qH-E3Y.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 2Jx-qH-E3Y.segmentTitles[0] = \"No\"; ObjectID = \"2Jx-qH-E3Y\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + } + } + }, + "2Jx-qH-E3Y.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 2Jx-qH-E3Y.segmentTitles[1] = \"Yes\"; ObjectID = \"2Jx-qH-E3Y\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" } } } }, "4FU-iP-c6T.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[0] = \"Captured\"; ObjectID = \"4FU-iP-c6T\";", + "comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[0] = \"Restricted by Window\"; ObjectID = \"4FU-iP-c6T\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Captured" + "value" : "Restricted by Window" } }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "被窗口捕获" } }, @@ -163,44 +223,14 @@ } } }, - "5aI-Zx-dNf.text" : { - "comment" : "Class = \"UILabel\"; text = \"Citrix X1 Mouse\"; ObjectID = \"5aI-Zx-dNf\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Citrix X1 Mouse" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Citrix X1 鼠标" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "Citrix X1 鼠标" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "Citrix X1 鼠标" - } - } - } - }, "6w5-Md-NpV.text" : { - "comment" : "Class = \"UILabel\"; text = \"Preferred Codec\"; ObjectID = \"6w5-Md-NpV\";", + "comment" : "Class = \"UILabel\"; text = \"Preferred Codec \"; ObjectID = \"6w5-Md-NpV\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Preferred Codec" + "value" : "Preferred Codec " } }, "zh-Hans" : { @@ -211,80 +241,134 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "视频编解码" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "视频编解码" } } } }, - "8hF-kb-2uV.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; 8hF-kb-2uV.segmentTitles[0] = \"30 FPS\"; ObjectID = \"8hF-kb-2uV\";", + "7Gm-zB-s7s.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 7Gm-zB-s7s.segmentTitles[0] = \"No\"; ObjectID = \"7Gm-zB-s7s\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "30 FPS" - } - } - } - }, - "8hF-kb-2uV.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; 8hF-kb-2uV.segmentTitles[1] = \"60 FPS\"; ObjectID = \"8hF-kb-2uV\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "60 FPS" - } - } - } - }, - "8hF-kb-2uV.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; 8hF-kb-2uV.segmentTitles[2] = \"120 FPS\"; ObjectID = \"8hF-kb-2uV\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "120 FPS" - } - } - } - }, - "8wW-Sq-EOE.text" : { - "comment" : "Class = \"UILabel\"; text = \"Play Audio on PC\"; ObjectID = \"8wW-Sq-EOE\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Play Audio on PC" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "播放主机端声音" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "播放主机端声音" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "播放主机端声音" + "value" : "关闭" + } + } + } + }, + "7Gm-zB-s7s.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 7Gm-zB-s7s.segmentTitles[1] = \"Yes\"; ObjectID = \"7Gm-zB-s7s\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + } + } + }, + "7va-uJ-IfD.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 7va-uJ-IfD.segmentTitles[0] = \"Lowest Latency\"; ObjectID = \"7va-uJ-IfD\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Lowest Latency" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "低延迟" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "低延迟" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "低延迟" + } + } + } + }, + "7va-uJ-IfD.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 7va-uJ-IfD.segmentTitles[1] = \"Smoothest Video\"; ObjectID = \"7va-uJ-IfD\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Smoothest Video" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "最高流畅度" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "最高流畅度" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "最高流畅度" } } } @@ -374,13 +458,13 @@ } }, "Aiv-r8-9k2.text" : { - "comment" : "Class = \"UILabel\"; text = \"Frame Rate\"; ObjectID = \"Aiv-r8-9k2\";", + "comment" : "Class = \"UILabel\"; text = \"Frame Rate \"; ObjectID = \"Aiv-r8-9k2\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Frame Rate" + "value" : "Frame Rate " } }, "zh-Hans" : { @@ -391,48 +475,18 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "串流帧率" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "串流帧率" } } } }, - "AlL-fp-WCm.text" : { - "comment" : "Class = \"UILabel\"; text = \"Enable On-Screen Widget & Peripherals\"; ObjectID = \"AlL-fp-WCm\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Enable On-Screen Widget & Peripherals" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用屏显控件与外设" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用屏显控件与外设" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用屏显控件与外设" - } - } - } - }, "aup-5k-z6P.text" : { "comment" : "Class = \"UILabel\"; text = \"Show Local Keyboard Toolbar \"; ObjectID = \"aup-5k-z6P\";", "extractionState" : "extracted_with_value", @@ -463,8 +517,80 @@ } } }, - "AXb-DO-LzB.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; AXb-DO-LzB.segmentTitles[0] = \"No\"; ObjectID = \"AXb-DO-LzB\";", + "bFD-Ng-abn.text" : { + "comment" : "Class = \"UILabel\"; text = \"Multi-Controller Mode \"; ObjectID = \"bFD-Ng-abn\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Multi-Controller Mode " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "多手柄模式" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "多手柄模式" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "多手柄模式" + } + } + } + }, + "Bhn-IO-Wlt.title" : { + "comment" : "Class = \"UIBarButtonItem\"; title = \"Exit\"; ObjectID = \"Bhn-IO-Wlt\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Exit" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "退出" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "退出" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "退出" + } + } + } + }, + "bMH-Yb-sb6.normalTitle" : { + "comment" : "Class = \"UIButton\"; normalTitle = \"+\"; ObjectID = \"bMH-Yb-sb6\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "+" + } + } + } + }, + "bw9-4S-s2V.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; bw9-4S-s2V.segmentTitles[0] = \"No\"; ObjectID = \"bw9-4S-s2V\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -475,26 +601,26 @@ }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "关闭" } } } }, - "AXb-DO-LzB.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; AXb-DO-LzB.segmentTitles[1] = \"Yes\"; ObjectID = \"AXb-DO-LzB\";", + "bw9-4S-s2V.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; bw9-4S-s2V.segmentTitles[1] = \"Yes\"; ObjectID = \"bw9-4S-s2V\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -505,170 +631,110 @@ }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "启用" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "启用" } } } }, - "bhC-da-VGd.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[0] = \"Touchpad\"; ObjectID = \"bhC-da-VGd\";", + "byH-Qz-Nbw.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; byH-Qz-Nbw.segmentTitles[0] = \"No\"; ObjectID = \"byH-Qz-Nbw\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Touchpad" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "触控板" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "触控板" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "触控板" + "value" : "关闭" } } } }, - "bhC-da-VGd.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[1] = \"Native Touch\"; ObjectID = \"bhC-da-VGd\";", + "byH-Qz-Nbw.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; byH-Qz-Nbw.segmentTitles[1] = \"Yes\"; ObjectID = \"byH-Qz-Nbw\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Native Touch" + "value" : "Yes" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "多点触控" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "多点触控" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "多点触控" + "value" : "启用" } } } }, - "bhC-da-VGd.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[2] = \"Absolute Touch\"; ObjectID = \"bhC-da-VGd\";", + "bZL-t1-mk7.text" : { + "comment" : "Class = \"UILabel\"; text = \"HDR (Beta) \"; ObjectID = \"bZL-t1-mk7\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Absolute Touch" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "单点鼠标" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "单点鼠标" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "单点鼠标" - } - } - } - }, - "Bhn-IO-Wlt.title" : { - "comment" : "Class = \"UIBarButtonItem\"; title = \"ExportAll\"; ObjectID = \"Bhn-IO-Wlt\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "ExportAll" + "value" : "HDR (Beta) " } }, "zh-Hans" : { "stringUnit" : { "state" : "needs_review", - "value" : "导出所有" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "导出所有" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "导出所有" - } - } - } - }, - "c1r-Hf-b7t.text" : { - "comment" : "Class = \"UILabel\"; text = \"Down Button\"; ObjectID = \"c1r-Hf-b7t\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Down Button" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "鼠标按下" + "value" : "HDR (测试功能)" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "鼠标按下" + "value" : "HDR (测试功能)" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "鼠标按下" + "value" : "HDR (测试功能)" } } } @@ -811,104 +877,56 @@ } } }, - "CpY-Sb-BDc.title" : { - "comment" : "Class = \"UIBarButtonItem\"; title = \"Import\"; ObjectID = \"CpY-Sb-BDc\";", + "cRV-Xw-CVi.text" : { + "comment" : "Class = \"UILabel\"; text = \"Profile:\"; ObjectID = \"cRV-Xw-CVi\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Import" + "value" : "Profile:" } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", - "value" : "导入" + "state" : "needs_review", + "value" : "当前布局: " } }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", - "value" : "导入" + "state" : "needs_review", + "value" : "当前布局: " } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", - "value" : "导入" + "state" : "needs_review", + "value" : "当前布局: " } } } }, - "czn-mj-8d1.title" : { - "comment" : "Class = \"UIBarButtonItem\"; title = \"Exit\"; ObjectID = \"czn-mj-8d1\";", + "DkI-w6-jku.text" : { + "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity: Scaled on 0% of Right Screen \"; ObjectID = \"DkI-w6-jku\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Exit" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "退出" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "退出" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "退出" - } - } - } - }, - "d1N-HH-Aq9.text" : { - "comment" : "Class = \"UILabel\"; text = \"Optimize Game Settings\"; ObjectID = \"d1N-HH-Aq9\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Optimize Game Settings" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "优化游戏设置" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "优化游戏设置" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "优化游戏设置" + "value" : "Touch Pointer Velocity: Scaled on 0% of Right Screen " } } } }, "Dll-7x-18l.text" : { - "comment" : "Class = \"UILabel\"; text = \"Swap A/B and X/Y Buttons\"; ObjectID = \"Dll-7x-18l\";", + "comment" : "Class = \"UILabel\"; text = \"Swap A/B and X/Y Buttons \"; ObjectID = \"Dll-7x-18l\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Swap A/B and X/Y Buttons" + "value" : "Swap A/B and X/Y Buttons " } }, "zh-Hans" : { @@ -919,116 +937,146 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "交换A/B键、X/Y键位置" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "交换A/B键、X/Y键位置" } } } }, - "dpd-Bw-aHE.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; dpd-Bw-aHE.segmentTitles[0] = \"No\"; ObjectID = \"dpd-Bw-aHE\";", + "e4G-id-vjI.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[0] = \"Touchpad\"; ObjectID = \"e4G-id-vjI\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "No" + "value" : "Touchpad" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "关闭" + "value" : "触控板" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "关闭" + "value" : "触控板" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "关闭" + "value" : "触控板" } } } }, - "dpd-Bw-aHE.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; dpd-Bw-aHE.segmentTitles[1] = \"Yes\"; ObjectID = \"dpd-Bw-aHE\";", + "e4G-id-vjI.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[1] = \"Native Touch\"; ObjectID = \"e4G-id-vjI\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Yes" + "value" : "Native Touch" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "启用" + "value" : "多点触控" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "启用" + "value" : "多点触控" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "启用" + "value" : "多点触控" } } } }, - "dqh-nl-heL.title" : { - "comment" : "Class = \"UINavigationItem\"; title = \"Title\"; ObjectID = \"dqh-nl-heL\";", + "e4G-id-vjI.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[2] = \"Native Only\"; ObjectID = \"e4G-id-vjI\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Title" + "value" : "Native Only" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "仅多点触控" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "仅多点触控" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "仅多点触控" + } + } + } + }, + "e4G-id-vjI.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[3] = \"Absolute Touch\"; ObjectID = \"e4G-id-vjI\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Absolute Touch" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "单点鼠标" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "单点鼠标" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "单点鼠标" } } } }, "egA-7n-Dpe.text" : { - "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity\"; ObjectID = \"egA-7n-Dpe\";", + "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity: 100% \"; ObjectID = \"egA-7n-Dpe\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Touch Pointer Velocity" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "触点灵敏度" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "触点灵敏度" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "触点灵敏度" + "value" : "Touch Pointer Velocity: 100% " } } } @@ -1064,409 +1112,289 @@ } }, "FJv-HJ-UYJ.text" : { - "comment" : "Class = \"UILabel\"; text = \"Touch Move Event Interval\"; ObjectID = \"FJv-HJ-UYJ\";", + "comment" : "Class = \"UILabel\"; text = \"Tap Exclusion Area Size for Custom OSC: 200% \"; ObjectID = \"FJv-HJ-UYJ\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Touch Move Event Interval" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "触控移动事件间隔" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "触控移动事件间隔" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "触控移动事件间隔" + "value" : "Tap Exclusion Area Size for Custom OSC: 200% " } } } }, "FwK-oG-vuz.text" : { - "comment" : "Class = \"UILabel\"; text = \"Physical Mouse Wheel Scroll\"; ObjectID = \"FwK-oG-vuz\";", + "comment" : "Class = \"UILabel\"; text = \"Reverse Wheel Direction for Physical Mouse \"; ObjectID = \"FwK-oG-vuz\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Physical Mouse Wheel Scroll" + "value" : "Reverse Wheel Direction for Physical Mouse " } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "物理鼠标滚轮方向" + "value" : "反转物理鼠标滚轮方向" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "物理鼠标滚轮方向" + "value" : "反转物理鼠标滚轮方向" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "物理鼠标滚轮方向" + "value" : "反转物理鼠标滚轮方向" } } } }, - "H8S-aI-EBo.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; H8S-aI-EBo.segmentTitles[0] = \"hovering\"; ObjectID = \"H8S-aI-EBo\";", + "fXq-oD-MrL.text" : { + "comment" : "Class = \"UILabel\"; text = \"Play Audio on PC \"; ObjectID = \"fXq-oD-MrL\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "hovering" + "value" : "Play Audio on PC " } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", - "value" : "悬浮" + "state" : "needs_review", + "value" : "播放主机端声音" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "悬浮" + "value" : "播放主机端声音" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "悬浮" + "value" : "播放主机端声音" } } } }, - "H8S-aI-EBo.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; H8S-aI-EBo.segmentTitles[1] = \"left button\"; ObjectID = \"H8S-aI-EBo\";", + "h5g-U1-Z2J.text" : { + "comment" : "Class = \"UILabel\"; text = \"Touch Mode \"; ObjectID = \"h5g-U1-Z2J\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "left button" + "value" : "Touch Mode " } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", - "value" : "左键" + "state" : "needs_review", + "value" : "触控模式" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "左键" + "value" : "触控模式" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "左键" - } - } - } - }, - "H8S-aI-EBo.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; H8S-aI-EBo.segmentTitles[2] = \"middle button\"; ObjectID = \"H8S-aI-EBo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "middle button" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "中键" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "中键" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "中键" - } - } - } - }, - "H8S-aI-EBo.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; H8S-aI-EBo.segmentTitles[3] = \"right button\"; ObjectID = \"H8S-aI-EBo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "right button" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "右键" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "右键" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "右键" + "value" : "触控模式" } } } }, "hAo-1k-oYF.text" : { - "comment" : "Class = \"UILabel\"; text = \"90° Display Rotation\"; ObjectID = \"hAo-1k-oYF\";", + "comment" : "Class = \"UILabel\"; text = \"Allow 90° Display Rotation in Steaming\"; ObjectID = \"hAo-1k-oYF\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "90° Display Rotation" + "value" : "Allow 90° Display Rotation in Steaming" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "90°转屏" + "value" : "允许90°转屏(App视图、串流时生效)" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "90°转屏" + "value" : "允许90°转屏(App视图、串流时生效)" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "90°转屏" + "value" : "允许90°转屏(App视图、串流时生效)" } } } }, - "hq8-dy-8BF.text" : { - "comment" : "Class = \"UILabel\"; text = \"Custom Resolution\"; ObjectID = \"hq8-dy-8BF\";", + "hm3-EV-h6d.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; hm3-EV-h6d.segmentTitles[0] = \"No\"; ObjectID = \"hm3-EV-h6d\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Custom Resolution" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "自定义分辨率" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "自定义分辨率" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "自定义分辨率" + "value" : "关闭" } } } }, - "iel-xl-xd9.text" : { - "comment" : "Class = \"UILabel\"; text = \"Profile:\"; ObjectID = \"iel-xl-xd9\";", + "hm3-EV-h6d.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; hm3-EV-h6d.segmentTitles[1] = \"Yes\"; ObjectID = \"hm3-EV-h6d\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Profile:" + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" } } } }, "IvI-tw-APj.text" : { - "comment" : "Class = \"UILabel\"; text = \"Open Settings in Streaming\"; ObjectID = \"IvI-tw-APj\";", + "comment" : "Class = \"UILabel\"; text = \"Open Settings in Stream View by Sliding from: \"; ObjectID = \"IvI-tw-APj\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Open Settings in Streaming" + "value" : "Open Settings in Stream View by Sliding from: " } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", - "value" : "串流中打开设置菜单" + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开设置" } }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", - "value" : "串流中打开设置菜单" + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开设置:" } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", - "value" : "串流中打开设置菜单" + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开设置" } } } }, - "kho-5R-daP.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; kho-5R-daP.segmentTitles[0] = \"3 Finger Tap\"; ObjectID = \"kho-5R-daP\";", + "KlC-fG-wEi.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; KlC-fG-wEi.segmentTitles[0] = \"Single\"; ObjectID = \"KlC-fG-wEi\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "3 Finger Tap" + "value" : "Single" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "3指轻按" + "value" : "单手柄" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "3指轻按" + "value" : "单手柄" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "3指轻按" + "value" : "单手柄" } } } }, - "kho-5R-daP.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; kho-5R-daP.segmentTitles[1] = \"4 Finger Tap\"; ObjectID = \"kho-5R-daP\";", + "KlC-fG-wEi.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; KlC-fG-wEi.segmentTitles[1] = \"Auto\"; ObjectID = \"KlC-fG-wEi\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "4 Finger Tap" + "value" : "Auto" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "4指轻按" + "value" : "自动" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "4指轻按" + "value" : "自动" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "4指轻按" + "value" : "自动" } } } }, - "kho-5R-daP.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; kho-5R-daP.segmentTitles[2] = \"5 Finger Tap\"; ObjectID = \"kho-5R-daP\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "5 Finger Tap" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "5指轻按" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "5指轻按" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "5指轻按" - } - } - } - }, - "kho-5R-daP.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; kho-5R-daP.segmentTitles[3] = \"Disabled\"; ObjectID = \"kho-5R-daP\";", - "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" : "禁用" - } - } - } - }, - "KJd-PE-5cS.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; KJd-PE-5cS.segmentTitles[0] = \"No\"; ObjectID = \"KJd-PE-5cS\";", + "KMg-3j-F9p.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; KMg-3j-F9p.segmentTitles[0] = \"No\"; ObjectID = \"KMg-3j-F9p\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -1495,8 +1423,8 @@ } } }, - "KJd-PE-5cS.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; KJd-PE-5cS.segmentTitles[1] = \"Yes\"; ObjectID = \"KJd-PE-5cS\";", + "KMg-3j-F9p.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; KMg-3j-F9p.segmentTitles[1] = \"Yes\"; ObjectID = \"KMg-3j-F9p\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -1525,254 +1453,248 @@ } } }, - "KNe-bN-CDb.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; KNe-bN-CDb.segmentTitles[0] = \"Disabled\"; ObjectID = \"KNe-bN-CDb\";", + "lcO-6v-Tbg.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; lcO-6v-Tbg.segmentTitles[0] = \"No\"; ObjectID = \"lcO-6v-Tbg\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Disabled" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", - "value" : "禁用" + "state" : "translated", + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", - "value" : "禁用" + "state" : "translated", + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", - "value" : "禁用" + "state" : "translated", + "value" : "关闭" } } } }, - "KNe-bN-CDb.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; KNe-bN-CDb.segmentTitles[1] = \"Allowed\"; ObjectID = \"KNe-bN-CDb\";", + "lcO-6v-Tbg.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; lcO-6v-Tbg.segmentTitles[1] = \"Yes\"; ObjectID = \"lcO-6v-Tbg\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Allowed" + "value" : "Yes" } }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", - "value" : "允许" + "state" : "translated", + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", - "value" : "允许" + "state" : "translated", + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", - "value" : "允许" + "state" : "translated", + "value" : "启用" + } + } + } + }, + "lGK-vl-pdw.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; lGK-vl-pdw.segmentTitles[0] = \"30 FPS\"; ObjectID = \"lGK-vl-pdw\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "30 FPS" + } + } + } + }, + "lGK-vl-pdw.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; lGK-vl-pdw.segmentTitles[1] = \"60 FPS\"; ObjectID = \"lGK-vl-pdw\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "60 FPS" + } + } + } + }, + "lGK-vl-pdw.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; lGK-vl-pdw.segmentTitles[2] = \"120 FPS\"; ObjectID = \"lGK-vl-pdw\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "120 FPS" } } } }, "LGV-5y-piG.text" : { - "comment" : "Class = \"UILabel\"; text = \"On-Screen Widgets \"; ObjectID = \"LGV-5y-piG\";", + "comment" : "Class = \"UILabel\"; text = \"On-Screen Controls & Widgets \"; ObjectID = \"LGV-5y-piG\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "On-Screen Widgets " + "value" : "On-Screen Controls & Widgets " } }, "zh-Hans" : { "stringUnit" : { "state" : "needs_review", - "value" : "屏显控件" + "value" : "屏幕虚拟手柄与控件" } }, "zh-Hant" : { "stringUnit" : { "state" : "needs_review", - "value" : "屏显控件" + "value" : "屏幕虚拟手柄与控件" } }, "zh-HK" : { "stringUnit" : { "state" : "needs_review", - "value" : "屏显控件" + "value" : "屏幕虚拟手柄与控件" } } } }, "lMt-4H-fkV.text" : { - "comment" : "Class = \"UILabel\"; text = \"Bitrate\"; ObjectID = \"lMt-4H-fkV\";", + "comment" : "Class = \"UILabel\"; text = \"Bitrate: 10 Mbps \"; ObjectID = \"lMt-4H-fkV\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Bitrate" + "value" : "Bitrate: 10 Mbps " } }, "zh-Hans" : { "stringUnit" : { "state" : "needs_review", - "value" : "串流码率" + "value" : "码率: 10Mbps" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", - "value" : "串流码率" + "state" : "translated", + "value" : "码率: 10Mbps" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", - "value" : "串流码率" + "state" : "translated", + "value" : "码率: 10Mbps" } } } }, "Mm0-xf-9eh.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; Mm0-xf-9eh.segmentTitles[0] = \"Slide From Left Edge\"; ObjectID = \"Mm0-xf-9eh\";", + "comment" : "Class = \"UISegmentedControl\"; Mm0-xf-9eh.segmentTitles[0] = \"Left Screen Edge\"; ObjectID = \"Mm0-xf-9eh\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Slide From Left Edge" + "value" : "Left Screen Edge" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "左边缘" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "左边缘" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "左边缘" } } } }, "Mm0-xf-9eh.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; Mm0-xf-9eh.segmentTitles[1] = \"Slide From Right Edge\"; ObjectID = \"Mm0-xf-9eh\";", + "comment" : "Class = \"UISegmentedControl\"; Mm0-xf-9eh.segmentTitles[1] = \"Right Screen Edge\"; ObjectID = \"Mm0-xf-9eh\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Slide From Right Edge" + "value" : "Right Screen Edge" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "右边缘" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "右边缘" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "右边缘" } } } }, - "MM5-O0-vK3.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; MM5-O0-vK3.segmentTitles[0] = \"No\"; ObjectID = \"MM5-O0-vK3\";", - "extractionState" : "extracted_with_value", + "Mm0-xf-9eh.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; Mm0-xf-9eh.segmentTitles[2] = \"Either\"; ObjectID = \"Mm0-xf-9eh\";", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "No" + "value" : "Either" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "关闭" + "value" : "左右任意" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "关闭" + "value" : "左右任意" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "关闭" - } - } - } - }, - "MM5-O0-vK3.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; MM5-O0-vK3.segmentTitles[1] = \"Yes\"; ObjectID = \"MM5-O0-vK3\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Yes" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - } - } - }, - "MNm-86-RGl.text" : { - "comment" : "Class = \"UILabel\"; text = \"YUV 4:4:4\"; ObjectID = \"MNm-86-RGl\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "YUV 4:4:4" + "value" : "左右任意" } } } @@ -1807,110 +1729,62 @@ } } }, - "mTM-NL-CcF.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; mTM-NL-CcF.segmentTitles[0] = \"Align with System\"; ObjectID = \"mTM-NL-CcF\";", + "nCO-OT-dV1.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; nCO-OT-dV1.segmentTitles[0] = \"No\"; ObjectID = \"nCO-OT-dV1\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Align with System" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "与系统一致" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "与系统一致" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "与系统一致" + "value" : "关闭" } } } }, - "mTM-NL-CcF.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; mTM-NL-CcF.segmentTitles[1] = \"Reversed\"; ObjectID = \"mTM-NL-CcF\";", + "nCO-OT-dV1.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; nCO-OT-dV1.segmentTitles[1] = \"Yes\"; ObjectID = \"nCO-OT-dV1\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Reversed" + "value" : "Yes" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "反转" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "反转" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "反转" - } - } - } - }, - "MUY-2Y-bHi.text" : { - "comment" : "Class = \"UILabel\"; text = \"Touch Mode\"; ObjectID = \"MUY-2Y-bHi\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Touch Mode" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "触控模式" - } - } - } - }, - "nh6-cn-z23.text" : { - "comment" : "Class = \"UILabel\"; text = \"Toggle Local Soft Keyboard\"; ObjectID = \"nh6-cn-z23\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Toggle Local Soft Keyboard" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "打开软键盘" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "打开软键盘" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "打开软键盘" + "value" : "启用" } } } @@ -2005,92 +1879,104 @@ } } }, - "OOg-A3-DdM.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; OOg-A3-DdM.segmentTitles[0] = \"Lowest Latency\"; ObjectID = \"OOg-A3-DdM\";", + "OA2-SA-bBO.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; OA2-SA-bBO.segmentTitles[0] = \"No\"; ObjectID = \"OA2-SA-bBO\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Lowest Latency" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "低延迟" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "低延迟" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "低延迟" + "value" : "关闭" } } } }, - "OOg-A3-DdM.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; OOg-A3-DdM.segmentTitles[1] = \"Smoothest Video\"; ObjectID = \"OOg-A3-DdM\";", + "OA2-SA-bBO.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; OA2-SA-bBO.segmentTitles[1] = \"Yes\"; ObjectID = \"OA2-SA-bBO\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Smoothest Video" + "value" : "Yes" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "最高流畅度" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "最高流畅度" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "最高流畅度" + "value" : "启用" + } + } + } + }, + "OHY-2z-Tm7.text" : { + "comment" : "Class = \"UILabel\"; text = \"Enable YUV 4:4:4 (Beta)\"; ObjectID = \"OHY-2z-Tm7\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Enable YUV 4:4:4 (Beta)" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "YUV 4:4:4 (测试功能)" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "YUV 4:4:4 (测试功能)" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "YUV 4:4:4 (测试功能)" } } } }, "oPM-G6-u5O.text" : { - "comment" : "Class = \"UILabel\"; text = \"Mouse Pointer Velocity\"; ObjectID = \"oPM-G6-u5O\";", + "comment" : "Class = \"UILabel\"; text = \"Mouse Pointer Velocity: 100% \"; ObjectID = \"oPM-G6-u5O\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Mouse Pointer Velocity" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "鼠标指针灵敏度" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "鼠标指针灵敏度" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "鼠标指针灵敏度" + "value" : "Mouse Pointer Velocity: 100% " } } } @@ -2126,55 +2012,31 @@ } }, "pMN-6T-aYE.text" : { - "comment" : "Class = \"UILabel\"; text = \"Gesture Slide Distance\"; ObjectID = \"pMN-6T-aYE\";", + "comment" : "Class = \"UILabel\"; text = \"Slide Distance for Stream View Menu: 0.5 * screen-width \"; ObjectID = \"pMN-6T-aYE\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Gesture Slide Distance" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "手势滑动触发距离" + "value" : "Slide Distance for Stream View Menu: 0.5 * screen-width " } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", - "value" : "手势滑动触发距离" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "手势滑动触发距离" - } - } - } - }, - "Pwa-YK-6Q2.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"Pwa-YK-6Q2\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" + "state" : "translated", + "value" : "打开串流菜单滑动距离: " } } } }, "pYZ-GR-EwO.text" : { - "comment" : "Class = \"UILabel\"; text = \"Resolution \"; ObjectID = \"pYZ-GR-EwO\";", + "comment" : "Class = \"UILabel\"; text = \"Resolution \"; ObjectID = \"pYZ-GR-EwO\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Resolution " + "value" : "Resolution " } }, "zh-Hans" : { @@ -2185,104 +2047,44 @@ }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "串流分辨率" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "串流分辨率" } } } }, "Q2V-XF-4jq.title" : { - "comment" : "Class = \"UINavigationItem\"; title = \"Widget Profiles\"; ObjectID = \"Q2V-XF-4jq\";", + "comment" : "Class = \"UINavigationItem\"; title = \"Controller & Widget Profiles\"; ObjectID = \"Q2V-XF-4jq\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Widget Profiles" + "value" : "Controller & Widget Profiles" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "屏显控件布局" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件布局" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件布局" - } - } - } - }, - "QdG-9a-5AZ.text" : { - "comment" : "Class = \"UILabel\"; text = \"Soft Keyboard Toolbar\"; ObjectID = \"QdG-9a-5AZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Soft Keyboard Toolbar" - } - }, - "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", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Divider Position" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "灵敏度分割位置" + "value" : "屏显手柄与控件布局" } }, "zh-Hant" : { "stringUnit" : { "state" : "needs_review", - "value" : "灵敏度分割位置" + "value" : "屏显手柄与控件布局" } }, "zh-HK" : { "stringUnit" : { "state" : "needs_review", - "value" : "灵敏度分割位置" + "value" : "屏显手柄与控件布局" } } } @@ -2407,6 +2209,36 @@ } } }, + "qSU-wh-tqA.segmentTitles[4]" : { + "comment" : "Class = \"UISegmentedControl\"; qSU-wh-tqA.segmentTitles[4] = \"Custom\"; ObjectID = \"qSU-wh-tqA\";", + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Custom" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + } + } + }, "QYJ-84-bvc.text" : { "comment" : "Class = \"UILabel\"; text = \"Lift Stream View for Local Keyboard \"; ObjectID = \"QYJ-84-bvc\";", "extractionState" : "extracted_with_value", @@ -2437,86 +2269,122 @@ } } }, - "r8L-dl-yLZ.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"r8L-dl-yLZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" - } - } - } - }, "s2i-ZL-Gz4.text" : { - "comment" : "Class = \"UILabel\"; text = \"Statistics Overlay\"; ObjectID = \"s2i-ZL-Gz4\";", + "comment" : "Class = \"UILabel\"; text = \"Statistics Overlay \"; ObjectID = \"s2i-ZL-Gz4\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Statistics Overlay" + "value" : "Statistics Overlay " } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", - "value" : "性能数据叠加" + "state" : "needs_review", + "value" : "性能数据叠加显示" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "性能数据叠加" + "value" : "性能数据叠加显示" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "性能数据叠加" + "value" : "性能数据叠加显示" } } } }, - "SAQ-04-n4h.text" : { - "comment" : "Class = \"UILabel\"; text = \"Multi-Controller Mode\"; ObjectID = \"SAQ-04-n4h\";", + "sIU-PH-H7V.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; sIU-PH-H7V.segmentTitles[0] = \"No\"; ObjectID = \"sIU-PH-H7V\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Multi-Controller Mode" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "多手柄模式" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "多手柄模式" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "多手柄模式" + "value" : "关闭" } } } }, - "sbd-0j-KWS.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"sbd-0j-KWS\";", + "sIU-PH-H7V.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; sIU-PH-H7V.segmentTitles[1] = \"Yes\"; ObjectID = \"sIU-PH-H7V\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "test" + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + } + } + }, + "t9f-V8-GCm.text" : { + "comment" : "Class = \"UILabel\"; text = \"Citrix X1 Mouse Support \"; ObjectID = \"t9f-V8-GCm\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Citrix X1 Mouse Support " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Citrix X1 鼠标支持" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "Citrix X1 鼠标支持" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "Citrix X1 鼠标支持" } } } @@ -2551,26 +2419,62 @@ } } }, - "tG7-oX-P9b.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"tG7-oX-P9b\";", + "uSS-ev-IFe.configuration.title" : { + "comment" : "Class = \"UIButton\"; configuration.title = \"Back to Streaming\"; ObjectID = \"uSS-ev-IFe\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "test" + "value" : "Back to Streaming" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "返回串流" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "返回串流" } } } }, - "vJs-pg-hHe.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"vJs-pg-hHe\";", + "uSS-ev-IFe.normalTitle" : { + "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"uSS-ev-IFe\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "test" + "value" : "Button" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" } } } @@ -2635,163 +2539,337 @@ } } }, - "xfv-K0-1CO.text" : { - "comment" : "Class = \"UILabel\"; text = \"Tap any widget to load configuration (per widget)\"; ObjectID = \"xfv-K0-1CO\";", + "VWB-YB-Ptj.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[2] = \"Disabled\"; ObjectID = \"VWB-YB-Ptj\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Tap any widget to load configuration (per widget)" + "value" : "Disabled" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "禁用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "禁用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "禁用" + } + } + } + }, + "WDY-9o-6Hb.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; WDY-9o-6Hb.segmentTitles[0] = \"No\"; ObjectID = \"WDY-9o-6Hb\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + } + } + }, + "WDY-9o-6Hb.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; WDY-9o-6Hb.segmentTitles[1] = \"Yes\"; ObjectID = \"WDY-9o-6Hb\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + } + } + }, + "WQX-ct-rnt.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; WQX-ct-rnt.segmentTitles[0] = \"Auto\"; ObjectID = \"WQX-ct-rnt\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Auto" + } + } + } + }, + "WQX-ct-rnt.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; WQX-ct-rnt.segmentTitles[1] = \"Device Motion\"; ObjectID = \"WQX-ct-rnt\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Device Motion" + } + } + } + }, + "WQX-ct-rnt.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; WQX-ct-rnt.segmentTitles[2] = \"Controller Motion\"; ObjectID = \"WQX-ct-rnt\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Controller Motion" + } + } + } + }, + "WSI-9V-G6c.text" : { + "comment" : "Class = \"UILabel\"; text = \"Optimize Game Settings \"; ObjectID = \"WSI-9V-G6c\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Optimize Game Settings " } }, "zh-Hans" : { "stringUnit" : { "state" : "needs_review", - "value" : "轻按任意控件加载配置 (各控件独立)" + "value" : "优化游戏设置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "优化游戏设置" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "优化游戏设置" + } + } + } + }, + "yq8-Hq-UWQ.configuration.title" : { + "comment" : "Class = \"UIButton\"; configuration.title = \"Exit\"; ObjectID = \"yq8-Hq-UWQ\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Exit" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "退出" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "退出" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "退出" + } + } + } + }, + "yq8-Hq-UWQ.normalTitle" : { + "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"yq8-Hq-UWQ\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Button" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "退出" } }, "zh-Hant" : { "stringUnit" : { "state" : "needs_review", - "value" : "轻按任意控件加载配置 (各控件独立)" + "value" : "退出" } }, "zh-HK" : { "stringUnit" : { "state" : "needs_review", - "value" : "轻按任意控件加载配置 (各控件独立)" + "value" : "退出" } } } }, "yY7-Sf-Zes.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; yY7-Sf-Zes.segmentTitles[0] = \"Slide From Left Edge\"; ObjectID = \"yY7-Sf-Zes\";", + "comment" : "Class = \"UISegmentedControl\"; yY7-Sf-Zes.segmentTitles[0] = \"Left Screen Edge\"; ObjectID = \"yY7-Sf-Zes\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Slide From Left Edge" + "value" : "Left Screen Edge" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "左边缘" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "左边缘" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "左边缘" } } } }, "yY7-Sf-Zes.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; yY7-Sf-Zes.segmentTitles[1] = \"Slide From Right Edge\"; ObjectID = \"yY7-Sf-Zes\";", + "comment" : "Class = \"UISegmentedControl\"; yY7-Sf-Zes.segmentTitles[1] = \"Right Screen Edge\"; ObjectID = \"yY7-Sf-Zes\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Slide From Right Edge" + "value" : "Right Screen Edge" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "右边缘" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "右边缘" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "右边缘" } } } }, "Zp4-fA-IeL.text" : { - "comment" : "Class = \"UILabel\"; text = \"Open Toolbox in Streaming\"; ObjectID = \"Zp4-fA-IeL\";", + "comment" : "Class = \"UILabel\"; text = \"Open Command Tool in Stream View by Sliding from: \"; ObjectID = \"Zp4-fA-IeL\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Open Toolbox in Streaming" + "value" : "Open Command Tool in Stream View by Sliding from: " } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", - "value" : "串流中打开工具箱" + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开命令工具" } }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", - "value" : "串流中打开工具箱" + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开命令工具" } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", - "value" : "串流中打开工具箱" - } - } - } - }, - "ZuV-4A-0Zb.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"ZuV-4A-0Zb\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开命令工具" } } } }, "ZWC-Gw-pSq.text" : { - "comment" : "Class = \"UILabel\"; text = \"Frame Pacing Preference\"; ObjectID = \"ZWC-Gw-pSq\";", + "comment" : "Class = \"UILabel\"; text = \"Frame Pacing Preference \"; ObjectID = \"ZWC-Gw-pSq\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Frame Pacing Preference" + "value" : "Frame Pacing Preference " } }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "帧步进控制" } }, "zh-Hant" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "帧步进控制" } }, "zh-HK" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "帧步进控制" } } diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings index 14703690..11b6ab84 100644 --- a/VoidLink/mul.lproj/iPhone.xcstrings +++ b/VoidLink/mul.lproj/iPhone.xcstrings @@ -1,746 +1,38 @@ { "sourceLanguage" : "en", "strings" : { - "0gh-fD-6V5.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; 0gh-fD-6V5.segmentTitles[0] = \"Disabled\"; ObjectID = \"0gh-fD-6V5\";", + "1UZ-3M-k6c.text" : { + "comment" : "Class = \"UILabel\"; text = \"Enable YUV 4:4:4 (Beta)\"; ObjectID = \"1UZ-3M-k6c\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Disabled" + "value" : "Enable YUV 4:4:4 (Beta)" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "禁用" + "value" : "YUV 4:4:4 (测试功能)" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "禁用" + "value" : "YUV 4:4:4 (测试功能)" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "禁用" + "value" : "YUV 4:4:4 (测试功能)" } } } }, - "0gh-fD-6V5.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; 0gh-fD-6V5.segmentTitles[1] = \"Allowed\"; ObjectID = \"0gh-fD-6V5\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Allowed" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "允许" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "允许" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "允许" - } - } - } - }, - "3av-lc-tcF.text" : { - "comment" : "Class = \"UILabel\"; text = \"Enable On-Screen Widget & Peripherals\"; ObjectID = \"3av-lc-tcF\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Enable On-Screen Widget & Peripherals" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用屏显控件与外设" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用屏显控件与外设" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用屏显控件与外设" - } - } - } - }, - "3GB-Km-AL8.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; 3GB-Km-AL8.segmentTitles[0] = \"No\"; ObjectID = \"3GB-Km-AL8\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "No" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "禁用" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "禁用" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "禁用" - } - } - } - }, - "3GB-Km-AL8.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; 3GB-Km-AL8.segmentTitles[1] = \"Yes\"; ObjectID = \"3GB-Km-AL8\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Yes" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - } - } - }, - "3Hh-2q-gas.text" : { - "comment" : "Class = \"UILabel\"; text = \"Preferred Codec\"; ObjectID = \"3Hh-2q-gas\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Preferred Codec" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "视频编解码" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "视频编解码" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "视频编解码" - } - } - } - }, - "4pE-po-Zn1.normalTitle" : { - "comment" : "Class = \"UIButton\"; normalTitle = \"Edit\"; ObjectID = \"4pE-po-Zn1\";", - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Edit" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "编辑" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "编辑" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "编辑" - } - } - } - }, - "5JB-m0-nUF.text" : { - "comment" : "Class = \"UILabel\"; text = \"YUV 4:4:4\"; ObjectID = \"5JB-m0-nUF\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "YUV 4:4:4" - } - } - } - }, - "5NE-u6-yIU.text" : { - "comment" : "Class = \"UILabel\"; text = \"Play Audio on PC\"; ObjectID = \"5NE-u6-yIU\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Play Audio on PC" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "播放主机端声音" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "播放主机端声音" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "播放主机端声音" - } - } - } - }, - "5pN-Sn-SCN.title" : { - "comment" : "Class = \"UINavigationItem\"; title = \"Controller & Widget Profiles\"; ObjectID = \"5pN-Sn-SCN\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Controller & Widget Profiles" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件布局" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件布局" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件布局" - } - } - } - }, - "5uF-E5-hpX.text" : { - "comment" : "Class = \"UILabel\"; text = \"On-Screen Widgets \"; ObjectID = \"5uF-E5-hpX\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "On-Screen Widgets " - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏显控件" - } - } - } - }, - "5Y7-To-ca2.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; 5Y7-To-ca2.segmentTitles[0] = \"H.264\"; ObjectID = \"5Y7-To-ca2\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "H.264" - } - } - } - }, - "5Y7-To-ca2.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; 5Y7-To-ca2.segmentTitles[1] = \"HEVC\"; ObjectID = \"5Y7-To-ca2\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "HEVC" - } - } - } - }, - "5Y7-To-ca2.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; 5Y7-To-ca2.segmentTitles[2] = \"AV1\"; ObjectID = \"5Y7-To-ca2\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "AV1" - } - } - } - }, - "5Y7-To-ca2.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; 5Y7-To-ca2.segmentTitles[3] = \"Auto\"; ObjectID = \"5Y7-To-ca2\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Auto" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "自动" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "自动" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "自动" - } - } - } - }, - "6g1-G6-jZx.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; 6g1-G6-jZx.segmentTitles[0] = \"3 Finger Tap\"; ObjectID = \"6g1-G6-jZx\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "3 Finger Tap" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "3指轻按" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "3指轻按" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "3指轻按" - } - } - } - }, - "6g1-G6-jZx.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; 6g1-G6-jZx.segmentTitles[1] = \"4 Finger Tap\"; ObjectID = \"6g1-G6-jZx\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "4 Finger Tap" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "4指轻按" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "4指轻按" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "4指轻按" - } - } - } - }, - "6g1-G6-jZx.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; 6g1-G6-jZx.segmentTitles[2] = \"5 Finger Tap\"; ObjectID = \"6g1-G6-jZx\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "5 Finger Tap" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "5指轻按" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "5指轻按" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "5指轻按" - } - } - } - }, - "6g1-G6-jZx.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; 6g1-G6-jZx.segmentTitles[3] = \"Disabled\"; ObjectID = \"6g1-G6-jZx\";", - "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" : "禁用" - } - } - } - }, - "7nX-ra-hKS.text" : { - "comment" : "Class = \"UILabel\"; text = \"HDR\"; ObjectID = \"7nX-ra-hKS\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "HDR" - } - } - } - }, - "7Sl-WI-zyo.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; 7Sl-WI-zyo.segmentTitles[0] = \"360p\"; ObjectID = \"7Sl-WI-zyo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "360p" - } - } - } - }, - "7Sl-WI-zyo.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; 7Sl-WI-zyo.segmentTitles[1] = \"720p\"; ObjectID = \"7Sl-WI-zyo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "720p" - } - } - } - }, - "7Sl-WI-zyo.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; 7Sl-WI-zyo.segmentTitles[2] = \"1080p\"; ObjectID = \"7Sl-WI-zyo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "1080p" - } - } - } - }, - "7Sl-WI-zyo.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; 7Sl-WI-zyo.segmentTitles[3] = \"4K\"; ObjectID = \"7Sl-WI-zyo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "4K" - } - } - } - }, - "7Sl-WI-zyo.segmentTitles[4]" : { - "comment" : "Class = \"UISegmentedControl\"; 7Sl-WI-zyo.segmentTitles[4] = \"Safe Area\"; ObjectID = \"7Sl-WI-zyo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Safe Area" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "安全区域" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "安全区域" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "安全区域" - } - } - } - }, - "7Sl-WI-zyo.segmentTitles[5]" : { - "comment" : "Class = \"UISegmentedControl\"; 7Sl-WI-zyo.segmentTitles[5] = \"FullScr/Window\"; ObjectID = \"7Sl-WI-zyo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "FullScr/Window" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "全屏/窗口" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "全屏/窗口" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "全屏/窗口" - } - } - } - }, - "7Sl-WI-zyo.segmentTitles[6]" : { - "comment" : "Class = \"UISegmentedControl\"; 7Sl-WI-zyo.segmentTitles[6] = \"Custom\"; ObjectID = \"7Sl-WI-zyo\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Custom" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "自定义" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "自定义" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "自定义" - } - } - } - }, - "9dX-RB-Fpa.text" : { - "comment" : "Class = \"UILabel\"; text = \"Optimize Game Settings\"; ObjectID = \"9dX-RB-Fpa\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Optimize Game Settings" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "优化游戏设置" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "优化游戏设置" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "优化游戏设置" - } - } - } - }, - "9Gg-66-UdB.text" : { - "comment" : "Class = \"UILabel\"; text = \"Tap any widget to load configuration (per widget)\"; ObjectID = \"9Gg-66-UdB\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Tap any widget to load configuration (per widget)" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "轻按任意控件加载配置 (各控件独立)" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "轻按任意控件加载配置 (各控件独立)" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "轻按任意控件加载配置 (各控件独立)" - } - } - } - }, - "885-w2-VAD.text" : { - "comment" : "Class = \"UILabel\"; text = \"Swap A/B and X/Y Buttons\"; ObjectID = \"885-w2-VAD\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Swap A/B and X/Y Buttons" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "交换 A/B、 X/Y 键位置" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "交换 A/B、 X/Y 键位置" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "交换 A/B、 X/Y 键位置" - } - } - } - }, - "A9r-dE-rT4.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; A9r-dE-rT4.segmentTitles[0] = \"Touchpad\"; ObjectID = \"A9r-dE-rT4\";", + "2lg-HW-tku.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 2lg-HW-tku.segmentTitles[0] = \"Touchpad\"; ObjectID = \"2lg-HW-tku\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -769,8 +61,8 @@ } } }, - "A9r-dE-rT4.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; A9r-dE-rT4.segmentTitles[1] = \"Native Touch\"; ObjectID = \"A9r-dE-rT4\";", + "2lg-HW-tku.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 2lg-HW-tku.segmentTitles[1] = \"Native Touch\"; ObjectID = \"2lg-HW-tku\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -799,8 +91,38 @@ } } }, - "A9r-dE-rT4.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; A9r-dE-rT4.segmentTitles[2] = \"Absolute Touch\"; ObjectID = \"A9r-dE-rT4\";", + "2lg-HW-tku.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; 2lg-HW-tku.segmentTitles[2] = \"Native Only\"; ObjectID = \"2lg-HW-tku\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Native Only" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "仅多点触控" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "仅多点触控" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "仅多点触控" + } + } + } + }, + "2lg-HW-tku.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; 2lg-HW-tku.segmentTitles[3] = \"Absolute Touch\"; ObjectID = \"2lg-HW-tku\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -829,44 +151,224 @@ } } }, - "awK-Ei-T9i.text" : { - "comment" : "Class = \"UILabel\"; text = \"Open Toolbox in Streaming\"; ObjectID = \"awK-Ei-T9i\";", + "2Lx-OY-ZPu.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 2Lx-OY-ZPu.segmentTitles[0] = \"Left Screen Edge\"; ObjectID = \"2Lx-OY-ZPu\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Open Toolbox in Streaming" + "value" : "Left Screen Edge" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "串流中打开工具箱" + "value" : "左边缘" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "串流中打开工具箱" + "value" : "左边缘" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "串流中打开工具箱" + "value" : "左边缘" } } } }, - "Bda-3L-Wtg.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; Bda-3L-Wtg.segmentTitles[0] = \"Off\"; ObjectID = \"Bda-3L-Wtg\";", + "2Lx-OY-ZPu.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 2Lx-OY-ZPu.segmentTitles[1] = \"Right Screen Edge\"; ObjectID = \"2Lx-OY-ZPu\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Off" + "value" : "Right Screen Edge" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "右边缘" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "右边缘" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "右边缘" + } + } + } + }, + "2Lx-OY-ZPu.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; 2Lx-OY-ZPu.segmentTitles[2] = \"Either\"; ObjectID = \"2Lx-OY-ZPu\";", + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Either" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "左右任意" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "左右任意" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "左右任意" + } + } + } + }, + "2LZ-cX-teZ.text" : { + "comment" : "Class = \"UILabel\"; text = \"Larger Sticks & L1/R1 Buttons \"; ObjectID = \"2LZ-cX-teZ\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Larger Sticks & L1/R1 Buttons " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "更大的摇杆和L1/R1按键" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "更大的摇杆和L1/R1按键" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "更大的摇杆和L1/R1按键" + } + } + } + }, + "2p1-r1-Gvf.text" : { + "comment" : "Class = \"UILabel\"; text = \"Swap A/B and X/Y Buttons \"; ObjectID = \"2p1-r1-Gvf\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Swap A/B and X/Y Buttons " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "交换A/B键、X/Y键位置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "交换A/B键、X/Y键位置" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "交换A/B键、X/Y键位置" + } + } + } + }, + "4Qy-hB-oa5.text" : { + "comment" : "Class = \"UILabel\"; text = \"External Display Mode\"; ObjectID = \"4Qy-hB-oa5\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "External Display Mode" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "外接显示模式" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "外接显示模式" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "外接显示模式" + } + } + } + }, + "5pN-Sn-SCN.title" : { + "comment" : "Class = \"UINavigationItem\"; title = \"Controller & Widget Profiles\"; ObjectID = \"5pN-Sn-SCN\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Controller & Widget Profiles" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "屏显手柄与控件布局" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "屏显手柄与控件布局" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "屏显手柄与控件布局" + } + } + } + }, + "6fE-k6-IG0.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 6fE-k6-IG0.segmentTitles[0] = \"No\"; ObjectID = \"6fE-k6-IG0\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" } }, "zh-Hans" : { @@ -889,92 +391,344 @@ } } }, - "Bda-3L-Wtg.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; Bda-3L-Wtg.segmentTitles[1] = \"Simplified\"; ObjectID = \"Bda-3L-Wtg\";", + "6fE-k6-IG0.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 6fE-k6-IG0.segmentTitles[1] = \"Yes\"; ObjectID = \"6fE-k6-IG0\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Simplified" + "value" : "Yes" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "简单" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "简单" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "简单" + "value" : "启用" } } } }, - "Bda-3L-Wtg.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; Bda-3L-Wtg.segmentTitles[2] = \"Detailed\"; ObjectID = \"Bda-3L-Wtg\";", + "6Lj-ss-Tj8.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 6Lj-ss-Tj8.segmentTitles[0] = \"Auto\"; ObjectID = \"6Lj-ss-Tj8\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Detailed" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "详细" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "详细" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "详细" + "value" : "Auto" } } } }, - "Bnb-RZ-jNp.text" : { - "comment" : "Class = \"UILabel\"; text = \"Multi-Controller Mode\"; ObjectID = \"Bnb-RZ-jNp\";", + "6Lj-ss-Tj8.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 6Lj-ss-Tj8.segmentTitles[1] = \"Device Motion\"; ObjectID = \"6Lj-ss-Tj8\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Multi-Controller Mode" + "value" : "Device Motion" + } + } + } + }, + "6Lj-ss-Tj8.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; 6Lj-ss-Tj8.segmentTitles[2] = \"Controller Motion\"; ObjectID = \"6Lj-ss-Tj8\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Controller Motion" + } + } + } + }, + "8GA-Js-kQN.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 8GA-Js-kQN.segmentTitles[0] = \"No\"; ObjectID = \"8GA-Js-kQN\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "多手柄模式" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "多手柄模式" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "多手柄模式" + "value" : "关闭" + } + } + } + }, + "8GA-Js-kQN.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 8GA-Js-kQN.segmentTitles[1] = \"Yes\"; ObjectID = \"8GA-Js-kQN\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + } + } + }, + "8kV-xZ-73k.text" : { + "comment" : "Class = \"UILabel\"; text = \"Open Settings in Stream View by Sliding from: \"; ObjectID = \"8kV-xZ-73k\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Open Settings in Stream View by Sliding from: " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "串流中从以下屏幕边缘滑动打开设置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "串流中从以下屏幕边缘滑动打开设置" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "串流中从以下屏幕边缘滑动打开设置" + } + } + } + }, + "8zy-ri-Dqc.text" : { + "comment" : "Class = \"UILabel\"; text = \"Resolution \"; ObjectID = \"8zy-ri-Dqc\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Resolution " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流分辨率" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流分辨率" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流分辨率" + } + } + } + }, + "9xD-GL-9xq.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 9xD-GL-9xq.segmentTitles[0] = \"No\"; ObjectID = \"9xD-GL-9xq\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + } + } + }, + "9xD-GL-9xq.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 9xD-GL-9xq.segmentTitles[1] = \"Yes\"; ObjectID = \"9xD-GL-9xq\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + } + } + }, + "AbS-CW-fjP.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; AbS-CW-fjP.segmentTitles[0] = \"H.264\"; ObjectID = \"AbS-CW-fjP\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "H.264" + } + } + } + }, + "AbS-CW-fjP.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; AbS-CW-fjP.segmentTitles[1] = \"HEVC\"; ObjectID = \"AbS-CW-fjP\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "HEVC" + } + } + } + }, + "AbS-CW-fjP.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; AbS-CW-fjP.segmentTitles[2] = \"AV1\"; ObjectID = \"AbS-CW-fjP\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "AV1" + } + } + } + }, + "AbS-CW-fjP.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; AbS-CW-fjP.segmentTitles[3] = \"Auto\"; ObjectID = \"AbS-CW-fjP\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Auto" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自动" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "自动" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "自动" + } + } + } + }, + "BEG-Id-J8y.text" : { + "comment" : "Class = \"UILabel\"; text = \"Preferred Codec \"; ObjectID = \"BEG-Id-J8y\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Preferred Codec " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "视频编解码" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "视频编解码" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "视频编解码" } } } @@ -1009,278 +763,122 @@ } } }, - "C9B-Rx-YCP.text" : { - "comment" : "Class = \"UILabel\"; text = \"Physical Mouse Wheel Scroll\"; ObjectID = \"C9B-Rx-YCP\";", + "c6f-bJ-Vji.text" : { + "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity: 100% \"; ObjectID = \"c6f-bJ-Vji\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Physical Mouse Wheel Scroll" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "物理鼠标滚轮方向" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "物理鼠标滚轮方向" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "物理鼠标滚轮方向" + "value" : "Touch Pointer Velocity: 100% " } } } }, - "ci6-ak-aCa.text" : { - "comment" : "Class = \"UILabel\"; text = \"Custom Resolution\"; ObjectID = \"ci6-ak-aCa\";", + "c8T-vY-LOX.text" : { + "comment" : "Class = \"UILabel\"; text = \"Player 1 Motion Mode\"; ObjectID = \"c8T-vY-LOX\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Custom Resolution" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "自定义分辨率" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "自定义分辨率" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "自定义分辨率" + "value" : "Player 1 Motion Mode" } } } }, - "cti-T5-cSE.text" : { - "comment" : "Class = \"UILabel\"; text = \"Gesture Slide Distance\"; ObjectID = \"cti-T5-cSE\";", + "CHp-14-aTt.text" : { + "comment" : "Class = \"UILabel\"; text = \"Touch Mode \"; ObjectID = \"CHp-14-aTt\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Gesture Slide Distance" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "手势滑动触发距离" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "手势滑动触发距离" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "手势滑动触发距离" - } - } - } - }, - "D9X-7p-9oc.title" : { - "comment" : "Class = \"UIBarButtonItem\"; title = \"ExportAll\"; ObjectID = \"D9X-7p-9oc\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "ExportAll" + "value" : "Touch Mode " } }, "zh-Hans" : { "stringUnit" : { "state" : "needs_review", - "value" : "导出所有" + "value" : "触控模式" } }, "zh-Hant" : { "stringUnit" : { "state" : "needs_review", - "value" : "导出所有" + "value" : "触控模式" } }, "zh-HK" : { "stringUnit" : { "state" : "needs_review", - "value" : "导出所有" + "value" : "触控模式" } } } }, - "dAN-Gy-Eg7.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; dAN-Gy-Eg7.segmentTitles[0] = \"30 FPS\"; ObjectID = \"dAN-Gy-Eg7\";", + "CMK-cS-h9b.configuration.title" : { + "comment" : "Class = \"UIButton\"; configuration.title = \"Exit\"; ObjectID = \"CMK-cS-h9b\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "30 FPS" - } - } - } - }, - "dAN-Gy-Eg7.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; dAN-Gy-Eg7.segmentTitles[1] = \"60 FPS\"; ObjectID = \"dAN-Gy-Eg7\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "60 FPS" - } - } - } - }, - "dAN-Gy-Eg7.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; dAN-Gy-Eg7.segmentTitles[2] = \"120 FPS\"; ObjectID = \"dAN-Gy-Eg7\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "120 FPS" - } - } - } - }, - "dJh-Ck-ugh.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"dJh-Ck-ugh\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" - } - } - } - }, - "E7F-vx-pnM.text" : { - "comment" : "Class = \"UILabel\"; text = \"Frame Rate\"; ObjectID = \"E7F-vx-pnM\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Frame Rate" + "value" : "Exit" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "串流帧率" + "value" : "退出" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "串流帧率" + "value" : "退出" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "串流帧率" + "value" : "退出" } } } }, - "ECJ-bg-fRJ.text" : { - "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity\"; ObjectID = \"ECJ-bg-fRJ\";", + "CMK-cS-h9b.normalTitle" : { + "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"CMK-cS-h9b\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Touch Pointer Velocity" + "value" : "Button" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "触点灵敏度" + "value" : "退出" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "触点灵敏度" + "value" : "退出" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "触点灵敏度" + "value" : "退出" } } } }, - "eiL-iX-G3Z.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"eiL-iX-G3Z\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" - } - } - } - }, - "epe-C9-jWg.text" : { - "comment" : "Class = \"UILabel\"; text = \"Open Settings in Streaming\"; ObjectID = \"epe-C9-jWg\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Open Settings in Streaming" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流中打开设置菜单" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流中打开设置菜单" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流中打开设置菜单" - } - } - } - }, - "F2F-TK-tyR.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; F2F-TK-tyR.segmentTitles[0] = \"Lowest Latency\"; ObjectID = \"F2F-TK-tyR\";", + "d2a-Ka-H2c.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; d2a-Ka-H2c.segmentTitles[0] = \"Lowest Latency\"; ObjectID = \"d2a-Ka-H2c\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -1309,8 +907,8 @@ } } }, - "F2F-TK-tyR.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; F2F-TK-tyR.segmentTitles[1] = \"Smoothest Video\"; ObjectID = \"F2F-TK-tyR\";", + "d2a-Ka-H2c.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; d2a-Ka-H2c.segmentTitles[1] = \"Smoothest Video\"; ObjectID = \"d2a-Ka-H2c\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -1339,26 +937,254 @@ } } }, - "f46-Pt-0Pv.text" : { - "comment" : "Class = \"UILabel\"; text = \"Profile:\"; ObjectID = \"f46-Pt-0Pv\";", + "D9X-7p-9oc.title" : { + "comment" : "Class = \"UIBarButtonItem\"; title = \"Exit\"; ObjectID = \"D9X-7p-9oc\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Profile:" + "value" : "Exit" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "退出" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "退出" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "退出" } } } }, - "fcy-zp-LGa.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"fcy-zp-LGa\";", + "Dfl-gL-00M.text" : { + "comment" : "Class = \"UILabel\"; text = \"Tap Exclusion Area Size for Custom OSC: 200% \"; ObjectID = \"Dfl-gL-00M\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "test" + "value" : "Tap Exclusion Area Size for Custom OSC: 200% " + } + } + } + }, + "dLF-qJ-2nY.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; dLF-qJ-2nY.segmentTitles[0] = \"30 FPS\"; ObjectID = \"dLF-qJ-2nY\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "30 FPS" + } + } + } + }, + "dLF-qJ-2nY.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; dLF-qJ-2nY.segmentTitles[1] = \"60 FPS\"; ObjectID = \"dLF-qJ-2nY\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "60 FPS" + } + } + } + }, + "dLF-qJ-2nY.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; dLF-qJ-2nY.segmentTitles[2] = \"120 FPS\"; ObjectID = \"dLF-qJ-2nY\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "120 FPS" + } + } + } + }, + "ecG-dC-PT1.text" : { + "comment" : "Class = \"UILabel\"; text = \"Mouse Pointer Velocity: 100% \"; ObjectID = \"ecG-dC-PT1\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Mouse Pointer Velocity: 100% " + } + } + } + }, + "Ex1-zI-oAH.text" : { + "comment" : "Class = \"UILabel\"; text = \"Slide Distance for Stream View Menu: 0.5 * screen-width \"; ObjectID = \"Ex1-zI-oAH\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Slide Distance for Stream View Menu: 0.5 * screen-width " + } + } + } + }, + "F96-Um-Q6t.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[0] = \"Restricted by Window\"; ObjectID = \"F96-Um-Q6t\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Restricted by Window" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "被窗口捕获" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "被窗口捕获" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "被窗口捕获" + } + } + } + }, + "F96-Um-Q6t.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[1] = \"Hidden\"; ObjectID = \"F96-Um-Q6t\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hidden" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏(绝对坐标)" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏(绝对坐标)" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏(绝对坐标)" + } + } + } + }, + "F96-Um-Q6t.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[2] = \"Visible\"; ObjectID = \"F96-Um-Q6t\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Visible" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见(绝对坐标)" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见(绝对坐标)" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见(绝对坐标)" + } + } + } + }, + "FqF-bM-afQ.configuration.title" : { + "comment" : "Class = \"UIButton\"; configuration.title = \"Back to Streaming\"; ObjectID = \"FqF-bM-afQ\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Back to Streaming" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + } + } + }, + "FqF-bM-afQ.normalTitle" : { + "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"FqF-bM-afQ\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Button" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回串流" } } } @@ -1393,170 +1219,38 @@ } } }, - "GQm-O3-z8H.text" : { - "comment" : "Class = \"UILabel\"; text = \"Frame Pacing Preference\"; ObjectID = \"GQm-O3-z8H\";", + "glN-9Q-GKD.text" : { + "comment" : "Class = \"UILabel\"; text = \"Citrix X1 Mouse Support \"; ObjectID = \"glN-9Q-GKD\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Frame Pacing Preference" + "value" : "Citrix X1 Mouse Support " } }, "zh-Hans" : { "stringUnit" : { - "state" : "translated", - "value" : "帧步进控制" + "state" : "needs_review", + "value" : "Citrix X1 鼠标支持" } }, "zh-Hant" : { "stringUnit" : { - "state" : "translated", - "value" : "帧步进控制" + "state" : "needs_review", + "value" : "Citrix X1 鼠标支持" } }, "zh-HK" : { "stringUnit" : { - "state" : "translated", - "value" : "帧步进控制" + "state" : "needs_review", + "value" : "Citrix X1 鼠标支持" } } } }, - "hn6-X9-TaI.text" : { - "comment" : "Class = \"UILabel\"; text = \"Mouse Pointer Velocity\"; ObjectID = \"hn6-X9-TaI\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Mouse Pointer Velocity" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "鼠标指针灵敏度" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "鼠标指针灵敏度" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "鼠标指针灵敏度" - } - } - } - }, - "HQS-Vu-wQO.text" : { - "comment" : "Class = \"UILabel\"; text = \"Citrix X1 Mouse\"; ObjectID = \"HQS-Vu-wQO\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Citrix X1 Mouse" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Citrix X1 鼠标" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "Citrix X1 鼠标" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "Citrix X1 鼠标" - } - } - } - }, - "HvT-Ek-DAx.text" : { - "comment" : "Class = \"UILabel\"; text = \"Bitrate\"; ObjectID = \"HvT-Ek-DAx\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Bitrate" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流码率" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流码率" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流码率" - } - } - } - }, - "hxU-Gq-tIl.text" : { - "comment" : "Class = \"UILabel\"; text = \"Divider Position\"; ObjectID = \"hxU-Gq-tIl\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Divider Position" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "灵敏度分割位置" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "灵敏度分割位置" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "灵敏度分割位置" - } - } - } - }, - "Idx-O1-5dn.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"Idx-O1-5dn\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" - } - } - } - }, - "INW-Cp-Ybl.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; INW-Cp-Ybl.segmentTitles[0] = \"No\"; ObjectID = \"INW-Cp-Ybl\";", + "Gob-Lu-b1y.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; Gob-Lu-b1y.segmentTitles[0] = \"No\"; ObjectID = \"Gob-Lu-b1y\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -1564,11 +1258,29 @@ "state" : "new", "value" : "No" } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } } } }, - "INW-Cp-Ybl.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; INW-Cp-Ybl.segmentTitles[1] = \"Yes\"; ObjectID = \"INW-Cp-Ybl\";", + "Gob-Lu-b1y.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; Gob-Lu-b1y.segmentTitles[1] = \"Yes\"; ObjectID = \"Gob-Lu-b1y\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -1576,113 +1288,203 @@ "state" : "new", "value" : "Yes" } - } - } - }, - "kva-gQ-CZh.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"kva-gQ-CZh\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" - } - } - } - }, - "lwy-Nu-hQj.text" : { - "comment" : "Class = \"UILabel\"; text = \"External Display Mode\"; ObjectID = \"lwy-Nu-hQj\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "External Display Mode" - } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "外接显示模式" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "外接显示模式" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "外接显示模式" + "value" : "启用" } } } }, - "mdA-jF-9Mf.text" : { - "comment" : "Class = \"UILabel\"; text = \"Local Mouse Pointer\"; ObjectID = \"mdA-jF-9Mf\";", + "hxa-gT-JXC.text" : { + "comment" : "Class = \"UILabel\"; text = \"Optimize Game Settings \"; ObjectID = \"hxa-gT-JXC\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Local Mouse Pointer" + "value" : "Optimize Game Settings " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "优化游戏设置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "优化游戏设置" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "优化游戏设置" + } + } + } + }, + "HZT-dd-DuQ.text" : { + "comment" : "Class = \"UILabel\"; text = \"On-Screen Controls & Widgets \"; ObjectID = \"HZT-dd-DuQ\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "On-Screen Controls & Widgets " } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "本地鼠标指针" + "value" : "屏幕虚拟手柄与控件" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "本地鼠标指针" + "value" : "屏幕虚拟手柄与控件" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "本地鼠标指针" + "value" : "屏幕虚拟手柄与控件" } } } }, - "MMc-Yp-e6i.text" : { - "comment" : "Class = \"UILabel\"; text = \"Async Native Touch\"; ObjectID = \"MMc-Yp-e6i\";", + "Jps-kj-bYJ.text" : { + "comment" : "Class = \"UILabel\"; text = \"Multi-Controller Mode \"; ObjectID = \"Jps-kj-bYJ\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Async Native Touch" + "value" : "Multi-Controller Mode " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "多手柄模式" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "多手柄模式" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "多手柄模式" } } } }, - "msE-2o-R3Q.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; msE-2o-R3Q.segmentTitles[0] = \"No\"; ObjectID = \"msE-2o-R3Q\";", + "Kkv-DF-MAl.text" : { + "comment" : "Class = \"UILabel\"; text = \"Frame Rate \"; ObjectID = \"Kkv-DF-MAl\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "No" + "value" : "Frame Rate " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流帧率" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流帧率" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流帧率" } } } }, - "msE-2o-R3Q.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; msE-2o-R3Q.segmentTitles[1] = \"Yes\"; ObjectID = \"msE-2o-R3Q\";", + "lBe-dn-yc7.text" : { + "comment" : "Class = \"UILabel\"; text = \"HDR (Beta) \"; ObjectID = \"lBe-dn-yc7\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Yes" + "value" : "HDR (Beta) " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "HDR (测试功能)" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "HDR (测试功能)" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "HDR (测试功能)" + } + } + } + }, + "m1k-oE-fIO.text" : { + "comment" : "Class = \"UILabel\"; text = \"Show Local Keyboard Toolbar \"; ObjectID = \"m1k-oE-fIO\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Show Local Keyboard Toolbar " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "显示本地软键盘工具栏" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "显示本地软键盘工具栏" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "显示本地软键盘工具栏" } } } @@ -1717,590 +1519,8 @@ } } }, - "NVL-ZX-kMQ.text" : { - "comment" : "Class = \"UILabel\"; text = \"Soft Keyboard Toolbar\"; ObjectID = \"NVL-ZX-kMQ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Soft Keyboard Toolbar" - } - }, - "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", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Slide From Left Edge" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "左边缘滑动" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "左边缘滑动" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "左边缘滑动" - } - } - } - }, - "oBs-zz-ZQv.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; oBs-zz-ZQv.segmentTitles[1] = \"Slide From Right Edge\"; ObjectID = \"oBs-zz-ZQv\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Slide From Right Edge" - } - }, - "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", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Button Down" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "鼠标按下" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "鼠标按下" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "鼠标按下" - } - } - } - }, - "Pdb-Bs-kMJ.text" : { - "comment" : "Class = \"UILabel\"; text = \"Statistics Overlay\"; ObjectID = \"Pdb-Bs-kMJ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Statistics Overlay" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "性能数据叠加" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "性能数据叠加" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "性能数据叠加" - } - } - } - }, - "PHm-2D-t4G.text" : { - "comment" : "Class = \"UILabel\"; text = \"Toggle Local Soft Keyboard\"; ObjectID = \"PHm-2D-t4G\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Toggle Local Soft Keyboard" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "打开软键盘" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "打开软键盘" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "打开软键盘" - } - } - } - }, - "qPQ-U2-aSg.text" : { - "comment" : "Class = \"UILabel\"; text = \"test\"; ObjectID = \"qPQ-U2-aSg\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "test" - } - } - } - }, - "QRV-je-HEZ.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; QRV-je-HEZ.segmentTitles[0] = \"light\"; ObjectID = \"QRV-je-HEZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "light" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "轻微" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "轻微" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "轻微" - } - } - } - }, - "QRV-je-HEZ.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; QRV-je-HEZ.segmentTitles[1] = \"medium\"; ObjectID = \"QRV-je-HEZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "medium" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "中等" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "中等" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "中等" - } - } - } - }, - "QRV-je-HEZ.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; QRV-je-HEZ.segmentTitles[2] = \"heavy\"; ObjectID = \"QRV-je-HEZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "heavy" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "强烈" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "强烈" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "强烈" - } - } - } - }, - "QRV-je-HEZ.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; QRV-je-HEZ.segmentTitles[3] = \"soft\"; ObjectID = \"QRV-je-HEZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "soft" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "柔和" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "柔和" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "柔和" - } - } - } - }, - "QRV-je-HEZ.segmentTitles[4]" : { - "comment" : "Class = \"UISegmentedControl\"; QRV-je-HEZ.segmentTitles[4] = \"rigid\"; ObjectID = \"QRV-je-HEZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "rigid" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "刚性" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "刚性" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "刚性" - } - } - } - }, - "QRV-je-HEZ.segmentTitles[5]" : { - "comment" : "Class = \"UISegmentedControl\"; QRV-je-HEZ.segmentTitles[5] = \"off\"; ObjectID = \"QRV-je-HEZ\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "off" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "关闭" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "关闭" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "关闭" - } - } - } - }, - "S7X-Kt-2jd.text" : { - "comment" : "Class = \"UILabel\"; text = \"Show Local Keyboard Toolbar \"; ObjectID = \"S7X-Kt-2jd\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Local Keyboard Toolbar " - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "软键盘工具栏" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "软键盘工具栏" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "软键盘工具栏" - } - } - } - }, - "sUC-Ur-7eI.title" : { - "comment" : "Class = \"UIBarButtonItem\"; title = \"Exit\"; ObjectID = \"sUC-Ur-7eI\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Exit" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "退出" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "退出" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "退出" - } - } - } - }, - "T0w-xM-ze7.text" : { - "comment" : "Class = \"UILabel\"; text = \"Resolution \"; ObjectID = \"T0w-xM-ze7\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Resolution " - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流分辨率" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流分辨率" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "串流分辨率" - } - } - } - }, - "tE5-Bm-4OB.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; tE5-Bm-4OB.segmentTitles[0] = \"hovering\"; ObjectID = \"tE5-Bm-4OB\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "hovering" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "悬浮" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "悬浮" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "悬浮" - } - } - } - }, - "tE5-Bm-4OB.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; tE5-Bm-4OB.segmentTitles[1] = \"left button\"; ObjectID = \"tE5-Bm-4OB\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "left button" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "左键" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "左键" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "左键" - } - } - } - }, - "tE5-Bm-4OB.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; tE5-Bm-4OB.segmentTitles[2] = \"middle button\"; ObjectID = \"tE5-Bm-4OB\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "middle button" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "中键" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "中键" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "中键" - } - } - } - }, - "tE5-Bm-4OB.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; tE5-Bm-4OB.segmentTitles[3] = \"right button\"; ObjectID = \"tE5-Bm-4OB\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "right button" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "右键" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "右键" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "右键" - } - } - } - }, - "TJx-6E-kgr.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; TJx-6E-kgr.segmentTitles[0] = \"No\"; ObjectID = \"TJx-6E-kgr\";", + "o4O-hO-teB.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; o4O-hO-teB.segmentTitles[0] = \"No\"; ObjectID = \"o4O-hO-teB\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -2308,11 +1528,29 @@ "state" : "new", "value" : "No" } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } } } }, - "TJx-6E-kgr.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; TJx-6E-kgr.segmentTitles[1] = \"Yes\"; ObjectID = \"TJx-6E-kgr\";", + "o4O-hO-teB.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; o4O-hO-teB.segmentTitles[1] = \"Yes\"; ObjectID = \"o4O-hO-teB\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -2320,197 +1558,95 @@ "state" : "new", "value" : "Yes" } - } - } - }, - "tO4-eD-VHF.text" : { - "comment" : "Class = \"UILabel\"; text = \"90° Display Rotation\"; ObjectID = \"tO4-eD-VHF\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "90° Display Rotation" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "90°转屏" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "90°转屏" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "90°转屏" - } - } - } - }, - "Tue-Qh-8zP.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; Tue-Qh-8zP.segmentTitles[0] = \"Stage Manager\"; ObjectID = \"Tue-Qh-8zP\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Stage Manager" - } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "台前调度" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "台前调度" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "台前调度" + "value" : "启用" } } } }, - "Tue-Qh-8zP.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; Tue-Qh-8zP.segmentTitles[1] = \"AirPlay\"; ObjectID = \"Tue-Qh-8zP\";", + "OCT-oL-Dqb.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; OCT-oL-Dqb.segmentTitles[0] = \"Single\"; ObjectID = \"OCT-oL-Dqb\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "AirPlay" + "value" : "Single" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "隔空播放" + "value" : "单手柄" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "隔空播放" + "value" : "单手柄" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "隔空播放" + "value" : "单手柄" } } } }, - "u3w-Se-xzH.text" : { - "comment" : "Class = \"UILabel\"; text = \"Vibration Style\"; ObjectID = \"u3w-Se-xzH\";", + "OCT-oL-Dqb.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; OCT-oL-Dqb.segmentTitles[1] = \"Auto\"; ObjectID = \"OCT-oL-Dqb\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Vibration Style" + "value" : "Auto" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "振动模式" + "value" : "自动" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "振动模式" + "value" : "自动" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "振动模式" + "value" : "自动" } } } }, - "Uca-fD-4AC.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; Uca-fD-4AC.segmentTitles[0] = \"Align with System\"; ObjectID = \"Uca-fD-4AC\";", + "p2k-7u-PDc.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; p2k-7u-PDc.segmentTitles[0] = \"No\"; ObjectID = \"p2k-7u-PDc\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Align with System" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "与系统一致" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "与系统一致" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "与系统一致" - } - } - } - }, - "Uca-fD-4AC.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; Uca-fD-4AC.segmentTitles[1] = \"Reversed\"; ObjectID = \"Uca-fD-4AC\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Reversed" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "反转" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "反转" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "反转" - } - } - } - }, - "UQu-Sg-YuF.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; UQu-Sg-YuF.segmentTitles[0] = \"Off\"; ObjectID = \"UQu-Sg-YuF\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Off" + "value" : "No" } }, "zh-Hans" : { @@ -2533,38 +1669,176 @@ } } }, - "UQu-Sg-YuF.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; UQu-Sg-YuF.segmentTitles[1] = \"Simple\"; ObjectID = \"UQu-Sg-YuF\";", + "p2k-7u-PDc.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; p2k-7u-PDc.segmentTitles[1] = \"Yes\"; ObjectID = \"p2k-7u-PDc\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Simple" + "value" : "Yes" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "简单" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "简单" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "简单" + "value" : "启用" } } } }, - "UQu-Sg-YuF.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; UQu-Sg-YuF.segmentTitles[2] = \"Full\"; ObjectID = \"UQu-Sg-YuF\";", + "P8R-nu-8Ln.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; P8R-nu-8Ln.segmentTitles[0] = \"No\"; ObjectID = \"P8R-nu-8Ln\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + } + } + }, + "P8R-nu-8Ln.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; P8R-nu-8Ln.segmentTitles[1] = \"Yes\"; ObjectID = \"P8R-nu-8Ln\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + } + } + }, + "PCM-t4-Sha.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; PCM-t4-Sha.segmentTitles[0] = \"360p\"; ObjectID = \"PCM-t4-Sha\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "360p" + } + } + } + }, + "PCM-t4-Sha.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; PCM-t4-Sha.segmentTitles[1] = \"720p\"; ObjectID = \"PCM-t4-Sha\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "720p" + } + } + } + }, + "PCM-t4-Sha.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; PCM-t4-Sha.segmentTitles[2] = \"1080p\"; ObjectID = \"PCM-t4-Sha\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "1080p" + } + } + } + }, + "PCM-t4-Sha.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; PCM-t4-Sha.segmentTitles[3] = \"4K\"; ObjectID = \"PCM-t4-Sha\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "4K" + } + } + } + }, + "PCM-t4-Sha.segmentTitles[4]" : { + "comment" : "Class = \"UISegmentedControl\"; PCM-t4-Sha.segmentTitles[4] = \"Safe Area\"; ObjectID = \"PCM-t4-Sha\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Safe Area" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "安全区域" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "安全区域" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "安全区域" + } + } + } + }, + "PCM-t4-Sha.segmentTitles[5]" : { + "comment" : "Class = \"UISegmentedControl\"; PCM-t4-Sha.segmentTitles[5] = \"Full\"; ObjectID = \"PCM-t4-Sha\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -2576,25 +1850,25 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "完整" + "value" : "全屏显示" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "完整" + "value" : "全屏显示" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "完整" + "value" : "全屏显示" } } } }, - "UQu-Sg-YuF.segmentTitles[3]" : { - "comment" : "Class = \"UISegmentedControl\"; UQu-Sg-YuF.segmentTitles[3] = \"Custom\"; ObjectID = \"UQu-Sg-YuF\";", + "PCM-t4-Sha.segmentTitles[6]" : { + "comment" : "Class = \"UISegmentedControl\"; PCM-t4-Sha.segmentTitles[6] = \"Custom\"; ObjectID = \"PCM-t4-Sha\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { @@ -2623,141 +1897,825 @@ } } }, - "v5B-5J-veL.text" : { - "comment" : "Class = \"UILabel\"; text = \"Touch Mode\"; ObjectID = \"v5B-5J-veL\";", - "extractionState" : "extracted_with_value", + "Pew-kf-bSM.text" : { + "comment" : "Class = \"UILabel\"; text = \"Enable YUV 4:4:4 (Beta)\"; ObjectID = \"Pew-kf-bSM\";", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Touch Mode" + "value" : "Enable YUV 4:4:4 (Beta)" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "触控模式" + "value" : "YUV 4:4:4 (测试功能)" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "触控模式" + "value" : "YUV 4:4:4 (测试功能)" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "触控模式" + "value" : "YUV 4:4:4 (测试功能)" } } } }, - "VEc-6n-QcS.text" : { - "comment" : "Class = \"UILabel\"; text = \"Lift Stream View for Local Keyboard \"; ObjectID = \"VEc-6n-QcS\";", + "pQE-vU-Nr7.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; pQE-vU-Nr7.segmentTitles[0] = \"No\"; ObjectID = \"pQE-vU-Nr7\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Lift Stream View for Local Keyboard " - } - } - } - }, - "wOV-Sp-UUE.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; wOV-Sp-UUE.segmentTitles[0] = \"Slide From Left Edge\"; ObjectID = \"wOV-Sp-UUE\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Slide From Left Edge" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "左边缘滑动" + "value" : "关闭" } } } }, - "wOV-Sp-UUE.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; wOV-Sp-UUE.segmentTitles[1] = \"Slide From Right Edge\"; ObjectID = \"wOV-Sp-UUE\";", + "pQE-vU-Nr7.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; pQE-vU-Nr7.segmentTitles[1] = \"Yes\"; ObjectID = \"pQE-vU-Nr7\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Slide From Right Edge" + "value" : "Yes" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "启用" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "启用" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "右边缘滑动" + "value" : "启用" } } } }, - "XtQ-YN-4jb.text" : { - "comment" : "Class = \"UILabel\"; text = \"Touch Move Event Interval\"; ObjectID = \"XtQ-YN-4jb\";", + "R9O-Tw-UD4.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; R9O-Tw-UD4.segmentTitles[0] = \"No\"; ObjectID = \"R9O-Tw-UD4\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Touch Move Event Interval" + "value" : "No" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "称点移动事件间隔" + "value" : "关闭" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "称点移动事件间隔" + "value" : "关闭" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "称点移动事件间隔" + "value" : "关闭" + } + } + } + }, + "R9O-Tw-UD4.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; R9O-Tw-UD4.segmentTitles[1] = \"Yes\"; ObjectID = \"R9O-Tw-UD4\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + } + } + }, + "rdz-eg-2oR.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[0] = \"Off\"; ObjectID = \"rdz-eg-2oR\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Off" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "关闭" + } + } + } + }, + "rdz-eg-2oR.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[1] = \"Simplified\"; ObjectID = \"rdz-eg-2oR\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Simplified" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "精简" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "精简" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "精简" + } + } + } + }, + "rdz-eg-2oR.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[2] = \"Detailed\"; ObjectID = \"rdz-eg-2oR\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Detailed" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整" + } + } + } + }, + "SBv-Wn-LB7.text" : { + "comment" : "Class = \"UILabel\"; text = \"Bitrate: 10 Mbps \"; ObjectID = \"SBv-Wn-LB7\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Bitrate: 10 Mbps " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流码率: 10Mbps" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流码率: 10Mbps" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流码率: 10Mbps" + } + } + } + }, + "stX-s7-H2W.text" : { + "comment" : "Class = \"UILabel\"; text = \"Open Command Tool in Stream View by Sliding from: \"; ObjectID = \"stX-s7-H2W\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Open Command Tool in Stream View by Sliding from: " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开命令工具" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开命令工具" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "串流中从以下屏幕边缘滑动打开命令工具" + } + } + } + }, + "svh-LO-bTr.text" : { + "comment" : "Class = \"UILabel\"; text = \"Reverse Wheel Direction for Physical Mouse \"; ObjectID = \"svh-LO-bTr\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Reverse Wheel Direction for Physical Mouse " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "反转物理鼠标滚轮方向" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "反转物理鼠标滚轮方向" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "反转物理鼠标滚轮方向" + } + } + } + }, + "T6M-nz-TW0.text" : { + "comment" : "Class = \"UILabel\"; text = \"Play Audio on PC \"; ObjectID = \"T6M-nz-TW0\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Play Audio on PC " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "播放主机端声音" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "播放主机端声音" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "播放主机端声音" + } + } + } + }, + "VGn-Oc-mKc.text" : { + "comment" : "Class = \"UILabel\"; text = \"Local Mouse Pointer\"; ObjectID = \"VGn-Oc-mKc\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Local Mouse Pointer" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "本地鼠标指针" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "本地鼠标指针" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "本地鼠标指针" + } + } + } + }, + "VlN-ZW-1gm.text" : { + "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity: Scaled on 0% of Right Screen \"; ObjectID = \"VlN-ZW-1gm\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Touch Pointer Velocity: Scaled on 0% of Right Screen " + } + } + } + }, + "VWB-YB-Ptj.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[0] = \"Stage Manager\"; ObjectID = \"VWB-YB-Ptj\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Stage Manager" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "台前调度" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "台前调度" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "台前调度" + } + } + } + }, + "VWB-YB-Ptj.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[1] = \"AirPlay\"; ObjectID = \"VWB-YB-Ptj\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "AirPlay" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "隔空播放" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "隔空播放" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "隔空播放" + } + } + } + }, + "VWB-YB-Ptj.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[2] = \"Disabled\"; ObjectID = \"VWB-YB-Ptj\";", + "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" : "禁用" + } + } + } + }, + "vwT-tg-RfT.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; vwT-tg-RfT.segmentTitles[0] = \"No\"; ObjectID = \"vwT-tg-RfT\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" + } + } + } + }, + "vwT-tg-RfT.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; vwT-tg-RfT.segmentTitles[1] = \"Yes\"; ObjectID = \"vwT-tg-RfT\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + } + } + }, + "WGf-9d-eAm.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; WGf-9d-eAm.segmentTitles[0] = \"Off\"; ObjectID = \"WGf-9d-eAm\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Off" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + } + } + }, + "WGf-9d-eAm.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; WGf-9d-eAm.segmentTitles[1] = \"Simple\"; ObjectID = \"WGf-9d-eAm\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Simple" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "简单" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "简单" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "简单" + } + } + } + }, + "WGf-9d-eAm.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; WGf-9d-eAm.segmentTitles[2] = \"Full\"; ObjectID = \"WGf-9d-eAm\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Full" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "完整" + } + } + } + }, + "WGf-9d-eAm.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; WGf-9d-eAm.segmentTitles[3] = \"Custom\"; ObjectID = \"WGf-9d-eAm\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Custom" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + } + } + }, + "WGf-9d-eAm.segmentTitles[4]" : { + "comment" : "Class = \"UISegmentedControl\"; WGf-9d-eAm.segmentTitles[4] = \"Custom\"; ObjectID = \"WGf-9d-eAm\";", + "extractionState" : "stale", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Custom" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "自定义" + } + } + } + }, + "WtB-ib-ZDj.text" : { + "comment" : "Class = \"UILabel\"; text = \"Statistics Overlay \"; ObjectID = \"WtB-ib-ZDj\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Statistics Overlay " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "性能数据叠加显示" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "性能数据叠加显示" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "性能数据叠加显示" + } + } + } + }, + "wUg-MH-aae.text" : { + "comment" : "Class = \"UILabel\"; text = \"Lift Stream View for Local Keyboard \"; ObjectID = \"wUg-MH-aae\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Lift Stream View for Local Keyboard " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "唤醒本地软键盘时, 抬升串流视图" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "唤醒本地软键盘时, 抬升串流视图" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "唤醒本地软键盘时, 抬升串流视图" + } + } + } + }, + "x1l-m4-eAM.text" : { + "comment" : "Class = \"UILabel\"; text = \"Frame Pacing Preference \"; ObjectID = \"x1l-m4-eAM\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Frame Pacing Preference " + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "帧步进控制" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "帧步进控制" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "帧步进控制" + } + } + } + }, + "XbO-CV-orB.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; XbO-CV-orB.segmentTitles[0] = \"No\"; ObjectID = \"XbO-CV-orB\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "No" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "关闭" + } + } + } + }, + "XbO-CV-orB.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; XbO-CV-orB.segmentTitles[1] = \"Yes\"; ObjectID = \"XbO-CV-orB\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Yes" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用" } } } }, "yJC-bq-EOU.text" : { "comment" : "Class = \"UILabel\"; text = \"Profile:\"; ObjectID = \"yJC-bq-EOU\";", - "extractionState" : "stale", + "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { @@ -2785,122 +2743,92 @@ } } }, - "Z9M-yq-an2.title" : { - "comment" : "Class = \"UIBarButtonItem\"; title = \"Import\"; ObjectID = \"Z9M-yq-an2\";", + "Z9P-TN-kci.text" : { + "comment" : "Class = \"UILabel\"; text = \"Allow 90° Display Rotation in Steaming\"; ObjectID = \"Z9P-TN-kci\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Import" + "value" : "Allow 90° Display Rotation in Steaming" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "导入" + "value" : "允许90°转屏(App视图、串流时生效)" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "导入" + "value" : "允许90°转屏(App视图、串流时生效)" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "导入" + "value" : "允许90°转屏(App视图、串流时生效)" } } } }, - "zLl-8w-K8J.segmentTitles[0]" : { - "comment" : "Class = \"UISegmentedControl\"; zLl-8w-K8J.segmentTitles[0] = \"Captured\"; ObjectID = \"zLl-8w-K8J\";", + "zDR-Ss-JPc.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; zDR-Ss-JPc.segmentTitles[0] = \"Left Screen Edge\"; ObjectID = \"zDR-Ss-JPc\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Captured" + "value" : "Left Screen Edge" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "窗口捕获" + "value" : "左边缘" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "窗口捕获" + "value" : "左边缘" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "窗口捕获" + "value" : "左边缘" } } } }, - "zLl-8w-K8J.segmentTitles[1]" : { - "comment" : "Class = \"UISegmentedControl\"; zLl-8w-K8J.segmentTitles[1] = \"Hidden\"; ObjectID = \"zLl-8w-K8J\";", + "zDR-Ss-JPc.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; zDR-Ss-JPc.segmentTitles[1] = \"Right Screen Edge\"; ObjectID = \"zDR-Ss-JPc\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Hidden" + "value" : "Right Screen Edge" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "隐藏(绝对坐标)" + "value" : "右边缘" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "隐藏(绝对坐标)" + "value" : "右边缘" } }, "zh-HK" : { "stringUnit" : { "state" : "translated", - "value" : "隐藏(绝对坐标)" - } - } - } - }, - "zLl-8w-K8J.segmentTitles[2]" : { - "comment" : "Class = \"UISegmentedControl\"; zLl-8w-K8J.segmentTitles[2] = \"Visible\"; ObjectID = \"zLl-8w-K8J\";", - "extractionState" : "extracted_with_value", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Visible" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "可见(绝对坐标)" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "可见(绝对坐标)" - } - }, - "zh-HK" : { - "stringUnit" : { - "state" : "translated", - "value" : "可见(绝对坐标)" + "value" : "右边缘" } } }