Fix: control safe area breaks in portrait mode
Rewrite the control safe area system: - Use UIEdgeInsets instead of CGRect (breaking change!) - Auto change depending on orientation (not really consistent yet) The safe area is reset to reflect this breaking change.
This commit is contained in:
1 parent
ca98257884
commit
31906e33b7
6 files changed
+63
-48
No files matched your search
@@ -53,7 +53,7 @@ BOOL shouldDismissPopover = YES;
|
||||
guideLabel.text = localize(@"custom_controls.hint", nil);
|
||||
[self.view addSubview:guideLabel];
|
||||
|
||||
self.ctrlView = [[ControlLayout alloc] initWithFrame:CGRectFromString(getPreference(@"control_safe_area"))];
|
||||
self.ctrlView = [[ControlLayout alloc] initWithFrame:getSafeArea()];
|
||||
if (@available(iOS 13.0, *)) {
|
||||
self.ctrlView.layer.borderColor = UIColor.labelColor.CGColor;
|
||||
} else {
|
||||
@@ -180,13 +180,8 @@ BOOL shouldDismissPopover = YES;
|
||||
}
|
||||
|
||||
- (void)viewDidLayoutSubviews {
|
||||
CGRect ctrlFrame = CGRectFromString(getPreference(@"control_safe_area"));
|
||||
if ((ctrlFrame.size.width > ctrlFrame.size.height) != (self.view.frame.size.width > self.view.frame.size.height)) {
|
||||
CGFloat tmpHeight = ctrlFrame.size.width;
|
||||
ctrlFrame.size.width = ctrlFrame.size.height;
|
||||
ctrlFrame.size.height = tmpHeight;
|
||||
self.ctrlView.frame = ctrlFrame;
|
||||
setPreference(@"control_safe_area", NSStringFromCGRect(ctrlFrame));
|
||||
if (self.navigationBar.hidden) {
|
||||
self.ctrlView.frame = getSafeArea();
|
||||
}
|
||||
|
||||
// Update dynamic position for each view
|
||||
@@ -203,10 +198,10 @@ BOOL shouldDismissPopover = YES;
|
||||
self.ctrlView.frame = self.view.frame;
|
||||
break;
|
||||
case 1:
|
||||
self.ctrlView.frame = getDefaultSafeArea();
|
||||
self.ctrlView.frame = UIEdgeInsetsInsetRect(self.view.frame, getDefaultSafeArea());
|
||||
break;
|
||||
case 2:
|
||||
self.ctrlView.frame = CGRectFromString(getPreference(@"control_safe_area"));
|
||||
self.ctrlView.frame = getSafeArea();
|
||||
break;
|
||||
}
|
||||
self.ctrlView.userInteractionEnabled = sender.selectedSegmentIndex == 2;
|
||||
@@ -217,7 +212,7 @@ BOOL shouldDismissPopover = YES;
|
||||
if (CGRectEqualToRect(self.ctrlView.frame, UIScreen.mainScreen.bounds)) {
|
||||
control.selectedSegmentIndex = 0;
|
||||
} else {
|
||||
control.selectedSegmentIndex = !CGRectEqualToRect(self.ctrlView.frame, getDefaultSafeArea()) + 1;
|
||||
control.selectedSegmentIndex = !CGRectEqualToRect(self.ctrlView.frame, UIEdgeInsetsInsetRect(self.view.frame, getDefaultSafeArea())) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,12 +370,12 @@ BOOL shouldDismissPopover = YES;
|
||||
}
|
||||
|
||||
- (void)actionMenuSafeAreaCancel {
|
||||
self.ctrlView.frame = CGRectFromString(getPreference(@"control_safe_area"));
|
||||
self.ctrlView.frame = getSafeArea();
|
||||
[self actionMenuSafeArea];
|
||||
}
|
||||
|
||||
- (void)actionMenuSafeAreaDone {
|
||||
setPreference(@"control_safe_area", NSStringFromCGRect(self.ctrlView.frame));
|
||||
setSafeArea(self.ctrlView.frame);
|
||||
[self actionMenuSafeArea];
|
||||
}
|
||||
|
||||
|
||||
@@ -9,5 +9,8 @@ void setDefaultValueForPref(NSMutableDictionary *dict, NSString* key, id value);
|
||||
void setPreference(NSString* key, id value);
|
||||
void resetWarnings();
|
||||
|
||||
CGRect getDefaultSafeArea();
|
||||
BOOL getEntitlementValue(NSString *key);
|
||||
|
||||
UIEdgeInsets getDefaultSafeArea();
|
||||
CGRect getSafeArea();
|
||||
void setSafeArea(CGRect safeArea);
|
||||
@@ -48,6 +48,7 @@ int getJavaVersion(NSString* java) {
|
||||
return [java substringWithRange:NSMakeRange(5, java.length - 13)].intValue;
|
||||
} else {
|
||||
NSLog(@"FIXME: What is the Java version of %@?", java);
|
||||
// TODO: parse from the release file
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -190,18 +191,42 @@ void resetWarnings() {
|
||||
[prefDict writeToFile:prefPath atomically:YES];
|
||||
}
|
||||
|
||||
CGRect getDefaultSafeArea() {
|
||||
CGRect defaultSafeArea = UIScreen.mainScreen.bounds;
|
||||
UIEdgeInsets insets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
|
||||
defaultSafeArea.origin.x = insets.left;
|
||||
//defaultSafeArea.origin.y = insets.top;
|
||||
defaultSafeArea.size.width -= insets.left + insets.right;
|
||||
//defaultSafeArea.size.height -= insets.bottom;
|
||||
// In some cases, the returned bounds is portrait instead of landscape
|
||||
if (defaultSafeArea.size.width < defaultSafeArea.size.height) {
|
||||
CGFloat height = defaultSafeArea.size.width;
|
||||
defaultSafeArea.size.width = defaultSafeArea.size.height;
|
||||
defaultSafeArea.size.height = height;
|
||||
CGRect getSafeArea() {
|
||||
CGRect screenBounds = UIScreen.mainScreen.bounds;
|
||||
UIEdgeInsets safeArea = UIEdgeInsetsFromString(getPreference(@"control_safe_area"));
|
||||
if (screenBounds.size.width < screenBounds.size.height) {
|
||||
safeArea = UIEdgeInsetsMake(safeArea.right, safeArea.top, safeArea.left, safeArea.bottom);
|
||||
}
|
||||
return defaultSafeArea;
|
||||
return UIEdgeInsetsInsetRect(screenBounds, safeArea);
|
||||
}
|
||||
|
||||
void setSafeArea(CGRect frame) {
|
||||
CGSize screenSize = UIScreen.mainScreen.bounds.size;
|
||||
UIEdgeInsets safeArea;
|
||||
// TODO: make safe area consistent across opposite orientations?
|
||||
if (screenSize.width < screenSize.height) {
|
||||
safeArea = UIEdgeInsetsMake(
|
||||
frame.origin.x,
|
||||
screenSize.height - CGRectGetMaxY(frame),
|
||||
screenSize.width - CGRectGetMaxX(frame),
|
||||
frame.origin.y);
|
||||
} else {
|
||||
safeArea = UIEdgeInsetsMake(
|
||||
frame.origin.y,
|
||||
frame.origin.x,
|
||||
screenSize.height - CGRectGetMaxY(frame),
|
||||
screenSize.width - CGRectGetMaxX(frame));
|
||||
}
|
||||
setPreference(@"control_safe_area", NSStringFromUIEdgeInsets(safeArea));
|
||||
}
|
||||
|
||||
UIEdgeInsets getDefaultSafeArea() {
|
||||
UIEdgeInsets safeArea = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
|
||||
CGSize screenSize = UIScreen.mainScreen.bounds.size;
|
||||
if (screenSize.width < screenSize.height) {
|
||||
safeArea.left = safeArea.top;
|
||||
safeArea.right = safeArea.bottom;
|
||||
}
|
||||
safeArea.top = safeArea.bottom = 0;
|
||||
return safeArea;
|
||||
}
|
||||
@@ -17,7 +17,11 @@ extern NSMutableDictionary *prefDict;
|
||||
[super viewDidLoad];
|
||||
UIApplication.sharedApplication.idleTimerDisabled = YES;
|
||||
setViewBackgroundColor(self.view);
|
||||
setDefaultValueForPref(prefDict, @"control_safe_area", NSStringFromCGRect(getDefaultSafeArea()));
|
||||
setDefaultValueForPref(prefDict, @"control_safe_area", NSStringFromUIEdgeInsets(getDefaultSafeArea()));
|
||||
if (![getPreference(@"internal_reset_safe_area") boolValue]) {
|
||||
setPreference(@"internal_reset_safe_area", @YES);
|
||||
setPreference(@"control_safe_area", NSStringFromUIEdgeInsets(getDefaultSafeArea()));
|
||||
}
|
||||
|
||||
self.delegate = self;
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ BOOL slideableHotbar;
|
||||
self.rootView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width + 30.0, self.view.frame.size.height)];
|
||||
[self.view addSubview:self.rootView];
|
||||
|
||||
self.ctrlView = [[ControlLayout alloc] initWithFrame:CGRectFromString(getPreference(@"control_safe_area"))];
|
||||
self.ctrlView = [[ControlLayout alloc] initWithFrame:getSafeArea()];
|
||||
|
||||
[self performSelector:@selector(initCategory_Navigation)];
|
||||
|
||||
@@ -335,13 +335,7 @@ BOOL slideableHotbar;
|
||||
virtualMouseFrame = CGRectMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2, 18.0 * mouseScale, 27 * mouseScale);
|
||||
self.mousePointerView.frame = virtualMouseFrame;
|
||||
|
||||
CGRect ctrlFrame = CGRectFromString(getPreference(@"control_safe_area"));
|
||||
if ((ctrlFrame.size.width > ctrlFrame.size.height) != (self.view.frame.size.width > self.view.frame.size.height)) {
|
||||
CGFloat tmpHeight = ctrlFrame.size.width;
|
||||
ctrlFrame.size.width = ctrlFrame.size.height;
|
||||
ctrlFrame.size.height = tmpHeight;
|
||||
}
|
||||
self.ctrlView.frame = ctrlFrame;
|
||||
self.ctrlView.frame = getSafeArea();
|
||||
[self loadCustomControls];
|
||||
|
||||
// Update gestures state
|
||||
@@ -459,17 +453,7 @@ BOOL slideableHotbar;
|
||||
[self viewWillTransitionToSize_Navigation:frame];
|
||||
|
||||
// Update custom controls button position
|
||||
CGRect ctrlFrame = CGRectFromString(getPreference(@"control_safe_area"));
|
||||
CGSize screenSize = UIScreen.mainScreen.bounds.size;
|
||||
if (size.width < screenSize.width || size.height < screenSize.height) {
|
||||
// TODO: safe area for windowed mode?
|
||||
ctrlFrame.size = screenSize;
|
||||
} else if ((ctrlFrame.size.width > ctrlFrame.size.height) != (size.width > size.height)) {
|
||||
CGFloat tmpHeight = ctrlFrame.size.width;
|
||||
ctrlFrame.size.width = ctrlFrame.size.height;
|
||||
ctrlFrame.size.height = tmpHeight;
|
||||
}
|
||||
self.ctrlView.frame = ctrlFrame;
|
||||
self.ctrlView.frame = getSafeArea();
|
||||
[self.ctrlView.subviews makeObjectsPerformSelector:@selector(update)];
|
||||
|
||||
// Update game resolution
|
||||
|
||||
@@ -137,7 +137,11 @@ const NSString *cornerLayerKey = @"cornerLayer";
|
||||
// Simulate safe area on iPhones without notch
|
||||
/*
|
||||
- (UIEdgeInsets)safeAreaInsets {
|
||||
return UIEdgeInsetsMake(0, 44, 21, 44);
|
||||
if (self.frame.size.width < self.frame.size.height) {
|
||||
return UIEdgeInsetsMake(44, 0, 44, 0);
|
||||
} else {
|
||||
return UIEdgeInsetsMake(0, 44, 21, 44);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
Reference in new issue
Block a user