From 561080568c862e30f62f8bee7b32a53ce3580794 Mon Sep 17 00:00:00 2001 From: TrueZhuangjia Date: Sat, 17 May 2025 22:40:10 +0800 Subject: [PATCH] - modularized settings widgets for iPad - navBar for settings menu --- Limelight/Base.lproj/iPad.storyboard | 1290 ++++++++++------- Limelight/Base.lproj/iPhone.storyboard | 154 +- Limelight/Database/DataManager.h | 5 + Limelight/Localization/Localizable.xcstrings | 69 + .../ViewControllers/MainFrameViewController.m | 18 +- .../ViewControllers/SWRevealViewController.h | 4 + .../ViewControllers/SWRevealViewController.m | 109 +- .../ViewControllers/SettingsViewController.h | 32 + .../ViewControllers/SettingsViewController.m | 88 +- .../StreamFrameViewController.m | 6 +- Limelight/mul.lproj/iPad.xcstrings | 168 ++- Limelight/mul.lproj/iPhone.xcstrings | 8 +- 12 files changed, 1280 insertions(+), 671 deletions(-) diff --git a/Limelight/Base.lproj/iPad.storyboard b/Limelight/Base.lproj/iPad.storyboard index 42be2326..a8a34226 100644 --- a/Limelight/Base.lproj/iPad.storyboard +++ b/Limelight/Base.lproj/iPad.storyboard @@ -62,594 +62,800 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + @@ -1064,13 +1270,13 @@ ICAgICAgICAgICAgICA - + - - + + diff --git a/Limelight/Base.lproj/iPhone.storyboard b/Limelight/Base.lproj/iPhone.storyboard index cc952df2..90c47271 100644 --- a/Limelight/Base.lproj/iPhone.storyboard +++ b/Limelight/Base.lproj/iPhone.storyboard @@ -87,14 +87,14 @@ - + @@ -109,19 +109,19 @@ - + - + @@ -132,26 +132,26 @@ - + - + @@ -163,7 +163,7 @@ - + - + - + - + - + @@ -238,14 +238,14 @@ ICAgICAgICAgICAgIA - + @@ -255,21 +255,21 @@ ICAgICAgICAgICAgIA - + @@ -279,14 +279,14 @@ ICAgICAgICAgICAgIA - + @@ -296,14 +296,14 @@ ICAgICAgICAgICAgIA - + @@ -313,14 +313,14 @@ ICAgICAgICAgICAgIA - + @@ -330,14 +330,14 @@ ICAgICAgICAgICAgIA - + @@ -349,14 +349,14 @@ ICAgICAgICAgICAgIA - + @@ -366,14 +366,14 @@ ICAgICAgICAgICAgIA - + @@ -383,14 +383,14 @@ ICAgICAgICAgICAgIA - + @@ -400,14 +400,14 @@ ICAgICAgICAgICAgIA - + @@ -418,7 +418,7 @@ ICAgICAgICAgICAgIA - + @@ -436,7 +436,7 @@ ICAgICAgICAgICAgIA - + @@ -454,19 +454,19 @@ ICAgICAgICAgICAgIA - + - + @@ -475,28 +475,15 @@ ICAgICAgICAgICAgIA - - + @@ -506,14 +493,14 @@ ICAgICAgICAgICAgIA - + @@ -523,14 +510,14 @@ ICAgICAgICAgICAgIA - + @@ -540,14 +527,14 @@ ICAgICAgICAgICAgIA - + @@ -558,7 +545,7 @@ ICAgICAgICAgICAgIA - + @@ -568,46 +555,33 @@ ICAgICAgICAgICAgIA - - + - + @@ -623,7 +597,6 @@ ICAgICAgICAgICAgIA - @@ -668,7 +641,7 @@ ICAgICAgICAgICAgIA - + @@ -1061,8 +1034,5 @@ ICAgICAgICAgICAgIA - - - diff --git a/Limelight/Database/DataManager.h b/Limelight/Database/DataManager.h index 24478cda..65167b5b 100644 --- a/Limelight/Database/DataManager.h +++ b/Limelight/Database/DataManager.h @@ -16,6 +16,11 @@ @interface DataManager : NSObject +typedef NS_ENUM(NSUInteger, UINavigationBarHeight) { + UINavigationBarHeightIPad = 50, + UINavigationBarHeightIPhone = 44 +}; + typedef NS_ENUM(NSInteger, TouchEventPriorityEnum) { AsyncNativeTouchOff, EqualPriority, diff --git a/Limelight/Localization/Localizable.xcstrings b/Limelight/Localization/Localizable.xcstrings index 712f7235..b8f4311c 100644 --- a/Limelight/Localization/Localizable.xcstrings +++ b/Limelight/Localization/Localizable.xcstrings @@ -260,6 +260,29 @@ } } }, + "Back" : { + "extractionState" : "manual", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "返回" + } + } + } + }, "Ball: assumed touch point. Cross: indicator location" : { "extractionState" : "manual", "localizations" : { @@ -772,6 +795,29 @@ } } }, + "Disconnect" : { + "extractionState" : "manual", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "断开" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "断开" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "断开" + } + } + } + }, "Done" : { "extractionState" : "manual", "localizations" : { @@ -2654,6 +2700,29 @@ } } }, + "Settings" : { + "extractionState" : "manual", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "设置" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "设置" + } + } + } + }, "Shape (r - round, s - square)" : { "extractionState" : "manual", "localizations" : { diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index 91b63ae6..b56987f1 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -961,12 +961,16 @@ static NSMutableSet* hostList; } } - -- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { - // If we moved back to the center position, we should save the settings +- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { SettingsViewController* settingsViewController = (SettingsViewController*)[revealController rearViewController]; settingsViewController.mainFrameViewController = self; // enable / disable widgets acoordingly: in streamview, disable, outside of streamview, enable. + if (@available(iOS 16.0, *)) { + revealController.disconnectButton.hidden = !self.settingsExpandedInStreamView; + } else { + revealController.disconnectButton.enabled = self.settingsExpandedInStreamView; + // Fallback on earlier versions + } [settingsViewController.resolutionSelector setEnabled:!self.settingsExpandedInStreamView]; [settingsViewController.framerateSelector setEnabled:!self.settingsExpandedInStreamView]; [settingsViewController widget:settingsViewController.bitrateSlider setEnabled:!self.settingsExpandedInStreamView]; @@ -978,8 +982,14 @@ static NSMutableSet* hostList; [settingsViewController.framePacingSelector setEnabled:!self.settingsExpandedInStreamView]; [settingsViewController.btMouseSelector setEnabled:!self.settingsExpandedInStreamView]; [settingsViewController.externalDisplayModeSelector setEnabled:!self.settingsExpandedInStreamView]; - [settingsViewController.backToStreamingButton setEnabled:self.settingsExpandedInStreamView]; + [settingsViewController.backToStreamingButton setEnabled:self.settingsExpandedInStreamView]; // will be deprecated soon // [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; if (position == FrontViewPositionLeft) { [settingsViewController saveSettings]; diff --git a/Limelight/ViewControllers/SWRevealViewController.h b/Limelight/ViewControllers/SWRevealViewController.h index 7ced5014..00087dad 100755 --- a/Limelight/ViewControllers/SWRevealViewController.h +++ b/Limelight/ViewControllers/SWRevealViewController.h @@ -183,6 +183,8 @@ typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType) @interface SWRevealViewController : UIViewController +@property (nonatomic, strong) UINavigationBar *dockedNavBar; + - (void)setPrimaryViewController:(UIViewController*)viewController; /* Basic API */ @@ -239,6 +241,8 @@ typedef NS_ENUM(NSInteger, SWRevealToggleAnimationType) /* The following properties are provided for further customization, they are set to default values on initialization, you do not generally have to set them */ +@property (strong, nonatomic) UIBarButtonItem *disconnectButton; + // Defines how much of the rear or right view is shown, default is 260. // Negative values indicate that the reveal width should be computed by substracting the full front view width, // so the revealed frontView width is kept constant when bounds change as opposed to the rear or right width. diff --git a/Limelight/ViewControllers/SWRevealViewController.m b/Limelight/ViewControllers/SWRevealViewController.m index 72bd0696..0e00c275 100755 --- a/Limelight/ViewControllers/SWRevealViewController.m +++ b/Limelight/ViewControllers/SWRevealViewController.m @@ -30,6 +30,7 @@ #import #import "SWRevealViewController.h" +#import "LocalizationHelper.h" #import "DataManager.h" @@ -59,6 +60,7 @@ static CGFloat statusBarAdjustment( UIView* view ) } @property (nonatomic, readonly) UIView *rearView; +@property (nonatomic, strong) UIView *rearNavView; @property (nonatomic, readonly) UIView *rightView; @property (nonatomic, readonly) UIView *frontView; @property (nonatomic, assign) BOOL disableLayout; @@ -73,7 +75,9 @@ static CGFloat statusBarAdjustment( UIView* view ) @end -@implementation SWRevealView +@implementation SWRevealView{ + +} static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1, CGFloat max1) @@ -99,7 +103,10 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1 [self reloadShadow]; [self addSubview:_frontView]; + + [self setupRearNavView]; } + return self; } @@ -128,13 +135,39 @@ static CGFloat scaledValue( CGFloat v1, CGFloat min2, CGFloat max2, CGFloat min1 } +- (void)setupRearNavView { + // 初始化 rearNavView + _rearNavView = [[UIView alloc] init]; + _rearNavView.translatesAutoresizingMaskIntoConstraints = NO; + _rearNavView.backgroundColor = [UIColor lightGrayColor]; // 设置背景色以便查看 + + // NSLog(@"_c.rearViewRevealWidth: %f", _c.rearViewRevealWidth); + // _rearNavView.frame = CGRectMake(0, 0, _c.rearViewRevealWidth, 100); + // 添加到主视图 + + // 设置约束 - 这里只是一个示例,你可以根据需要调整 + + [self insertSubview:_rearNavView belowSubview:_frontView]; + + CGFloat navBarHeight = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad; + + [NSLayoutConstraint activateConstraints:@[ + [_rearNavView.topAnchor constraintEqualToAnchor:self.topAnchor], + [_rearNavView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor], + [_rearNavView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor], + [_rearNavView.heightAnchor constraintEqualToConstant:navBarHeight] + // reserve height for navigation bar + ]]; + // [self setupNavigationBar]; +} + - (void)prepareRearViewForPosition:(FrontViewPosition)newPosition { if ( _rearView == nil ) { _rearView = [[UIView alloc] initWithFrame:self.bounds]; _rearView.autoresizingMask = /*UIViewAutoresizingFlexibleWidth|*/UIViewAutoresizingFlexibleHeight; - [self insertSubview:_rearView belowSubview:_frontView]; + [self insertSubview:_rearView belowSubview:_rearNavView]; } CGFloat xLocation = [self frontLocationForPosition:_c.frontViewPosition]; @@ -633,7 +666,8 @@ const int FrontViewPositionNone = 0xff; _rearViewPosition = FrontViewPositionLeft; _rightViewPosition = FrontViewPositionLeft; _rearViewRevealWidth = 492.0f; - _rearViewRevealOverdraw = 60.0f; + // _rearViewRevealOverdraw = 60.0f; + _rearViewRevealOverdraw = 0.0f; _rearViewRevealDisplacement = 40.0f; _rightViewRevealWidth = 492.0f; _rightViewRevealOverdraw = 60.0f; @@ -701,6 +735,8 @@ const int FrontViewPositionNone = 0xff; // create a custom content view for the controller _contentView = [[SWRevealView alloc] initWithFrame:frame controller:self]; + [self setupNavigationBar]; + // set the content view to resize along with its superview [_contentView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight]; @@ -754,6 +790,9 @@ const int FrontViewPositionNone = 0xff; else return [self getCurrentOrientation]; // 90 Degree rotation not allowed in streaming or app view } +- (void)viewDidLayoutSubviews{ + // [self setupNavigationBarConstraints]; +} - (void)viewDidLoad{ @@ -786,6 +825,70 @@ const int FrontViewPositionNone = 0xff; #pragma mark - Public methods and property accessors +- (void)setupNavigationBar { + // 创建导航栏 + if (_dockedNavBar == nil) _dockedNavBar = [[UINavigationBar alloc] init]; + _dockedNavBar.translatesAutoresizingMaskIntoConstraints = NO; + _dockedNavBar.userInteractionEnabled = YES; + + // 创建导航项 + UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Settings"]]; + + // Back Button + + UIButton *customBackButton = [UIButton buttonWithType:UIButtonTypeSystem]; + if (@available(iOS 13.0, *)) { + [customBackButton setImage:[UIImage systemImageNamed:@"chevron.left"] forState:UIControlStateNormal]; + } else { + // Fallback on earlier versions + } + [customBackButton setTitle:[LocalizationHelper localizedStringForKey:@"Back"] forState:UIControlStateNormal]; + customBackButton.titleLabel.font = [UIFont systemFontOfSize:19 weight:UIFontWeightRegular]; + [customBackButton addTarget:self action:@selector(foldRearView) forControlEvents:UIControlEventTouchUpInside]; + //customBackButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 8); // 增加点击区域 + // customBackButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, -5); + UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customBackButton]; + + /* + UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Back"] + style:UIBarButtonItemStylePlain + target:self + action:@selector(foldRearView)]; + */ + + navItem.leftBarButtonItem = backButtonItem; + + _disconnectButton = [[UIBarButtonItem alloc] initWithTitle:[LocalizationHelper localizedStringForKey:@"Disconnect"] + style:UIBarButtonItemStylePlain + target:self + action:@selector(disconnectRemoteSession)]; + navItem.rightBarButtonItem = _disconnectButton; + + [_dockedNavBar setItems:@[navItem]]; + _dockedNavBar.barTintColor = [UIColor darkGrayColor]; + _dockedNavBar.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor]}; + + [_contentView.rearNavView addSubview:_dockedNavBar]; + + // 设置导航栏约束 + [NSLayoutConstraint activateConstraints:@[ + [_dockedNavBar.topAnchor constraintEqualToAnchor:_contentView.rearNavView.topAnchor], + [_dockedNavBar.bottomAnchor constraintEqualToAnchor:_contentView.rearNavView.bottomAnchor], + [_dockedNavBar.leadingAnchor constraintEqualToAnchor:_contentView.rearNavView.leadingAnchor], + [_dockedNavBar.widthAnchor constraintEqualToConstant:_rearViewRevealWidth], + ]]; + +} + +- (void)foldRearView{ + [self revealToggleAnimated:YES]; +} + +- (void)disconnectRemoteSession{ + [[NSNotificationCenter defaultCenter] postNotificationName:@"SessionDisconnectedBySettingsMenuNotification" object:self]; + [self foldRearView]; +} + - (void)setFrontViewController:(UIViewController *)frontViewController { [self setFrontViewController:frontViewController animated:NO]; diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h index 17b0d899..82c136cd 100644 --- a/Limelight/ViewControllers/SettingsViewController.h +++ b/Limelight/ViewControllers/SettingsViewController.h @@ -16,6 +16,38 @@ #import "CustomEdgeSlideGestureRecognizer.h" @interface SettingsViewController : UIViewController +@property (strong, nonatomic) IBOutlet UINavigationBar *navigationBar; +@property (strong, nonatomic) IBOutlet UIStackView *resolutionStack; +@property (strong, nonatomic) IBOutlet UIStackView *fpsStack; +@property (strong, nonatomic) IBOutlet UIStackView *bitrateStack; +@property (strong, nonatomic) IBOutlet UIStackView *touchModeStack; +@property (strong, nonatomic) IBOutlet UIStackView *asyncTouchStack; +@property (strong, nonatomic) IBOutlet UIStackView *pointerVelocityDividerStack; +@property (strong, nonatomic) IBOutlet UIStackView *pointerVelocityFactorStack; +@property (strong, nonatomic) IBOutlet UIStackView *touchMoveEventIntervalStack; +@property (strong, nonatomic) IBOutlet UIStackView *mousePointerVelocityStack; +@property (strong, nonatomic) IBOutlet UIStackView *onScreenWidgetStack; +@property (strong, nonatomic) IBOutlet UIStackView *keyboardToggleFingerNumStack; +@property (strong, nonatomic) IBOutlet UIStackView *liftStreamViewForKeyboardStack; +@property (strong, nonatomic) IBOutlet UIStackView *showKeyboardToolbarStack; +@property (strong, nonatomic) IBOutlet UIStackView *slideToSettingsScreenEdgeStack; +@property (strong, nonatomic) IBOutlet UIStackView *slideToCmdToolScreenEdgeStack; +@property (strong, nonatomic) IBOutlet UIStackView *slideToSettingsDistanceStack; +@property (strong, nonatomic) IBOutlet UIStackView *optimizeSettingsStack; +@property (strong, nonatomic) IBOutlet UIStackView *multiControllerStack; +@property (strong, nonatomic) IBOutlet UIStackView *swapAbaxyStack; +@property (strong, nonatomic) IBOutlet UIStackView *audioOnPcStack; +@property (strong, nonatomic) IBOutlet UIStackView *codecStack; +@property (strong, nonatomic) IBOutlet UIStackView *yuv444Stack; +@property (strong, nonatomic) IBOutlet UIStackView *HdrStack; +@property (strong, nonatomic) IBOutlet UIStackView *framepacingStack; +@property (strong, nonatomic) IBOutlet UIStackView *reverseMouseWheelDirectionStack; +@property (strong, nonatomic) IBOutlet UIStackView *citrixX1MouseStack; +@property (strong, nonatomic) IBOutlet UIStackView *statsOverlayStack; +@property (strong, nonatomic) IBOutlet UIStackView *unlockDisplayOrientationStack; +@property (strong, nonatomic) IBOutlet UIStackView *externalDisplayModeStack; +@property (strong, nonatomic) IBOutlet UIStackView *localMousePointerModeStack; + @property (strong, nonatomic) IBOutlet UILabel *bitrateLabel; @property (strong, nonatomic) IBOutlet UISlider *bitrateSlider; @property (strong, nonatomic) IBOutlet UISegmentedControl *framerateSelector; diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m index 59e4f222..210367e9 100644 --- a/Limelight/ViewControllers/SettingsViewController.m +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -25,6 +25,7 @@ bool justEnteredSettingsViewDoNotOpenOscLayoutTool; uint16_t oscLayoutFingers; CustomEdgeSlideGestureRecognizer *slideToCloseSettingsViewRecognizer; + UIStackView *parentStack; } @dynamic overrideUserInterfaceStyle; @@ -159,6 +160,7 @@ CGSize resolutionTable[RESOLUTION_TABLE_SIZE]; // 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 @@ -177,7 +179,7 @@ CGSize resolutionTable[RESOLUTION_TABLE_SIZE]; // 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); + [self isIPhone] ? highestViewY + 20 : parentStack.frame.size.height + [self getStandardNavBarHeight] + 20); } // Adjust the subviews for the safe area on the iPhone X. @@ -300,23 +302,13 @@ BOOL isCustomResolution(CGSize res) { [[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; - } -} - +//deprecated - (IBAction)exitButtonTapped:(id)sender { [self->_mainFrameViewController simulateSettingsButtonPress]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"SessionDisconnectedBySettingsViewNotification" object:self]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"SessionDisconnectedBySettingsMenuNotification" object:self]; } +//deprecated - (IBAction)backToStreamingButtonTapped:(id)sender { [self simulateSettingsButtonPress]; } @@ -340,9 +332,77 @@ BOOL isCustomResolution(CGSize res) { [self simulateSettingsButtonPress]; } +- (BOOL)isIPhone { + return [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone; +} + +- (CGFloat)getStandardNavBarHeight{ + return [self isIPhone] ? UINavigationBarHeightIPhone : UINavigationBarHeightIPad; +} + +- (void)layoutWidgetes { + + // [self.view addSubview:self.navigationBar]; + + self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic; + + // 可选:确保 scrollView 开启垂直滚动 + self.scrollView.alwaysBounceVertical = YES; + + parentStack = [[UIStackView alloc] init]; + parentStack.axis = UILayoutConstraintAxisVertical; + parentStack.spacing = 13; + parentStack.translatesAutoresizingMaskIntoConstraints = NO; + [self.scrollView addSubview:parentStack]; + [NSLayoutConstraint activateConstraints:@[ + [parentStack.topAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.topAnchor constant: [self getStandardNavBarHeight] + 20], + [parentStack.bottomAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.bottomAnchor constant:-20], + [parentStack.leadingAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.leadingAnchor constant: 14], + [parentStack.trailingAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.trailingAnchor constant: -15], + [parentStack.widthAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.widthAnchor] + ]]; + + [parentStack addArrangedSubview:self.resolutionStack]; + // self.resolutionStack.hidden = YES; + [parentStack addArrangedSubview:self.fpsStack]; + // self.fpsStack.hidden = YES; + [parentStack addArrangedSubview:self.bitrateStack]; + // self.bitrateStack.hidden = YES; + [parentStack addArrangedSubview:self.touchModeStack]; + [parentStack addArrangedSubview:self.asyncTouchStack]; + [parentStack addArrangedSubview:self.pointerVelocityDividerStack]; + [parentStack addArrangedSubview:self.pointerVelocityFactorStack]; + [parentStack addArrangedSubview:self.touchMoveEventIntervalStack]; + [parentStack addArrangedSubview:self.mousePointerVelocityStack]; + [parentStack addArrangedSubview:self.onScreenWidgetStack]; + [parentStack addArrangedSubview:self.keyboardToggleFingerNumStack]; + [parentStack addArrangedSubview:self.liftStreamViewForKeyboardStack]; + [parentStack addArrangedSubview:self.showKeyboardToolbarStack]; + [parentStack addArrangedSubview:self.slideToSettingsScreenEdgeStack]; + [parentStack addArrangedSubview:self.slideToCmdToolScreenEdgeStack]; + [parentStack addArrangedSubview:self.slideToSettingsDistanceStack]; + [parentStack addArrangedSubview:self.optimizeSettingsStack]; + [parentStack addArrangedSubview:self.multiControllerStack]; + [parentStack addArrangedSubview:self.swapAbaxyStack]; + [parentStack addArrangedSubview:self.audioOnPcStack]; + [parentStack addArrangedSubview:self.codecStack]; + [parentStack addArrangedSubview:self.yuv444Stack]; + [parentStack addArrangedSubview:self.HdrStack]; + [parentStack addArrangedSubview:self.framepacingStack]; + [parentStack addArrangedSubview:self.reverseMouseWheelDirectionStack]; + [parentStack addArrangedSubview:self.citrixX1MouseStack]; + [parentStack addArrangedSubview:self.statsOverlayStack]; + [parentStack addArrangedSubview:self.unlockDisplayOrientationStack]; + [parentStack addArrangedSubview:self.externalDisplayModeStack]; + [parentStack addArrangedSubview:self.localMousePointerModeStack]; +} + + - (void)viewDidLoad { //[self pushDownExistingWidgets]; //[self addExitButtonOnTop]; + BOOL isIPad = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad); + if(isIPad) [self layoutWidgetes]; // layout for ipad tmply self->slideToCloseSettingsViewRecognizer = [[CustomEdgeSlideGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)]; slideToCloseSettingsViewRecognizer.edges = UIRectEdgeLeft; diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m index 8e7a7b08..5c993b4c 100644 --- a/Limelight/ViewControllers/StreamFrameViewController.m +++ b/Limelight/ViewControllers/StreamFrameViewController.m @@ -250,8 +250,8 @@ object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(sessionDisconnectedBySettingView) //quit session when exit button is press in setting view during streaming - name:@"SessionDisconnectedBySettingsViewNotification" + selector:@selector(disconnectRemoteSession) //quit session when exit button is press in setting view during streaming + name:@"SessionDisconnectedBySettingsMenuNotification" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -741,7 +741,7 @@ [self expandSettingsView]; // expand settings view in other cases; } -- (void)sessionDisconnectedBySettingView { +- (void)disconnectRemoteSession { Log(LOG_I, @"Settings view disconnect the session in stream view"); self.mainFrameViewcontroller.settingsExpandedInStreamView = false; // reset this flag to false [self returnToMainFrame]; diff --git a/Limelight/mul.lproj/iPad.xcstrings b/Limelight/mul.lproj/iPad.xcstrings index 6b5f12ee..bef41823 100644 --- a/Limelight/mul.lproj/iPad.xcstrings +++ b/Limelight/mul.lproj/iPad.xcstrings @@ -691,6 +691,126 @@ } } }, + "bhC-da-VGd.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[0] = \"Touchpad\"; ObjectID = \"bhC-da-VGd\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Touchpad" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "触控板" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "触控板" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "触控板" + } + } + } + }, + "bhC-da-VGd.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[1] = \"Native Touch\"; ObjectID = \"bhC-da-VGd\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Native Touch" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "多点触控" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "多点触控" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "多点触控" + } + } + } + }, + "bhC-da-VGd.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[2] = \"Native Only\"; ObjectID = \"bhC-da-VGd\";", + "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" : "仅多点触控" + } + } + } + }, + "bhC-da-VGd.segmentTitles[3]" : { + "comment" : "Class = \"UISegmentedControl\"; bhC-da-VGd.segmentTitles[3] = \"Absolute Touch\"; ObjectID = \"bhC-da-VGd\";", + "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", @@ -1231,9 +1351,21 @@ } } }, + "dqh-nl-heL.title" : { + "comment" : "Class = \"UINavigationItem\"; title = \"Title\"; ObjectID = \"dqh-nl-heL\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Title" + } + } + } + }, "e4G-id-vjI.segmentTitles[0]" : { "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[0] = \"Touchpad\"; ObjectID = \"e4G-id-vjI\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -1263,7 +1395,7 @@ }, "e4G-id-vjI.segmentTitles[1]" : { "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[1] = \"Native Touch\"; ObjectID = \"e4G-id-vjI\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -1293,7 +1425,7 @@ }, "e4G-id-vjI.segmentTitles[2]" : { "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[2] = \"Native Only\"; ObjectID = \"e4G-id-vjI\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -1323,7 +1455,7 @@ }, "e4G-id-vjI.segmentTitles[3]" : { "comment" : "Class = \"UISegmentedControl\"; e4G-id-vjI.segmentTitles[3] = \"Absolute Touch\"; ObjectID = \"e4G-id-vjI\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -1719,7 +1851,7 @@ }, "h5g-U1-Z2J.text" : { "comment" : "Class = \"UILabel\"; text = \"Touch Mode \"; ObjectID = \"h5g-U1-Z2J\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -2467,6 +2599,24 @@ } } }, + "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" : "translated", + "value" : "触控模式" + } + } + } + }, "nCO-OT-dV1.segmentTitles[0]" : { "comment" : "Class = \"UISegmentedControl\"; nCO-OT-dV1.segmentTitles[0] = \"No\"; ObjectID = \"nCO-OT-dV1\";", "extractionState" : "stale", @@ -3351,7 +3501,7 @@ }, "uSS-ev-IFe.configuration.title" : { "comment" : "Class = \"UIButton\"; configuration.title = \"Back to Streaming\"; ObjectID = \"uSS-ev-IFe\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -3381,7 +3531,7 @@ }, "uSS-ev-IFe.normalTitle" : { "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"uSS-ev-IFe\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -3591,7 +3741,7 @@ }, "yq8-Hq-UWQ.configuration.title" : { "comment" : "Class = \"UIButton\"; configuration.title = \"Exit\"; ObjectID = \"yq8-Hq-UWQ\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -3621,7 +3771,7 @@ }, "yq8-Hq-UWQ.normalTitle" : { "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"yq8-Hq-UWQ\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { diff --git a/Limelight/mul.lproj/iPhone.xcstrings b/Limelight/mul.lproj/iPhone.xcstrings index c6268720..8dc409ed 100644 --- a/Limelight/mul.lproj/iPhone.xcstrings +++ b/Limelight/mul.lproj/iPhone.xcstrings @@ -843,7 +843,7 @@ }, "CMK-cS-h9b.configuration.title" : { "comment" : "Class = \"UIButton\"; configuration.title = \"Exit\"; ObjectID = \"CMK-cS-h9b\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -873,7 +873,7 @@ }, "CMK-cS-h9b.normalTitle" : { "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"CMK-cS-h9b\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -1155,7 +1155,7 @@ }, "FqF-bM-afQ.configuration.title" : { "comment" : "Class = \"UIButton\"; configuration.title = \"Back to Streaming\"; ObjectID = \"FqF-bM-afQ\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -1185,7 +1185,7 @@ }, "FqF-bM-afQ.normalTitle" : { "comment" : "Class = \"UIButton\"; normalTitle = \"Button\"; ObjectID = \"FqF-bM-afQ\";", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : {