From d8459effc08d041b87acf19c66ebd8bb28588955 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh Date: Fri, 22 Jul 2022 08:02:40 +0700 Subject: [PATCH] WIP: New User interface UISplitViewController is being used to create split menu. Currently, autolayout is not yet done. Added account switcher to the split view. Fixes: - auth_session parameter for legacy Minecraft versions - Updating self.view background color is now automated by UIColor.systemBackgroundColor --- .../main/java/net/kdt/pojavlaunch/Tools.java | 1 + Natives/AboutLauncherViewController.m | 19 +-- Natives/AccountListViewController.h | 3 +- Natives/AccountListViewController.m | 9 +- Natives/CMakeLists.txt | 3 + Natives/CustomControlsViewController.m | 22 +-- Natives/JavaGUIViewController.m | 20 +-- Natives/LauncherFAQViewController.m | 18 +-- Natives/LauncherMenuViewController.h | 7 + Natives/LauncherMenuViewController.m | 138 ++++++++++++++++++ Natives/LauncherPreferencesViewController.m | 20 +-- Natives/LauncherSplitViewController.h | 5 + Natives/LauncherSplitViewController.m | 42 ++++++ Natives/LauncherViewController.m | 39 +---- Natives/LoginViewController.m | 53 +++---- Natives/SceneDelegate.m | 1 - Natives/SurfaceViewController.m | 22 ++- Natives/UpdateHistoryViewController.m | 21 +-- Natives/ios_uikit_bridge.m | 5 +- Natives/utils.h | 1 + Natives/utils.m | 8 + 21 files changed, 268 insertions(+), 189 deletions(-) create mode 100644 Natives/LauncherMenuViewController.h create mode 100644 Natives/LauncherMenuViewController.m create mode 100644 Natives/LauncherSplitViewController.h create mode 100644 Natives/LauncherSplitViewController.m diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java index 12eb1a3e..e3965723 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -158,6 +158,7 @@ public final class Tools gameDir.mkdirs(); Map varArgMap = new ArrayMap(); + varArgMap.put("auth_session", profile.accessToken); // For legacy versions of MC varArgMap.put("auth_access_token", profile.accessToken); varArgMap.put("auth_player_name", username); varArgMap.put("auth_uuid", profile.profileId); diff --git a/Natives/AboutLauncherViewController.m b/Natives/AboutLauncherViewController.m index b3066cff..5f9d9204 100644 --- a/Natives/AboutLauncherViewController.m +++ b/Natives/AboutLauncherViewController.m @@ -26,7 +26,7 @@ - (void)viewDidLoad { [super viewDidLoad]; - + setViewBackgroundColor(self.view); [self setTitle:@"About PojavLauncher"]; CGRect screenBounds = [[UIScreen mainScreen] bounds]; @@ -40,13 +40,6 @@ [self.view addSubview:scrollView]; scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - // Update color mode once - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - // TODO: Move this into utils? struct utsname systemInfo; uname(&systemInfo); @@ -125,14 +118,4 @@ [self.navigationController pushViewController:vc animated:YES]; } --(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if(@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - @end diff --git a/Natives/AccountListViewController.h b/Natives/AccountListViewController.h index 7ab063c2..4d1f418a 100644 --- a/Natives/AccountListViewController.h +++ b/Natives/AccountListViewController.h @@ -1,6 +1,7 @@ #import -@interface AccountListViewController : UITableViewController +@interface AccountListViewController: UITableViewController + @property (nonatomic, copy) void (^whenDelete)(NSString* name); @property(nonatomic, copy) void (^whenItemSelected)(NSString* name); diff --git a/Natives/AccountListViewController.m b/Natives/AccountListViewController.m index d8247888..6b444dfb 100644 --- a/Natives/AccountListViewController.m +++ b/Natives/AccountListViewController.m @@ -58,8 +58,10 @@ } NSDictionary *selected = self.accountList[indexPath.row]; + // By default, display the saved username cell.textLabel.text = selected[@"username"]; if ([selected[@"username"] hasPrefix:@"Demo."]) { + // Remove the prefix "Demo." cell.textLabel.text = [selected[@"username"] substringFromIndex:5]; cell.detailTextLabel.text = NSLocalizedString(@"login.option.demo", nil); } else if (selected[@"xboxGamertag"] == nil) { @@ -85,7 +87,7 @@ if (editingStyle == UITableViewCellEditingStyleDelete) { // TODO: invalidate token - NSString *str = [self.accountList objectAtIndex:indexPath.row][@"username"]; + NSString *str = self.accountList[indexPath.row][@"username"]; NSFileManager *fm = [NSFileManager defaultManager]; NSString *path = [NSString stringWithFormat:@"%s/accounts/%@.json", getenv("POJAV_HOME"), str]; if (self.whenDelete != nil) { @@ -97,4 +99,9 @@ } } +#pragma mark - UIPopoverPresentationControllerDelegate +- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection { + return UIModalPresentationNone; +} + @end diff --git a/Natives/CMakeLists.txt b/Natives/CMakeLists.txt index 89b1b8b3..1de7337a 100644 --- a/Natives/CMakeLists.txt +++ b/Natives/CMakeLists.txt @@ -59,6 +59,7 @@ add_executable(PojavLauncher external/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m external/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.m external/AFNetworking/UIKit+AFNetworking/AFImageDownloader.m + external/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.m external/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.m main.m @@ -87,8 +88,10 @@ add_executable(PojavLauncher JavaGUIViewController.m KeyboardInput.m LauncherFAQViewController.m + LauncherMenuViewController.m LauncherPreferences.m LauncherPreferencesViewController.m + LauncherSplitViewController.m LauncherViewController.m LoginViewController.m MinecraftResourceUtils.m diff --git a/Natives/CustomControlsViewController.m b/Natives/CustomControlsViewController.m index 6a5d7f6d..72a4d9bf 100644 --- a/Natives/CustomControlsViewController.m +++ b/Natives/CustomControlsViewController.m @@ -86,19 +86,12 @@ NSMutableArray *keyCodeMap, *keyValueMap; - (void)viewDidLoad { [super viewDidLoad]; + viewController = self; isControlModifiable = YES; - [self.navigationController setNavigationBarHidden:YES animated:YES]; [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; [self setNeedsUpdateOfHomeIndicatorAutoHidden]; - // Update color mode once - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - CGRect screenBounds = [[UIScreen mainScreen] bounds]; UIEdgeInsets insets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets; @@ -203,8 +196,7 @@ NSMutableArray *keyCodeMap, *keyValueMap; } - (void)actionMenuExit { - [self.navigationController setNavigationBarHidden:NO animated:YES]; - [self.navigationController popViewControllerAnimated:YES]; + [self dismissViewControllerAnimated:YES completion:nil]; } - (void)actionMenuSave { @@ -437,16 +429,6 @@ NSMutableArray *keyCodeMap, *keyValueMap; } } --(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if(@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - #pragma mark - UIPopoverPresentationControllerDelegate - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection { return UIModalPresentationNone; diff --git a/Natives/JavaGUIViewController.m b/Natives/JavaGUIViewController.m index 883a9dfe..6e113a4f 100644 --- a/Natives/JavaGUIViewController.m +++ b/Natives/JavaGUIViewController.m @@ -69,7 +69,8 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { - (void)viewDidLoad { [super viewDidLoad]; - + viewController = self; + self.view.backgroundColor = UIColor.blackColor; [self.navigationController setNavigationBarHidden:YES animated:NO]; [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; [self setNeedsUpdateOfHomeIndicatorAutoHidden]; @@ -95,13 +96,6 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { [self.view addSubview:scrollView]; - // Update color mode once - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnClick:)]; tapGesture.delegate = self; @@ -164,14 +158,4 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { return NO; } --(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if(@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - @end diff --git a/Natives/LauncherFAQViewController.m b/Natives/LauncherFAQViewController.m index 6717c4e0..7b64adb8 100644 --- a/Natives/LauncherFAQViewController.m +++ b/Natives/LauncherFAQViewController.m @@ -12,7 +12,7 @@ CGFloat faqcurrY = 4.0; - (void)viewDidLoad { [super viewDidLoad]; - + setViewBackgroundColor(self.view); [self setTitle:@"Launcher FAQ"]; CGRect screenBounds = [[UIScreen mainScreen] bounds]; @@ -25,12 +25,6 @@ CGFloat faqcurrY = 4.0; [self.view addSubview:scrollView]; scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - // Update color mode once - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } NSString *snapheadingtext = @"Vanilla versions after 21w08b"; faqcurrY = 4.0; @@ -67,14 +61,4 @@ CGFloat faqcurrY = 4.0; return label; } --(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if(@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - @end diff --git a/Natives/LauncherMenuViewController.h b/Natives/LauncherMenuViewController.h new file mode 100644 index 00000000..ff66f69a --- /dev/null +++ b/Natives/LauncherMenuViewController.h @@ -0,0 +1,7 @@ +#import + +@interface LauncherMenuViewController : UITableViewController + +@property NSString* listPath; + +@end diff --git a/Natives/LauncherMenuViewController.m b/Natives/LauncherMenuViewController.m new file mode 100644 index 00000000..0a3c15f9 --- /dev/null +++ b/Natives/LauncherMenuViewController.m @@ -0,0 +1,138 @@ +#import "authenticator/BaseAuthenticator.h" +#import "AccountListViewController.h" +#import "LauncherMenuViewController.h" +#import "LauncherPreferencesViewController.h" +#import "LauncherViewController.h" +#import "UIButton+AFNetworking.h" +#import "UIImageView+AFNetworking.h" + +@interface LauncherMenuViewController () { +} + +@property NSArray *options; +@end + +@implementation LauncherMenuViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + // View controllers are put into an array to keep its state + self.options = @[ + [[LauncherViewController alloc] init], + [[LauncherPreferencesViewController alloc] init] + ]; + self.options[0].title = @"PojavLauncher"; + self.options[1].title = @"Preferences"; + //@[@"News", @"Development Console", @"Crash logs"]; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + + UIButton *titleButton = [UIButton buttonWithType:UIButtonTypeCustom]; + [titleButton addTarget:self action:@selector(selectAccount:) forControlEvents:UIControlEventTouchUpInside]; + titleButton.frame = self.navigationController.navigationBar.frame; + titleButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + if (@available(iOS 14.0, tvOS 14.0, *)) { + // On iOS 14+, a special button is displayed to toggle the visibility of the master view controller. + // It creates a bit more offset while in the process of swipe/animation. Therefore the left inset + // has to be increased a bit for this button. + titleButton.contentEdgeInsets = UIEdgeInsetsMake(4, 4, 4, 8); + } else { + titleButton.contentEdgeInsets = UIEdgeInsetsMake(4, 0, 4, 8); + } + titleButton.titleEdgeInsets = UIEdgeInsetsMake(0, 4, 0, -4); + titleButton.imageView.contentMode = UIViewContentModeScaleAspectFit; + titleButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; + self.navigationItem.titleView = titleButton; + + [self updateAccountInfo]; + [self tableView:self.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + // workaround while investigating for issue + if (self.splitViewController.viewControllers.count < 2) return; + + // Restore the selected row when the view appears again + int index = [self.options indexOfObject:[self.splitViewController.viewControllers[1] viewControllers][0]]; + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0]; + [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.options.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; + } + + cell.textLabel.text = [self.options[indexPath.row] title]; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + UIViewController *selected = self.options[indexPath.row]; + [self.splitViewController.viewControllers[1] setViewControllers:@[selected] animated:NO]; //YES? + + if (@available(iOS 14.0, tvOS 14.0, *)) { + // It is unnecessary to put the toggle button as it is automated on iOS 14+ + } else { + selected.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; + selected.navigationItem.leftItemsSupplementBackButton = true; + } + + // This button is placed temporarily while migrating to the new UI + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"❌" style:UIBarButtonItemStyleDone target:self.splitViewController action:@selector(dismissViewController)]; +} + +- (void)selectAccount:(UIButton *)sender { + AccountListViewController *vc = [[AccountListViewController alloc] init]; + vc.whenItemSelected = ^void(NSString* name) { + // TODO: perform token refreshing + [BaseAuthenticator loadSavedName:name]; + [self updateAccountInfo]; + }; + vc.modalPresentationStyle = UIModalPresentationPopover; + vc.preferredContentSize = CGSizeMake(350, 250); + + UIPopoverPresentationController *popoverController = vc.popoverPresentationController; + popoverController.sourceView = sender; + popoverController.sourceRect = sender.bounds; + popoverController.permittedArrowDirections = UIPopoverArrowDirectionAny; + popoverController.delegate = vc; + [self presentViewController:vc animated:YES completion:nil]; +} + +- (void)updateAccountInfo { + NSDictionary *selected = BaseAuthenticator.current.authData; + BOOL isDemo = [selected[@"username"] hasPrefix:@"Demo."]; + NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:[selected[@"username"] substringFromIndex:(isDemo?5:0)]]; + id subtitle; + if (isDemo) { + // Remove the prefix "Demo." + subtitle = NSLocalizedString(@"login.option.demo", nil); + } else if (selected[@"xboxGamertag"] == nil) { + subtitle = NSLocalizedString(@"login.option.local", nil); + } else { + // Display the Xbox gamertag for online accounts + subtitle = selected[@"xboxGamertag"]; + } + subtitle = [[NSAttributedString alloc] initWithString:subtitle attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:12]}]; + [title appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n" attributes:nil]]; + [title appendAttributedString:subtitle]; + [(UIButton *)self.navigationItem.titleView setAttributedTitle:title forState:UIControlStateNormal]; + + NSURL *url = [NSURL URLWithString:[selected[@"profilePicURL"] stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]]; + UIImage *placeholder = [UIImage imageNamed:@"default_account_pfp"]; + [(UIButton *)self.navigationItem.titleView setImageForState:UIControlStateNormal withURL:url placeholderImage:placeholder]; + [((UIButton *)self.navigationItem.titleView).imageView setImageWithURL:url placeholderImage:placeholder]; +} + +@end diff --git a/Natives/LauncherPreferencesViewController.m b/Natives/LauncherPreferencesViewController.m index a5d76b9c..19898195 100644 --- a/Natives/LauncherPreferencesViewController.m +++ b/Natives/LauncherPreferencesViewController.m @@ -102,8 +102,7 @@ int tempIndex; - (void)viewDidLoad { [super viewDidLoad]; - - [self setTitle:@"Preferences"]; + setViewBackgroundColor(self.view); CGRect screenBounds = [[UIScreen mainScreen] bounds]; CGFloat screenScale = [[UIScreen mainScreen] scale]; @@ -137,13 +136,6 @@ int tempIndex; blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular]; blurView = [[UIVisualEffectView alloc] initWithEffect:blur]; - - // Update color mode once - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } UILabel *btnsizeTextView = [[UILabel alloc] initWithFrame:CGRectMake(16.0, currY, 0.0, 30.0)]; btnsizeTextView.text = @"Button scale (%)"; @@ -1018,16 +1010,6 @@ int tempIndex; } } --(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if(@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - #pragma mark - UIPopoverPresentationControllerDelegate - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection { return UIModalPresentationNone; diff --git a/Natives/LauncherSplitViewController.h b/Natives/LauncherSplitViewController.h new file mode 100644 index 00000000..19515fcf --- /dev/null +++ b/Natives/LauncherSplitViewController.h @@ -0,0 +1,5 @@ +#import + +@interface LauncherSplitViewController : UISplitViewController + +@end diff --git a/Natives/LauncherSplitViewController.m b/Natives/LauncherSplitViewController.m new file mode 100644 index 00000000..f27c3a66 --- /dev/null +++ b/Natives/LauncherSplitViewController.m @@ -0,0 +1,42 @@ +#import "LauncherSplitViewController.h" +#import "LauncherMenuViewController.h" +#import "LauncherViewController.h" +#import "utils.h" + +@interface LauncherSplitViewController () { +} + +@end + +@implementation LauncherSplitViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + viewController = self; + setViewBackgroundColor(self.view); + + //TODO: maximumPrimaryColumnWidth + + LauncherMenuViewController *masterVc = [[LauncherMenuViewController alloc] init]; + UINavigationController *detailVc = [[UINavigationController alloc] init]; + + self.presentsWithGesture = YES; + self.preferredDisplayMode = UISplitViewControllerDisplayModeOneBesideSecondary; + self.viewControllers = @[[[UINavigationController alloc] initWithRootViewController:masterVc], detailVc]; + if (@available(iOS 14.0, tvOS 14.0, *)) { + self.preferredSplitBehavior = UISplitViewControllerSplitBehaviorTile; + } +} + +- (UITraitCollection *)traitCollection { + // Allows splitting on compact-sized iPhones + UITraitCollection *collection = super.traitCollection; + UITraitCollection *horizontalCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular]; + return [UITraitCollection traitCollectionWithTraitsFromCollections:@[collection, horizontalCollection]]; +} + +- (void)dismissViewController { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/Natives/LauncherViewController.m b/Natives/LauncherViewController.m index 8c538980..8097dc4f 100644 --- a/Natives/LauncherViewController.m +++ b/Natives/LauncherViewController.m @@ -28,8 +28,6 @@ int versionSelectedAt = 0; [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; [self setNeedsUpdateOfHomeIndicatorAutoHidden]; - - [self setTitle:@"PojavLauncher"]; CGRect screenBounds = [[UIScreen mainScreen] bounds]; CGFloat screenScale = [[UIScreen mainScreen] scale]; @@ -41,13 +39,6 @@ int versionSelectedAt = 0; [self.view addSubview:scrollView]; scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - // Update color mode once - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - UILabel *versionTextView = [[UILabel alloc] initWithFrame:CGRectMake(4.0, 4.0, 0.0, 0.0)]; versionTextView.text = @"Minecraft version: "; versionTextView.numberOfLines = 0; @@ -82,10 +73,8 @@ int versionSelectedAt = 0; handler:^(__kindof UIAction * _Nonnull action) {[self enterModInstaller:self.navigationItem.rightBarButtonItem];}]; UIAction *option2 = [UIAction actionWithTitle:@"Custom controls" image:[[UIImage systemImageNamed:@"dpad.right.fill"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {[self enterCustomControls];}]; - UIAction *option3 = [UIAction actionWithTitle:@"Preferences" image:[[UIImage systemImageNamed:@"wrench.and.screwdriver"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] identifier:nil - handler:^(__kindof UIAction * _Nonnull action) {[self enterPreferences];}]; UIMenu *menu = [UIMenu menuWithTitle:@"" image:nil identifier:nil - options:UIMenuOptionsDisplayInline children:@[option1, option2, option3]]; + options:UIMenuOptionsDisplayInline children:@[option1, option2]]; self.navigationItem.rightBarButtonItem.action = nil; self.navigationItem.rightBarButtonItem.primaryAction = nil; self.navigationItem.rightBarButtonItem.menu = menu; @@ -201,20 +190,17 @@ int versionSelectedAt = 0; handler:^(UIAlertAction * _Nonnull action) {[self enterModInstaller:self.navigationItem.rightBarButtonItem];}]; UIAlertAction *option2 = [UIAlertAction actionWithTitle:@"Custom controls" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {[self enterCustomControls];}]; - UIAlertAction *option3 = [UIAlertAction actionWithTitle:@"Preferences" style:UIAlertActionStyleDefault - handler:^(UIAlertAction * _Nonnull action) {[self enterPreferences];}]; fullAlert.popoverPresentationController.barButtonItem = sender; [self presentViewController:fullAlert animated:YES completion:nil]; [fullAlert addAction:option1]; [fullAlert addAction:option2]; - [fullAlert addAction:option3]; } } - (void)enterCustomControls { if (![getPreference(@"customctrl_warn") boolValue]) { CustomControlsViewController *vc = [[CustomControlsViewController alloc] init]; - [self.navigationController pushViewController:vc animated:YES]; + [self presentViewController:vc animated:YES completion:nil]; return; } setPreference(@"customctrl_warn", @(NO)); @@ -225,7 +211,7 @@ int versionSelectedAt = 0; } UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { CustomControlsViewController *vc = [[CustomControlsViewController alloc] init]; - [self.navigationController pushViewController:vc animated:YES]; + [self presentViewController:vc animated:YES completion:nil]; }]; [self presentViewController:alert animated:YES completion:nil]; [alert addAction:ok]; @@ -257,18 +243,12 @@ int versionSelectedAt = 0; JavaGUIViewController *vc = [[JavaGUIViewController alloc] init]; vc.filepath = url.path; NSLog(@"ModInstaller: launching %@", vc.filepath); - [self.navigationController pushViewController:vc animated:YES]; + [self presentViewController:vc animated:YES completion:nil]; } } -- (void)enterPreferences { - LauncherPreferencesViewController *vc = [[LauncherPreferencesViewController alloc] init]; - [self.navigationController pushViewController:vc animated:YES]; -} - - (void)launchMinecraft:(UIButton *)sender { sender.enabled = NO; - [self.navigationItem setHidesBackButton:YES animated:YES]; NSObject *object = [versionList objectAtIndex:[versionPickerView selectedRowInComponent:0]]; @@ -282,7 +262,6 @@ int versionSelectedAt = 0; = progress; if (stage == nil) { sender.enabled = YES; - [self.navigationItem setHidesBackButton:NO animated:YES]; if (mainProgress != nil) { UIKit_launchMinecraftSurfaceVC(); } @@ -335,14 +314,4 @@ int versionSelectedAt = 0; return NO; } -- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if(@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - @end diff --git a/Natives/LoginViewController.m b/Natives/LoginViewController.m index 418baea8..46eb2faa 100644 --- a/Natives/LoginViewController.m +++ b/Natives/LoginViewController.m @@ -2,27 +2,26 @@ #include #import - #import "authenticator/BaseAuthenticator.h" #import "AppDelegate.h" -#import "LauncherViewController.h" -#import "LoginViewController.h" #import "AboutLauncherViewController.h" #import "AccountListViewController.h" #import "LauncherFAQViewController.h" -#import "LauncherPreferences.h" +#import "LauncherSplitViewController.h" +#import "LoginViewController.h" #import "UpdateHistoryViewController.h" -#include "ios_uikit_bridge.h" -#include "utils.h" +#import "LauncherPreferences.h" +#import "ios_uikit_bridge.h" +#import "utils.h" #define TYPE_SELECTACC 0 #define TYPE_MICROSOFT 1 #define TYPE_OFFLINE 2 #pragma mark - LoginViewController -@interface LoginViewController () { +@interface LoginViewController () { } @property (nonatomic, strong) ASWebAuthenticationSession *authVC; @property (nonatomic, strong) UIActivityViewController *activityViewController; @@ -34,12 +33,10 @@ - (void)viewDidLoad { [super viewDidLoad]; + setViewBackgroundColor(self.view); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(msaLoginCallback:) name:@"MSALoginCallback" object:nil]; - UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil]; - [self.navigationItem setBackBarButtonItem:backItem]; - CGRect screenBounds = [[UIScreen mainScreen] bounds]; int width = (int) roundf(screenBounds.size.width); @@ -50,12 +47,6 @@ scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; [self.view addSubview:scrollView]; - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - if(getenv("POJAV_DETECTEDJB")) { if(strcmp(getenv("POJAV_DETECTEDJB"), "Other") == 0 && [getPreference(@"jb_warn") boolValue] == YES) { UIAlertController *jbAlert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"login.warn.title.otherjb", nil) message:NSLocalizedString(@"login.warn.message.otherjb", nil) preferredStyle:UIAlertControllerStyleAlert]; @@ -85,7 +76,7 @@ [dateFormatter setDateFormat:@"MM-dd"]; NSString* date = [dateFormatter stringFromDate:[NSDate date]]; - if(@available (iOS 14.0, *)) { + if(@available(iOS 14.0, *)) { self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage systemImageNamed:@"info.circle"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] style:UIBarButtonItemStyleDone target:self action:@selector(aboutLauncher)]; UIAction *option1 = [UIAction actionWithTitle:NSLocalizedString(@"login.menu.about", nil) image:[[UIImage systemImageNamed:@"eyes.inverse"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {[self aboutLauncher];}]; @@ -191,16 +182,6 @@ } } -- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if (@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - - (void)displayProgress:(NSString *)title { self.title = title; UIActivityIndicatorViewStyle style; @@ -260,10 +241,15 @@ id callback = ^(BOOL success) { self.title = @""; self.navigationItem.leftBarButtonItem = nil; - if (success) { - LauncherViewController *vc = [[LauncherViewController alloc] init]; - [self.navigationController pushViewController:vc animated:YES]; + if (!success) return; + + LauncherSplitViewController *splitVc; + if (@available(iOS 14.0, tvOS 14.0, *)) { + splitVc = [[LauncherSplitViewController alloc] initWithStyle:UISplitViewControllerStyleDoubleColumn]; + } else { + splitVc = [[LauncherSplitViewController alloc] init]; } + [self presentViewController:splitVc animated:YES completion:nil]; }; if (type == TYPE_SELECTACC) { [auth refreshTokenWithCallback:callback]; @@ -376,7 +362,7 @@ UIPopoverPresentationController *popoverController = [vc popoverPresentationController]; [self setPopoverProperties:popoverController sender:sender]; popoverController.permittedArrowDirections = UIPopoverArrowDirectionAny; - popoverController.delegate = self; + popoverController.delegate = vc; [self presentViewController:vc animated:YES completion:nil]; } @@ -413,11 +399,6 @@ } } -#pragma mark - UIPopoverPresentationControllerDelegate -- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection { - return UIModalPresentationNone; -} - #pragma mark - ASWebAuthenticationPresentationContextProviding - (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session API_AVAILABLE(ios(13.0)){ return UIApplication.sharedApplication.windows.firstObject; diff --git a/Natives/SceneDelegate.m b/Natives/SceneDelegate.m index 032fecf9..e4c7bce9 100644 --- a/Natives/SceneDelegate.m +++ b/Natives/SceneDelegate.m @@ -16,7 +16,6 @@ - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0)) API_AVAILABLE(ios(13.0)) API_AVAILABLE(ios(13.0)){ - if (@available(iOS 13.0, *)) { UIWindowScene *windowScene = (UIWindowScene *)scene; self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; diff --git a/Natives/SurfaceViewController.m b/Natives/SurfaceViewController.m index a98ef45b..efb813cc 100644 --- a/Natives/SurfaceViewController.m +++ b/Natives/SurfaceViewController.m @@ -60,6 +60,20 @@ BOOL slideableHotbar; return [self positionFromPosition:self.beginningOfDocument offset:clamp(start, 20, self.text.length - 20)]; } +- (void)deleteBackward { + [super deleteBackward]; + +} + +- (BOOL)hasText { + return YES; +} + +- (BOOL)insertText:(NSString *)text { + [super insertText:text]; + +} + - (void)setText:(NSString *)text { [super setText:text]; self.lockPos = [self positionFromPosition:self.beginningOfDocument offset:20]; @@ -362,6 +376,9 @@ CGPoint lastCenterPoint; self.rootView.transform = CGAffineTransformScale(CGAffineTransformIdentity, scale, scale); self.menuView.frame = CGRectMake(self.rootView.frame.size.width, self.rootView.frame.origin.y, self.menuView.frame.size.width, self.menuView.frame.size.height); + // scale is in range of 0.7-1 + // 1.1 - scale produces in range of 0.4-0.1 + // result in transform scale range of 1-0.25 self.menuView.transform = CGAffineTransformScale(CGAffineTransformIdentity, (1.1-scale)*2.5, (1.1-scale)*2.5); } else { CGPoint velocity = [sender velocityInView:sender.view]; @@ -370,6 +387,7 @@ CGPoint lastCenterPoint; // calculate duration to produce smooth movement // FIXME: any better way? CGFloat duration = fabs(self.rootView.center.x - centerX * scale) / centerX + 0.1; + duration = MIN(0.4, duration); //(110 - MIN(100, fabs(velocity.x))) / 100 [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseOut @@ -628,8 +646,8 @@ CGPoint lastCenterPoint; - (void)surfaceOnHover:(UIHoverGestureRecognizer *)sender API_AVAILABLE(ios(13.0)) { if (@available(iOS 13.0, *)) { - if (@available(iOS 14.0, *) && isGrabbing) { - return; + if (@available(iOS 14.0, *)) { + if (isGrabbing) return; } CGPoint point = [sender locationInView:self.rootView]; // NSLog(@"Mouse move!!"); diff --git a/Natives/UpdateHistoryViewController.m b/Natives/UpdateHistoryViewController.m index b353cc34..d00d898d 100644 --- a/Natives/UpdateHistoryViewController.m +++ b/Natives/UpdateHistoryViewController.m @@ -18,6 +18,7 @@ CGFloat uhcurrY = 4.0; - (void)viewDidLoad { [super viewDidLoad]; + setViewBackgroundColor(self.view); [self setTitle:@"Update History"]; @@ -32,15 +33,8 @@ CGFloat uhcurrY = 4.0; [self.view addSubview:scrollView]; scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; - // Update color mode once - if(@available(iOS 13.0, *)) { - [self traitCollectionDidChange:nil]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - uhcurrY = 4.0; - + [scrollView addSubview:[self uhContent:true size:25 text:@"Current version" width:width]]; [scrollView addSubview:[self uhContent:true size:20 text:[NSString stringWithFormat:@"2.1 (%s)", CONFIG_TYPE] width:width]]; [scrollView addSubview:[self uhContent:true size:17 text:@"Changes" width:width]]; @@ -136,15 +130,4 @@ CGFloat uhcurrY = 4.0; return label; } - --(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - if(@available(iOS 13.0, *)) { - if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { - self.view.backgroundColor = [UIColor blackColor]; - } else { - self.view.backgroundColor = [UIColor whiteColor]; - } - } -} - @end diff --git a/Natives/ios_uikit_bridge.m b/Natives/ios_uikit_bridge.m index 86ccb40e..b748deb6 100644 --- a/Natives/ios_uikit_bridge.m +++ b/Natives/ios_uikit_bridge.m @@ -127,10 +127,11 @@ void UIKit_launchMinecraftSurfaceVC() { } UIWindow *window = [delegate window]; [UIView animateWithDuration:0.2 animations:^{ - window.rootViewController.view.alpha = 0; + window.alpha = 0; } completion:^(BOOL b){ [window resignKeyWindow]; - window.rootViewController = [[SurfaceViewController alloc] init]; + window.alpha = 1; + window.rootViewController = [[SurfaceViewController alloc] init]; [window makeKeyAndVisible]; }]; } diff --git a/Natives/utils.h b/Natives/utils.h index a2bf0d9e..941fd5fd 100644 --- a/Natives/utils.h +++ b/Natives/utils.h @@ -64,6 +64,7 @@ CGFloat MathUtils_dist(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2); CGFloat MathUtils_map(CGFloat x, CGFloat in_min, CGFloat in_max, CGFloat out_min, CGFloat out_max); CGFloat dpToPx(CGFloat dp); CGFloat pxToDp(CGFloat px); +void setViewBackgroundColor(UIView* view); void _CGDataProviderReleaseBytePointerCallback(void *info,const void *pointer); jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr); diff --git a/Natives/utils.m b/Natives/utils.m index dd81a401..e65462c6 100644 --- a/Natives/utils.m +++ b/Natives/utils.m @@ -102,6 +102,14 @@ CGFloat pxToDp(CGFloat px) { return px / screenScale; } +void setViewBackgroundColor(UIView* view) { + if(@available(iOS 13.0, *)) { + view.backgroundColor = UIColor.systemBackgroundColor; + } else { + view.backgroundColor = UIColor.whiteColor; + } +} + jstring convertStringJVM(JNIEnv* srcEnv, JNIEnv* dstEnv, jstring srcStr) { if (srcStr == NULL) { return NULL;