Files
PojavLauncher_iOS/Natives/SurfaceViewController+LogView.m
T
Duy Tran Khanh 8ca77a1b73 Support resizable for iPadOS Stage Manager
On iPadOS, PojavLauncher can be launched in portrait mode
Declare controller support in Info.plist
Sync LWJGL changes from Android repo
2022-10-31 11:13:03 +07:00

227 lines
9.3 KiB
Objective-C

#import "SurfaceViewController.h"
static BOOL fatalErrorOccurred;
extern UIWindow* currentWindow();
@interface LogDelegate : NSObject
@end
@interface LogDelegate()<UITableViewDataSource, UITableViewDelegate>
@end
static NSMutableArray* logLines;
@implementation LogDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return logLines.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
cell.backgroundColor = UIColor.clearColor;
//cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:16];
cell.textLabel.textColor = UIColor.whiteColor;
}
cell.textLabel.text = logLines[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *line = cell.textLabel.text;
if (line.length == 0 || [line isEqualToString:@"\n"]) {
return;
}
SurfaceViewController *vc = (id)currentWindow().rootViewController;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:line preferredStyle:UIAlertControllerStyleActionSheet];
alert.popoverPresentationController.sourceView = cell;
alert.popoverPresentationController.sourceRect = cell.bounds;
UIAlertAction *share = [UIAlertAction actionWithTitle:NSLocalizedString(NSLocalizedString(@"Share", nil), nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
UIView *navigationBar = vc.logOutputView.subviews[1];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[line] applicationActivities:nil];
activityVC.popoverPresentationController.sourceView = navigationBar;
activityVC.popoverPresentationController.sourceRect = navigationBar.bounds;
[vc presentViewController:activityVC animated:YES completion:nil];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil];
[alert addAction:share];
[alert addAction:cancel];
[vc presentViewController:alert animated:YES completion:nil];
}
@end
@implementation SurfaceViewController(LogView)
static LogDelegate* logDelegate;
static int logCharPerLine;
- (void)initCategory_LogView {
logLines = NSMutableArray.new;
logCharPerLine = self.view.frame.size.width / 10;
self.logOutputView = [[UIView alloc] initWithFrame:CGRectOffset(self.view.frame, 0, self.view.frame.size.height)];
self.logOutputView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
self.logOutputView.hidden = YES;
UINavigationItem *navigationItem = [[UINavigationItem alloc] init];
navigationItem.rightBarButtonItems = @[
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
target:self action:@selector(actionToggleLogOutput)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
target:self action:@selector(actionClearLogOutput)]
];
UINavigationBar* navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
navigationBar.items = @[navigationItem];
navigationBar.topItem.title = NSLocalizedString(@"game.menu.log_output", nil);
[navigationBar sizeToFit];
navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.logTableView = [[UITableView alloc] initWithFrame:self.view.frame];
logDelegate = [[LogDelegate alloc] init];
//self.logTableView.allowsSelection = NO;
self.logTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.logTableView.backgroundColor = UIColor.clearColor;
self.logTableView.contentInset = UIEdgeInsetsMake(navigationBar.frame.size.height, 0, 0, 0);
self.logTableView.dataSource = logDelegate;
self.logTableView.delegate = logDelegate;
self.logTableView.layoutMargins = UIEdgeInsetsZero;
self.logTableView.rowHeight = 20;
self.logTableView.separatorInset = UIEdgeInsetsZero;
self.logTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.logOutputView addSubview:self.logTableView];
[self.logOutputView addSubview:navigationBar];
[self.rootView addSubview:self.logOutputView];
canAppendToLog = YES;
[self actionStartStopLogOutput];
}
- (void)actionClearLogOutput {
[logLines removeAllObjects];
[self.logTableView reloadData];
}
- (void)actionShareLatestlog {
UINavigationBar *navigationBar = self.logOutputView.subviews[1];
NSString *latestlogPath = [NSString stringWithFormat:@"file://%s/latestlog.txt", getenv("POJAV_HOME")];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[@"latestlog.txt",
[NSURL URLWithString:latestlogPath]] applicationActivities:nil];
activityVC.popoverPresentationController.sourceView = navigationBar;
activityVC.popoverPresentationController.sourceRect = navigationBar.bounds;
[self presentViewController:activityVC animated:YES completion:nil];
}
- (void)actionStartStopLogOutput {
canAppendToLog = !canAppendToLog;
UINavigationItem* item = ((UINavigationBar *)self.logOutputView.subviews[1]).items[0];
item.leftBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
canAppendToLog ? UIBarButtonSystemItemPause : UIBarButtonSystemItemPlay
target:self action:@selector(actionStartStopLogOutput)];
}
- (void)actionToggleLogOutput {
if (fatalErrorOccurred) {
[self performSelector:@selector(actionForceClose)];
return;
}
UIViewAnimationOptions opt = self.logOutputView.hidden ? UIViewAnimationOptionCurveEaseOut : UIViewAnimationOptionCurveEaseIn;
[UIView transitionWithView:self.logOutputView duration:0.4 options:UIViewAnimationOptionCurveEaseOut animations:^(void){
CGRect frame = self.logOutputView.frame;
frame.origin.y = self.logOutputView.hidden ? 0 : frame.size.height;
self.logOutputView.hidden = NO;
self.logOutputView.frame = frame;
} completion: ^(BOOL finished) {
self.logOutputView.hidden = self.logOutputView.frame.origin.y != 0;
}];
}
+ (void)_appendToLog:(NSString *)line {
if (line.length == 0) {
return;
}
SurfaceViewController *instance = (id)currentWindow().rootViewController;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:logLines.count inSection:0];
[logLines addObject:line];
[instance.logTableView beginUpdates];
[instance.logTableView
insertRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationNone];
[instance.logTableView endUpdates];
[instance.logTableView
scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}
+ (void)appendToLog:(NSString *)string {
dispatch_async(dispatch_get_main_queue(), ^(void){
NSArray *lines = [string componentsSeparatedByCharactersInSet:
NSCharacterSet.newlineCharacterSet];
for (NSString *line in lines) {
[self _appendToLog:line];
}
});
}
+ (void)handleExitCode:(int)code {
dispatch_async(dispatch_get_main_queue(), ^(void){
SurfaceViewController *instance = (id)currentWindow().rootViewController;
if (instance.logOutputView.hidden) {
[instance actionToggleLogOutput];
}
// Cleanup navigation bar
UINavigationBar *navigationBar = instance.logOutputView.subviews[1];
navigationBar.topItem.title = [NSString stringWithFormat:
NSLocalizedString(@"game.title.exit_code", nil), code];
navigationBar.items[0].leftBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:instance action:@selector(actionShareLatestlog)];
UIBarButtonItem *exitItem = navigationBar.items[0].rightBarButtonItems[0];
navigationBar.items[0].rightBarButtonItems = nil;
navigationBar.items[0].rightBarButtonItem = exitItem;
if (canAppendToLog) {
canAppendToLog = NO;
fatalErrorOccurred = YES;
return;
}
[instance actionClearLogOutput];
[self _appendToLog:@"... (latestlog.txt)"];
NSString *latestlogPath = [NSString stringWithFormat:@"%s/latestlog.txt", getenv("POJAV_HOME")];
NSString *linesStr = [NSString stringWithContentsOfFile:latestlogPath
encoding:NSUTF8StringEncoding error:nil];
NSArray *lines = [linesStr componentsSeparatedByCharactersInSet:
NSCharacterSet.newlineCharacterSet];
// Print last 100 lines from latestlog.txt
for (int i = MAX(lines.count-100, 0); i < lines.count; i++) {
[self _appendToLog:lines[i]];
}
fatalErrorOccurred = YES;
});
}
- (void)viewWillTransitionToSize_LogView:(CGRect)frame {
self.logOutputView.frame = frame;
}
@end