From f2705d33b58f22cb24c6e3acb070dcdb19a675b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20Guti=C3=A9rrez=20G=C3=B3mez?= Date: Sat, 3 Jun 2023 23:52:57 +0200 Subject: [PATCH] Add support for changing the sensitivity of relative mouse mode. This commit introduces support on the iOS and tvOS apps for changing the mouse sensitivity within relative mouse ("Touchpad") mode. It does this by multiplying the delta movement sent to the host by a fixed factor which can be configured by the user in Settings. On iOS, the setting provided is a slider with non-lineal behavior. While it has a multiplier range of 0.0 to 6.0, the default value of 1.0 stays in the middle; thus, the left side comprehends a range of [0.0, 1.0) and the right side uses a different range of [1.0, 6.0]. The option of having 0x sensibility is explicitely provided in order to unlock usecases in which locking the mouse cursor in a fixed place is desired. In addition to that, the slider has a soft detent on the default 1.0x setting, which allows to quickly reset the setting to a default state. This is accompanied by haptic feedback for better UX. On tvOS, due to the lack of a slider control support in Settings.bundle, a multi-input is provided instead that roughly covers the iOS's slider range. A Core Data migration and accompanying glue code is provided for persisting the setting change. --- Limelight/Database/DataManager.h | 3 +- Limelight/Database/DataManager.m | 2 + Limelight/Database/TemporarySettings.h | 1 + Limelight/Database/TemporarySettings.m | 2 + Limelight/Input/RelativeTouchHandler.h | 2 +- Limelight/Input/RelativeTouchHandler.m | 8 +- Limelight/Input/StreamView.m | 4 +- .../Limelight.xcdatamodeld/.xccurrentversion | 2 +- .../Moonlight v1.10.xcdatamodel/contents | 48 ++++++++++ Limelight/Stream/StreamConfiguration.h | 1 + .../ViewControllers/MainFrameViewController.m | 2 + .../ViewControllers/SettingsViewController.h | 11 +++ .../ViewControllers/SettingsViewController.m | 96 ++++++++++++++++++- Moonlight TV/Settings.bundle/Root.plist | 44 +++++++++ Moonlight.xcodeproj/project.pbxproj | 4 +- iPad.storyboard | 68 +++++++------ iPhone.storyboard | 53 ++++++---- 17 files changed, 295 insertions(+), 56 deletions(-) create mode 100644 Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents diff --git a/Limelight/Database/DataManager.h b/Limelight/Database/DataManager.h index d7d4d5ec5..2cba40804 100644 --- a/Limelight/Database/DataManager.h +++ b/Limelight/Database/DataManager.h @@ -17,8 +17,9 @@ framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width - audioConfig:(NSInteger)audioConfig + audioConfig:(NSInteger)audioConfig onscreenControls:(NSInteger)onscreenControls + relativeTouchSensitivity:(float)relativeTouchSensitivity optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController swapABXYButtons:(BOOL)swapABXYButtons diff --git a/Limelight/Database/DataManager.m b/Limelight/Database/DataManager.m index 1c3144a7b..50c000237 100644 --- a/Limelight/Database/DataManager.m +++ b/Limelight/Database/DataManager.m @@ -58,6 +58,7 @@ - (void) saveSettingsWithBitrate:(NSInteger)bitrate width:(NSInteger)width audioConfig:(NSInteger)audioConfig onscreenControls:(NSInteger)onscreenControls + relativeTouchSensitivity:(float)relativeTouchSensitivity optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController swapABXYButtons:(BOOL)swapABXYButtons @@ -87,6 +88,7 @@ - (void) saveSettingsWithBitrate:(NSInteger)bitrate settingsToSave.btMouseSupport = btMouseSupport; settingsToSave.absoluteTouchMode = absoluteTouchMode; settingsToSave.statsOverlay = statsOverlay; + settingsToSave.relativeTouchSensitivity = [NSNumber numberWithFloat:relativeTouchSensitivity]; [self saveData]; }]; diff --git a/Limelight/Database/TemporarySettings.h b/Limelight/Database/TemporarySettings.h index 196c6892e..f85123449 100644 --- a/Limelight/Database/TemporarySettings.h +++ b/Limelight/Database/TemporarySettings.h @@ -18,6 +18,7 @@ @property (nonatomic, retain) NSNumber * width; @property (nonatomic, retain) NSNumber * audioConfig; @property (nonatomic, retain) NSNumber * onscreenControls; +@property (nonatomic, retain) NSNumber * relativeTouchSensitivity; @property (nonatomic, retain) NSString * uniqueId; @property (nonatomic) BOOL useHevc; @property (nonatomic) BOOL useFramePacing; diff --git a/Limelight/Database/TemporarySettings.m b/Limelight/Database/TemporarySettings.m index 16aaa776e..fee307feb 100644 --- a/Limelight/Database/TemporarySettings.m +++ b/Limelight/Database/TemporarySettings.m @@ -45,6 +45,7 @@ - (id) initFromSettings:(Settings*)settings { self.swapABXYButtons = [[NSUserDefaults standardUserDefaults] boolForKey:@"swapABXYButtons"]; self.btMouseSupport = [[NSUserDefaults standardUserDefaults] boolForKey:@"btMouseSupport"]; self.statsOverlay = [[NSUserDefaults standardUserDefaults] boolForKey:@"statsOverlay"]; + self.relativeTouchSensitivity = [NSNumber numberWithFloat:[[NSUserDefaults standardUserDefaults] floatForKey:@"relativeTouchSensitivity"]]; NSInteger _screenSize = [[NSUserDefaults standardUserDefaults] integerForKey:@"streamResolution"]; switch (_screenSize) { @@ -85,6 +86,7 @@ - (id) initFromSettings:(Settings*)settings { self.btMouseSupport = settings.btMouseSupport; self.absoluteTouchMode = settings.absoluteTouchMode; self.statsOverlay = settings.statsOverlay; + self.relativeTouchSensitivity = settings.relativeTouchSensitivity; #endif self.uniqueId = settings.uniqueId; diff --git a/Limelight/Input/RelativeTouchHandler.h b/Limelight/Input/RelativeTouchHandler.h index 2f8d9dbda..d065eec50 100644 --- a/Limelight/Input/RelativeTouchHandler.h +++ b/Limelight/Input/RelativeTouchHandler.h @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @interface RelativeTouchHandler : UIResponder --(id)initWithView:(StreamView*)view; +-(id)initWithView:(StreamView*)view sensitivityMultiplier:(float)sensitivityMultiplier; @end diff --git a/Limelight/Input/RelativeTouchHandler.m b/Limelight/Input/RelativeTouchHandler.m index 64d7da465..6f301f2ad 100644 --- a/Limelight/Input/RelativeTouchHandler.m +++ b/Limelight/Input/RelativeTouchHandler.m @@ -26,11 +26,13 @@ @implementation RelativeTouchHandler { #endif UIView* view; + float sensitivityMultiplier; } -- (id)initWithView:(StreamView*)view { +- (id)initWithView:(StreamView*)view sensitivityMultiplier:(float)sensitivityMultiplier{ self = [self init]; self->view = view; + self->sensitivityMultiplier = sensitivityMultiplier; #if TARGET_OS_TV remotePressRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(remoteButtonPressed:)]; @@ -88,8 +90,8 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { if (touchLocation.x != currentLocation.x || touchLocation.y != currentLocation.y) { - int deltaX = (currentLocation.x - touchLocation.x) * (REFERENCE_WIDTH / view.bounds.size.width); - int deltaY = (currentLocation.y - touchLocation.y) * (REFERENCE_HEIGHT / view.bounds.size.height); + int deltaX = (currentLocation.x - touchLocation.x) * (REFERENCE_WIDTH / view.bounds.size.width) * sensitivityMultiplier; + int deltaY = (currentLocation.y - touchLocation.y) * (REFERENCE_HEIGHT / view.bounds.size.height) * sensitivityMultiplier; if (deltaX != 0 || deltaY != 0) { LiSendMouseMoveEvent(deltaX, deltaY); diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m index a399858a6..e1e4afb11 100644 --- a/Limelight/Input/StreamView.m +++ b/Limelight/Input/StreamView.m @@ -62,14 +62,14 @@ - (void) setupStreamView:(ControllerSupport*)controllerSupport #if TARGET_OS_TV // tvOS requires RelativeTouchHandler to manage Apple Remote input - self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self]; + self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self sensitivityMultiplier:streamConfig.relativeTouchSensitivity]; #else // iOS uses RelativeTouchHandler or AbsoluteTouchHandler depending on user preference if (settings.absoluteTouchMode) { self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self]; } else { - self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self]; + self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self sensitivityMultiplier:streamConfig.relativeTouchSensitivity]; } onScreenControls = [[OnScreenControls alloc] initWithView:self controllerSup:controllerSupport streamConfig:streamConfig]; diff --git a/Limelight/Limelight.xcdatamodeld/.xccurrentversion b/Limelight/Limelight.xcdatamodeld/.xccurrentversion index 4e7ed17b8..b202eb9f3 100644 --- a/Limelight/Limelight.xcdatamodeld/.xccurrentversion +++ b/Limelight/Limelight.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - Moonlight v1.9.xcdatamodel + Moonlight v1.10.xcdatamodel diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents new file mode 100644 index 000000000..707cf3adf --- /dev/null +++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Limelight/Stream/StreamConfiguration.h b/Limelight/Stream/StreamConfiguration.h index 4cfa3942b..460d86aa7 100644 --- a/Limelight/Stream/StreamConfiguration.h +++ b/Limelight/Stream/StreamConfiguration.h @@ -28,6 +28,7 @@ @property int audioConfiguration; @property BOOL enableHdr; @property BOOL multiController; +@property float relativeTouchSensitivity; @property BOOL allowHevc; @property BOOL useFramePacing; @property NSData* serverCert; diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index fe105e6fb..d1776c973 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -623,6 +623,8 @@ - (void) prepareToStreamApp:(TemporaryApp *)app { _streamConfig.height = [streamSettings.height intValue]; _streamConfig.width = [streamSettings.width intValue]; + + _streamConfig.relativeTouchSensitivity = [streamSettings.relativeTouchSensitivity floatValue]; #if TARGET_OS_TV // Don't allow streaming 4K on the Apple TV HD struct utsname systemInfo; diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h index af3caff04..408ed79b0 100644 --- a/Limelight/ViewControllers/SettingsViewController.h +++ b/Limelight/ViewControllers/SettingsViewController.h @@ -16,6 +16,8 @@ @property (strong, nonatomic) IBOutlet UISegmentedControl *resolutionSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *touchModeSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *onscreenControlSelector; +@property (strong, nonatomic) IBOutlet UILabel *touchpadSensitivityLabel; +@property (strong, nonatomic) IBOutlet UISlider *touchpadSensitivitySlider; @property (strong, nonatomic) IBOutlet UISegmentedControl *optimizeSettingsSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *multiControllerSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *swapABXYButtonsSelector; @@ -26,6 +28,7 @@ @property (strong, nonatomic) IBOutlet UISegmentedControl *btMouseSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *statsOverlaySelector; @property (strong, nonatomic) IBOutlet UIScrollView *scrollView; +@property UIImpactFeedbackGenerator *impactFeedbackGenerator; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability" @@ -38,3 +41,11 @@ - (void) saveSettings; @end + +/// Performs linear interpolation between [0, 1] and [a, b] through t. +/// +/// Source: https://stackoverflow.com/a/1820951 +UIKIT_STATIC_INLINE float lerpf(float a, float b, float t) +{ + return a + (b - a) * t; +} diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m index 49be86324..c5de49ffa 100644 --- a/Limelight/ViewControllers/SettingsViewController.m +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -16,6 +16,7 @@ @implementation SettingsViewController { NSInteger _bitrate; NSInteger _lastSelectedResolutionIndex; + float _touchpadSensitivityPreviousValue; } @dynamic overrideUserInterfaceStyle; @@ -54,6 +55,11 @@ @implementation SettingsViewController { const int RESOLUTION_TABLE_CUSTOM_INDEX = RESOLUTION_TABLE_SIZE - 1; CGSize resolutionTable[RESOLUTION_TABLE_SIZE]; +static NSString* touchpadSensitivityFormat = @"Touchpad Sensitivity: %.2fx"; + +/// The maximum allowable relative touch sensitivity multipler, as stored on Core Data. +const float RELATIVE_TOUCH_SENSITIVITY_MAX_MULTIPLIER = 6.0; + -(int)getSliderValueForBitrate:(NSInteger)bitrate { int i; @@ -67,6 +73,30 @@ -(int)getSliderValueForBitrate:(NSInteger)bitrate { return i - 1; } +/// Converts the relativeTouchSensitivity as stored on Core Data to touchpadSensitivitySlider's value. +-(float)getSliderValueForTouchpadSensitivity:(float)sensitivity { + float sliderMidpoint = (self.touchpadSensitivitySlider.maximumValue + self.touchpadSensitivitySlider.minimumValue) / 2.0; + + if (sensitivity > RELATIVE_TOUCH_SENSITIVITY_MAX_MULTIPLIER) { + // Clamp to RELATIVE_TOUCH_SENSITIVITY_MAX_MULTIPLIER + return self.touchpadSensitivitySlider.maximumValue; + } else if (sensitivity >= 1) { + // Linearly interpolate from [1..RELATIVE_TOUCH_SENSITIVITY_MAX_MULTIPLIER] + // to [sliderMidpoint..sliderMax] + return lerpf( + sliderMidpoint, + self.touchpadSensitivitySlider.maximumValue, + (sensitivity - 1) / (RELATIVE_TOUCH_SENSITIVITY_MAX_MULTIPLIER - 1) + ); + } else if (sensitivity >= 0) { + // Linearly interpolate from [0..1) to [sliderMin..sliderMidpoint) + return sensitivity * sliderMidpoint; + } else { + // Clamp to 0x + return self.touchpadSensitivitySlider.minimumValue; + } +} + // This view is rooted at a ScrollView. To make it scrollable, // we'll update content size here. -(void)viewDidLayoutSubviews { @@ -137,6 +167,8 @@ - (void)viewDidLoad { DataManager* dataMan = [[DataManager alloc] init]; TemporarySettings* currentSettings = [dataMan getSettings]; + _touchpadSensitivityPreviousValue = 1.0; + // Ensure we pick a bitrate that falls exactly onto a slider notch _bitrate = bitrateTable[[self getSliderValueForBitrate:[currentSettings.bitrate intValue]]]; @@ -252,12 +284,17 @@ - (void)viewDidLoad { [self.framerateSelector addTarget:self action:@selector(updateBitrate) forControlEvents:UIControlEventValueChanged]; [self.onscreenControlSelector setSelectedSegmentIndex:onscreenControls]; [self.onscreenControlSelector setEnabled:!currentSettings.absoluteTouchMode]; + [self.touchpadSensitivitySlider setValue:[self getSliderValueForTouchpadSensitivity:currentSettings.relativeTouchSensitivity.floatValue]]; + [self.touchpadSensitivitySlider addTarget:self action:@selector(touchpadSensitivitySliderMoved) forControlEvents:UIControlEventValueChanged]; + [self.touchpadSensitivitySlider addTarget:self action:@selector(touchpadSensitivitySliderTouchStart) forControlEvents:UIControlEventTouchDown]; + [self.touchpadSensitivitySlider addTarget:self action:@selector(touchpadSensitivitySliderTouchEnd) forControlEvents:UIControlEventTouchUpInside]; + [self.touchpadSensitivitySlider addTarget:self action:@selector(touchpadSensitivitySliderTouchEnd) forControlEvents:UIControlEventTouchUpOutside]; [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 updateCustomResolutionText]; + [self updateTouchpadSensitivityText]; } - (void) touchModeChanged { @@ -423,6 +460,40 @@ - (void) updateBitrateText { [self.bitrateLabel setText:[NSString stringWithFormat:bitrateFormat, _bitrate / 1000.]]; } +- (void) touchpadSensitivitySliderTouchStart { + self.impactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; + [self.impactFeedbackGenerator prepare]; +} + +- (void) touchpadSensitivitySliderTouchEnd { + self.impactFeedbackGenerator = NULL; +} + +- (void) touchpadSensitivitySliderMoved { + float value = self.touchpadSensitivitySlider.value; + float sliderMidpoint = (self.touchpadSensitivitySlider.maximumValue + self.touchpadSensitivitySlider.minimumValue) / 2.0; + float sliderRange = self.touchpadSensitivitySlider.maximumValue - self.touchpadSensitivitySlider.minimumValue; + float sliderSnapThresholdRadius = sliderRange * 0.02; + if ( + value >= (sliderMidpoint - sliderSnapThresholdRadius) && + value <= (sliderMidpoint + sliderSnapThresholdRadius) + ) { + [self.touchpadSensitivitySlider setValue:sliderMidpoint]; + + if (_touchpadSensitivityPreviousValue != sliderMidpoint) { + [self.impactFeedbackGenerator impactOccurred]; + // Keep the generator in a prepared state + [self.impactFeedbackGenerator prepare]; + } + } + [self updateTouchpadSensitivityText]; + _touchpadSensitivityPreviousValue = self.touchpadSensitivitySlider.value; +} + +- (void) updateTouchpadSensitivityText { + [self.touchpadSensitivityLabel setText:[NSString stringWithFormat:touchpadSensitivityFormat, [self getChosenRelativeTouchSensitivity]]]; +} + - (NSInteger) getChosenFrameRate { switch ([self.framerateSelector selectedSegmentIndex]) { case 0: @@ -456,12 +527,34 @@ - (NSInteger) getChosenStreamWidth { return resolutionTable[[self.resolutionSelector selectedSegmentIndex]].width; } +/// Converts the touchpadSensitivitySlider's current value to the relativeTouchSensitivity as stored on Core Data +- (float) getChosenRelativeTouchSensitivity { + float sliderValue = self.touchpadSensitivitySlider.value; + float sliderMax = self.touchpadSensitivitySlider.maximumValue; + float sliderMin = self.touchpadSensitivitySlider.minimumValue; + float sliderMidpoint = (sliderMax + sliderMin) / 2.0; + + if (sliderValue >= sliderMidpoint) { + // Linearly interpolate from [sliderMidpoint..sliderMax] + // to [1..RELATIVE_TOUCH_SENSITIVITY_MAX_MULTIPLIER] + return lerpf( + 1, + RELATIVE_TOUCH_SENSITIVITY_MAX_MULTIPLIER, + (sliderValue - sliderMidpoint) / (sliderMax - sliderMidpoint) + ); + } else { + // Linearly interpolate from [sliderMin..sliderMidpoint) to [0..1) + return lerpf(0, 1, (sliderValue - sliderMin) / (sliderMidpoint - sliderMin)); + } +} + - (void) saveSettings { DataManager* dataMan = [[DataManager alloc] init]; NSInteger framerate = [self getChosenFrameRate]; NSInteger height = [self getChosenStreamHeight]; NSInteger width = [self getChosenStreamWidth]; NSInteger onscreenControls = [self.onscreenControlSelector selectedSegmentIndex]; + float relativeTouchSensitivity = [self getChosenRelativeTouchSensitivity]; BOOL optimizeGames = [self.optimizeSettingsSelector selectedSegmentIndex] == 1; BOOL multiController = [self.multiControllerSelector selectedSegmentIndex] == 1; BOOL swapABXYButtons = [self.swapABXYButtonsSelector selectedSegmentIndex] == 1; @@ -478,6 +571,7 @@ - (void) saveSettings { width:width audioConfig:2 // Stereo onscreenControls:onscreenControls + relativeTouchSensitivity:relativeTouchSensitivity optimizeGames:optimizeGames multiController:multiController swapABXYButtons:swapABXYButtons diff --git a/Moonlight TV/Settings.bundle/Root.plist b/Moonlight TV/Settings.bundle/Root.plist index 36193c7d4..9cd20102b 100644 --- a/Moonlight TV/Settings.bundle/Root.plist +++ b/Moonlight TV/Settings.bundle/Root.plist @@ -180,6 +180,50 @@ DefaultValue + + Type + PSMultiValueSpecifier + Title + Touchpad Sensitivity + Key + relativeTouchSensitivity + DefaultValue + 1 + Values + + 6 + 5 + 4 + 3 + 2 + 1.5 + 1 + 0.75 + 0.5 + 0.333 + 0.25 + 0.2 + 0.166 + 0 + + Titles + + 6x + 5x + 4x + 3x + 2x + 1.5x + 1x + 0.75x + 1/2 + 1/3 + 1/4 + 1/5 + 1/6 + 0x (Frozen mouse) + + Type PSGroupSpecifier diff --git a/Moonlight.xcodeproj/project.pbxproj b/Moonlight.xcodeproj/project.pbxproj index 2968af532..aa6f67b02 100644 --- a/Moonlight.xcodeproj/project.pbxproj +++ b/Moonlight.xcodeproj/project.pbxproj @@ -166,6 +166,7 @@ /* Begin PBXFileReference section */ 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 = ""; }; + 7CB2C5442A2BC071005EEB03 /* Moonlight v1.10.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.10.xcdatamodel"; 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 = ""; }; @@ -1448,6 +1449,7 @@ FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + 7CB2C5442A2BC071005EEB03 /* Moonlight v1.10.xcdatamodel */, 986E28A528EA989100758361 /* Moonlight v1.9.xcdatamodel */, 984CD023288A310D0097D2D4 /* Moonlight v1.8.xcdatamodel */, 566E9D2B2770B23A00EF7BFE /* Moonlight v1.7.xcdatamodel */, @@ -1463,7 +1465,7 @@ FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */, FB290D0619B2C406004C83CF /* Limelight.xcdatamodel */, ); - currentVersion = 986E28A528EA989100758361 /* Moonlight v1.9.xcdatamodel */; + currentVersion = 7CB2C5442A2BC071005EEB03 /* Moonlight v1.10.xcdatamodel */; path = Limelight.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; diff --git a/iPad.storyboard b/iPad.storyboard index d0f87e2dc..adefb6a2a 100644 --- a/iPad.storyboard +++ b/iPad.storyboard @@ -152,15 +152,27 @@ + + + + + + - + @@ -170,14 +182,14 @@ - + @@ -187,21 +199,31 @@ + + + + + + + + + + - + @@ -211,14 +233,14 @@ - + @@ -228,14 +250,14 @@ - + @@ -245,14 +267,14 @@ - + @@ -262,14 +284,14 @@ - + @@ -279,24 +301,14 @@ - - - - - - - - - - - + @@ -325,6 +337,8 @@ + + diff --git a/iPhone.storyboard b/iPhone.storyboard index 312542e63..36d324b25 100644 --- a/iPhone.storyboard +++ b/iPhone.storyboard @@ -82,7 +82,7 @@ - + + + + + + + - + @@ -189,14 +201,14 @@ - + @@ -206,14 +218,14 @@ - + @@ -223,14 +235,14 @@ - + @@ -240,14 +252,14 @@ - + @@ -257,14 +269,14 @@ - + @@ -274,14 +286,14 @@ - + @@ -291,14 +303,14 @@ - + @@ -308,14 +320,14 @@ - + @@ -327,6 +339,7 @@ + @@ -344,6 +357,8 @@ + +