diff options
Diffstat (limited to 'platform/iphone/view_controller.mm')
-rw-r--r-- | platform/iphone/view_controller.mm | 226 |
1 files changed, 170 insertions, 56 deletions
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index 465e38e45e..6cef244567 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,100 +29,184 @@ /*************************************************************************/ #import "view_controller.h" - +#include "core/config/project_settings.h" +#include "display_server_iphone.h" +#import "godot_view.h" +#import "godot_view_renderer.h" +#import "keyboard_input_view.h" +#import "native_video_view.h" #include "os_iphone.h" -#include "core/project_settings.h" +#import <AVFoundation/AVFoundation.h> +#import <GameController/GameController.h> -extern "C" { +@interface ViewController () <GodotViewDelegate> -int add_path(int, char **); -int add_cmdline(int, char **); +@property(strong, nonatomic) GodotViewRenderer *renderer; +@property(strong, nonatomic) GodotNativeVideoView *videoView; +@property(strong, nonatomic) GodotKeyboardInputView *keyboardView; -int add_path(int p_argc, char **p_args) { +@property(strong, nonatomic) UIView *godotLoadingOverlay; - NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"]; - if (!str) - return p_argc; +@end - p_args[p_argc++] = "--path"; - [str retain]; // memory leak lol (maybe make it static here and delete it in ViewController destructor? @todo - p_args[p_argc++] = (char *)[str cString]; - p_args[p_argc] = NULL; +@implementation ViewController - return p_argc; -}; +- (GodotView *)godotView { + return (GodotView *)self.view; +} -int add_cmdline(int p_argc, char **p_args) { +- (void)loadView { + GodotView *view = [[GodotView alloc] init]; + GodotViewRenderer *renderer = [[GodotViewRenderer alloc] init]; - NSArray *arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_cmdline"]; - if (!arr) - return p_argc; + self.renderer = renderer; + self.view = view; - for (int i = 0; i < [arr count]; i++) { + view.renderer = self.renderer; + view.delegate = self; +} - NSString *str = [arr objectAtIndex:i]; - if (!str) - continue; - [str retain]; // @todo delete these at some point - p_args[p_argc++] = (char *)[str cString]; - }; +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - p_args[p_argc] = NULL; + if (self) { + [self godot_commonInit]; + } - return p_argc; -}; -}; // extern "C" + return self; +} -@interface ViewController () +- (instancetype)initWithCoder:(NSCoder *)coder { + self = [super initWithCoder:coder]; -@end + if (self) { + [self godot_commonInit]; + } -@implementation ViewController + return self; +} -- (void)didReceiveMemoryWarning { +- (void)godot_commonInit { + // Initialize view controller values. +} +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; printf("*********** did receive memory warning!\n"); -}; +} - (void)viewDidLoad { [super viewDidLoad]; + [self observeKeyboard]; + [self displayLoadingOverlay]; + if (@available(iOS 11.0, *)) { [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; } } +- (void)observeKeyboard { + printf("******** setting up keyboard input view\n"); + self.keyboardView = [GodotKeyboardInputView new]; + [self.view addSubview:self.keyboardView]; + + printf("******** adding observer for keyboard show/hide\n"); + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardOnScreen:) + name:UIKeyboardDidShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardHidden:) + name:UIKeyboardDidHideNotification + object:nil]; +} + +- (void)displayLoadingOverlay { + NSBundle *bundle = [NSBundle mainBundle]; + NSString *storyboardName = @"Launch Screen"; + + if ([bundle pathForResource:storyboardName ofType:@"storyboardc"] == nil) { + return; + } + + UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:bundle]; + + UIViewController *controller = [launchStoryboard instantiateInitialViewController]; + self.godotLoadingOverlay = controller.view; + self.godotLoadingOverlay.frame = self.view.bounds; + self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + + [self.view addSubview:self.godotLoadingOverlay]; +} + +- (BOOL)godotViewFinishedSetup:(GodotView *)view { + [self.godotLoadingOverlay removeFromSuperview]; + self.godotLoadingOverlay = nil; + + return YES; +} + +- (void)dealloc { + [self.videoView stopVideo]; + + self.videoView = nil; + + self.keyboardView = nil; + + self.renderer = nil; + + if (self.godotLoadingOverlay) { + [self.godotLoadingOverlay removeFromSuperview]; + self.godotLoadingOverlay = nil; + } + + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +// MARK: Orientation + - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures { return UIRectEdgeAll; } - (BOOL)shouldAutorotate { - switch (OS::get_singleton()->get_screen_orientation()) { - case OS::SCREEN_SENSOR: - case OS::SCREEN_SENSOR_LANDSCAPE: - case OS::SCREEN_SENSOR_PORTRAIT: + if (!DisplayServerIPhone::get_singleton()) { + return NO; + } + + switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) { + case DisplayServer::SCREEN_SENSOR: + case DisplayServer::SCREEN_SENSOR_LANDSCAPE: + case DisplayServer::SCREEN_SENSOR_PORTRAIT: return YES; default: return NO; } -}; +} - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - switch (OS::get_singleton()->get_screen_orientation()) { - case OS::SCREEN_PORTRAIT: + if (!DisplayServerIPhone::get_singleton()) { + return UIInterfaceOrientationMaskAll; + } + + switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) { + case DisplayServer::SCREEN_PORTRAIT: return UIInterfaceOrientationMaskPortrait; - case OS::SCREEN_REVERSE_LANDSCAPE: + case DisplayServer::SCREEN_REVERSE_LANDSCAPE: return UIInterfaceOrientationMaskLandscapeRight; - case OS::SCREEN_REVERSE_PORTRAIT: + case DisplayServer::SCREEN_REVERSE_PORTRAIT: return UIInterfaceOrientationMaskPortraitUpsideDown; - case OS::SCREEN_SENSOR_LANDSCAPE: + case DisplayServer::SCREEN_SENSOR_LANDSCAPE: return UIInterfaceOrientationMaskLandscape; - case OS::SCREEN_SENSOR_PORTRAIT: + case DisplayServer::SCREEN_SENSOR_PORTRAIT: return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; - case OS::SCREEN_SENSOR: + case DisplayServer::SCREEN_SENSOR: return UIInterfaceOrientationMaskAll; - case OS::SCREEN_LANDSCAPE: + case DisplayServer::SCREEN_LANDSCAPE: return UIInterfaceOrientationMaskLandscapeLeft; } }; @@ -139,12 +223,42 @@ int add_cmdline(int p_argc, char **p_args) { } } -#ifdef GAME_CENTER_ENABLED -- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController { - //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone - GameCenter::get_singleton()->game_center_closed(); - [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; +// MARK: Keyboard + +- (void)keyboardOnScreen:(NSNotification *)notification { + NSDictionary *info = notification.userInfo; + NSValue *value = info[UIKeyboardFrameEndUserInfoKey]; + + CGRect rawFrame = [value CGRectValue]; + CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil]; + + if (DisplayServerIPhone::get_singleton()) { + DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height); + } +} + +- (void)keyboardHidden:(NSNotification *)notification { + if (DisplayServerIPhone::get_singleton()) { + DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(0); + } +} + +// MARK: Native Video Player + +- (BOOL)playVideoAtPath:(NSString *)filePath volume:(float)videoVolume audio:(NSString *)audioTrack subtitle:(NSString *)subtitleTrack { + // If we are showing some video already, reuse existing view for new video. + if (self.videoView) { + return [self.videoView playVideoAtPath:filePath volume:videoVolume audio:audioTrack subtitle:subtitleTrack]; + } else { + // Create autoresizing view for video playback. + GodotNativeVideoView *videoView = [[GodotNativeVideoView alloc] initWithFrame:self.view.bounds]; + videoView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.view addSubview:videoView]; + + self.videoView = videoView; + + return [self.videoView playVideoAtPath:filePath volume:videoVolume audio:audioTrack subtitle:subtitleTrack]; + } } -#endif @end |