diff --git a/Frameworks/StarboardXaml/ApplicationMain.mm b/Frameworks/StarboardXaml/ApplicationMain.mm index fd8e634bef..86ac1a705a 100644 --- a/Frameworks/StarboardXaml/ApplicationMain.mm +++ b/Frameworks/StarboardXaml/ApplicationMain.mm @@ -39,26 +39,6 @@ void SetCACompositorClient(CACompositorClientInterface* client) { _compositorClient = client; } -struct ApplicationProperties { - float width; - float height; - float scale; - std::string name; - bool isTablet; - bool isLandscape; -}; - -ApplicationProperties g_applicationProperties; - -std::string GetAppNameFromPList() { - NSString* appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]; - if (appName != nil) { - return [appName UTF8String]; - } - - return "Starboard"; -} - int ApplicationMainStart( int argc, char* argv[], const char* principalName, const char* delegateName, float windowWidth, float windowHeight) { // Note: We must use nil rather than an empty string for these class names @@ -68,11 +48,6 @@ int ApplicationMainStart( WOCDisplayMode* displayMode = [UIApplication displayMode]; [displayMode _setWindowSize:CGSizeMake(windowWidth, windowHeight)]; - float defaultWidth = GetCACompositor()->screenWidth(); - float defaultHeight = GetCACompositor()->screenHeight(); - float defaultScale = GetCACompositor()->screenScale(); - bool defaultTablet = false; - [NSBundle setMainBundlePath:@"."]; NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary]; @@ -124,14 +99,7 @@ int ApplicationMainStart( [UIApplication setStartupDisplayMode:displayMode]; } - g_applicationProperties.width = defaultWidth; - g_applicationProperties.height = defaultHeight; - g_applicationProperties.scale = defaultScale; - g_applicationProperties.name = GetAppNameFromPList(); - g_applicationProperties.isTablet = defaultTablet; - [displayMode _updateDisplaySettings]; - GetCACompositor()->setTablet(g_applicationProperties.isTablet); UIApplicationMainInit(argc, argv, principalClassName, delegateClassName, defaultOrientation); return UIApplicationMainLoop(); diff --git a/Frameworks/UIKit/UIApplication.mm b/Frameworks/UIKit/UIApplication.mm index da3d272774..f5995af564 100644 --- a/Frameworks/UIKit/UIApplication.mm +++ b/Frameworks/UIKit/UIApplication.mm @@ -2578,6 +2578,7 @@ - (void)_updateDisplaySettings { break; } + GetCACompositor()->setTablet(_operationMode == WOCOperationModeTablet); GetCACompositor()->setScreenSize(newWidth, newHeight, newMagnification, newRotation); GetCACompositor()->setDeviceSize(newWidth, newHeight); diff --git a/Frameworks/UIKit/UIViewController.mm b/Frameworks/UIKit/UIViewController.mm index 457e2b0090..b187cfbc36 100644 --- a/Frameworks/UIKit/UIViewController.mm +++ b/Frameworks/UIKit/UIViewController.mm @@ -343,15 +343,8 @@ - (CGRect)_orientationRect:(UIInterfaceOrientation)orientation { appFrame = [[UIScreen mainScreen] applicationFrame]; - if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - appFrame.size.width = 540; - appFrame.size.height = 575; - - appFrame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - appFrame.size.width / 2.0f; - appFrame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - appFrame.size.height / 2.0f; + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { + appFrame = [self _modalPresentationFormSheetFrame]; } CGRect rect; @@ -386,6 +379,35 @@ - (CGRect)_orientationRect:(UIInterfaceOrientation)orientation { return rect; } +- (CGRect)_modalPresentationFormSheetFrame { + if (!GetCACompositor()->isTablet()) { + // fullscreen on non-tablets + return [[UIScreen mainScreen] applicationFrame]; + } + + CGRect frame; + if (!CGSizeEqualToSize([self preferredContentSize], CGSizeZero)) { + frame.size = [self preferredContentSize]; + } else { + frame.size.width = 540; + frame.size.height = 620; + } + + CGRect screenFrame = [[UIScreen mainScreen] applicationFrame]; + frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; + frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + + return frame; +} + +- (BOOL)_hidesParent { + if ([self modalPresentationStyle] == UIModalPresentationFormSheet && GetCACompositor()->isTablet()) { + return NO; + } + + return YES; +} + - (void)_setResizeToScreen:(BOOL)resize { priv->_resizeToScreen = TRUE; } @@ -402,20 +424,13 @@ - (void)setOrientationInternal:(UIInterfaceOrientation)orientation animated:(BOO [[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:FALSE]; - if (priv->_wantsFullScreenLayout) { + if ([self wantsFullScreenLayout]) { appFrame = [[UIScreen mainScreen] bounds]; } else { appFrame = [[UIScreen mainScreen] applicationFrame]; } - if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - appFrame.size.width = GetCACompositor()->screenWidth(); - appFrame.size.height = GetCACompositor()->screenHeight(); - - appFrame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - appFrame.size.width / 2.0f; - appFrame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - appFrame.size.height / 2.0f; + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { + appFrame = [self _modalPresentationFormSheetFrame]; } switch (orientation) { @@ -786,15 +801,8 @@ - (void)loadView { CGRect frame = { 0.0f, 0.0f, GetCACompositor()->screenWidth(), GetCACompositor()->screenHeight() }; frame = [[UIScreen mainScreen] applicationFrame]; /** This is correct **/ - if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - frame.size.width = 540; - frame.size.height = 575; - - frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; - frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { + frame = [self _modalPresentationFormSheetFrame]; } UIView* view = [[[UIEmptyController alloc] initWithFrame:frame] autorelease]; @@ -807,24 +815,17 @@ - (void)loadView { } - (void)_doResizeToScreen { - if ((priv->_resizeToScreen && priv->view && priv->_autoresize) || priv->_wantsFullScreenLayout) { + if ((priv->_resizeToScreen && priv->view && priv->_autoresize) || [self wantsFullScreenLayout]) { CGRect frame = { 0.0f, 0.0f, GetCACompositor()->screenHeight(), GetCACompositor()->screenWidth() }; - if (priv->_wantsFullScreenLayout) { + if ([self wantsFullScreenLayout]) { frame = [[UIScreen mainScreen] bounds]; } else { frame = [[UIScreen mainScreen] applicationFrame]; } - if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - frame.size.width = 540; - frame.size.height = 575; - - frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; - frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { + frame = [self _modalPresentationFormSheetFrame]; } UIInterfaceOrientation curOrientation = (UIInterfaceOrientation)[[UIApplication sharedApplication] statusBarOrientation]; @@ -857,15 +858,8 @@ - (UIView*)view { CGRect frame = { 0.0f, 0.0f, GetCACompositor()->screenHeight(), GetCACompositor()->screenWidth() }; frame = [[UIScreen mainScreen] applicationFrame]; - if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - frame.size.width = 540; - frame.size.height = 575; - - frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; - frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { + frame = [self _modalPresentationFormSheetFrame]; } UIView* view = [[[UIEmptyController alloc] initWithFrame:frame] autorelease]; @@ -1046,7 +1040,7 @@ - (void)presentViewController:(UIViewController*)controller animated:(BOOL)anima if (curController->priv->_visibility != controllerNotVisible) { shouldShow = true; } - curController = curController->priv->_parentViewController; + curController = [curController parentViewController]; } if (!shouldShow) { TraceWarning(TAG, L"Controller is not visible!"); @@ -1069,7 +1063,9 @@ - (void)presentViewController:(UIViewController*)controller animated:(BOOL)anima [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; } - [self _notifyViewWillDisappear:animated]; + if ([controller _hidesParent]) { + [self _notifyViewWillDisappear:animated]; + } priv->_modalViewController = controller; priv->_presentedViewController = controller; @@ -1129,8 +1125,8 @@ - (void)_dismissTransitionStopped:(id)anim finished:(BOOL)finished { */ - (void)dismissViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion { if (priv->_modalViewController == nil) { - if (priv->_parentViewController) { - [priv->_parentViewController dismissViewControllerAnimated:animated completion:completion]; + if ([self parentViewController] != nil) { + [[self parentViewController] dismissViewControllerAnimated:animated completion:completion]; return; } TraceWarning(TAG, L"dismissModalViewController invalid!"); @@ -1225,7 +1221,9 @@ - (void)_notifyDidAppearAnimated:(UIView*)view { - (void)_transitionStopped:(id)context { UIView* view = [self view]; - [[priv->_parentViewController view] setHidden:TRUE]; + if ([self _hidesParent]) { + [[[self parentViewController] view] setHidden:TRUE]; + } [self _notifyDidAppearAnimated:view]; [[UIApplication sharedApplication] endIgnoringInteractionEvents]; } @@ -1235,18 +1233,18 @@ - (void)_addToTop:(NSNumber*)animatedValue { priv->_isRootView = true; - if (priv->_parentViewController != nil) { + if ([self parentViewController] != nil) { // TODO: This implementation satisfies the contract that the popoverPresentationController is not nil when presenting a // UIViewController with modalPresentationType equal to UIModalPresentationPopover. // The full implementation will need to utilize the UIPresentationController for UIViewController presentations - if (priv->_presentationStyle == UIModalPresentationPopover) { + if ([self modalPresentationStyle] == UIModalPresentationPopover) { if (priv->_popoverPresentationController != nil) { [priv->_popoverPresentationController release]; } priv->_popoverPresentationController = [[UIPopoverPresentationController alloc] initWithPresentedViewController:self - presentingViewController:priv->_parentViewController]; + presentingViewController:[self parentViewController]]; if (priv->_presentationController != nil) { [priv->_presentationController release]; @@ -1258,14 +1256,14 @@ - (void)_addToTop:(NSNumber*)animatedValue { float endY = 0; UIView* view = [self view]; - UIWindow* parentWindow = [[priv->_parentViewController view] window]; + UIWindow* parentWindow = [[[self parentViewController] view] window]; if (animated) { g_presentingAnimated = TRUE; [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; [self _notifyViewWillAppear:TRUE]; - } else { - [[priv->_parentViewController view] setHidden:TRUE]; + } else if ([self _hidesParent]) { + [[[self parentViewController] view] setHidden:TRUE]; } if (parentWindow != nil) { @@ -1331,7 +1329,9 @@ - (void)_addToTop:(NSNumber*)animatedValue { g_presentingAnimated = FALSE; } - [priv->_parentViewController _notifyViewDidDisappear:animated]; + if ([self _hidesParent]) { + [[self parentViewController] _notifyViewDidDisappear:animated]; + } } else { TraceVerbose(TAG, L"Modal controller doesn't have a parent!"); } @@ -1371,8 +1371,9 @@ - (BOOL)isModalInPopover { static UIInterfaceOrientation findOrientation(UIViewController* self) { UIInterfaceOrientation orientation = (UIInterfaceOrientation)[[UIDevice currentDevice] orientation]; - if (self->priv->_parentViewController != nil && [self->priv->_parentViewController _rotationLocked:orientation]) { - UIInterfaceOrientation parentOrientation = (UIInterfaceOrientation)[self->priv->_parentViewController interfaceOrientation]; + UIViewController* parent = [self parentViewController]; + if (parent != nil && [parent _rotationLocked:orientation]) { + UIInterfaceOrientation parentOrientation = (UIInterfaceOrientation)[parent interfaceOrientation]; if (parentOrientation != 0) { orientation = parentOrientation; } diff --git a/samples/WOCCatalog/WOCCatalog/ControlsViewController.m b/samples/WOCCatalog/WOCCatalog/ControlsViewController.m index b7e76bbcac..bd1ae3fbe5 100644 --- a/samples/WOCCatalog/WOCCatalog/ControlsViewController.m +++ b/samples/WOCCatalog/WOCCatalog/ControlsViewController.m @@ -17,7 +17,14 @@ #import "ControlsViewController.h" #import "PopoverViewController.h" -#define UIPOPOVERCONTROL_ROW 4 +static const int POPOVERCONTROL_ROW = 4; +static const int MODALFORMSHEET_ROW = 5; + +@interface ControlsViewController () + +@property (nonatomic) BOOL resizeModal; + +@end @implementation ControlsViewController @@ -25,8 +32,15 @@ - (void)viewDidLoad { [super viewDidLoad]; } +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:(BOOL)animated]; + + // UIModalPresentationFormSheet shouldn't cover parent with tablet. + assert(!([[self presentedViewController] modalPresentationStyle] == UIModalPresentationFormSheet && [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)); +} + - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { - return 5; + return 6; } - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath { @@ -96,18 +110,35 @@ - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSI cell.textLabel.text = @"UIProgressView"; cell.selectionStyle = UITableViewCellSelectionStyleNone; - } else if (indexPath.row == UIPOPOVERCONTROL_ROW) { + } else if (indexPath.row == POPOVERCONTROL_ROW) { // UIPopoverPresentationController - cell.textLabel.text = @"UIPopupPresentationController (press me)"; + cell.textLabel.text = @"UIPopupPresentationController (press to launch)"; cell.selectionStyle = UITableViewCellSelectionStyleBlue; + } else if (indexPath.row == MODALFORMSHEET_ROW) { + // form sheet modal + + UITableViewCell* subtitleCell = [tableView dequeueReusableCellWithIdentifier:@"MenuSubtitleCell"]; + if (!subtitleCell) { + subtitleCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MenuSubtitleCell"]; + } + + subtitleCell.textLabel.text = @"UIModalPresentationFormSheet (press to launch)"; + subtitleCell.detailTextLabel.text = @"Toggle switch to resize (tablet only)"; + subtitleCell.selectionStyle = UITableViewCellSelectionStyleBlue; + UISwitch* resizeSwitch = [[UISwitch alloc] init]; + resizeSwitch.on = self.resizeModal; + [resizeSwitch addTarget:self action:@selector(toggleResizeModal) forControlEvents:UIControlEventValueChanged]; + subtitleCell.accessoryView = resizeSwitch; + + return subtitleCell; } return cell; } - (NSIndexPath*)tableView:(UITableView*)tableView willSelectRowAtIndexPath:(NSIndexPath*)indexPath { - if (indexPath.row == UIPOPOVERCONTROL_ROW) { + if (indexPath.row == POPOVERCONTROL_ROW || indexPath.row == MODALFORMSHEET_ROW) { return indexPath; } @@ -115,7 +146,7 @@ - (NSIndexPath*)tableView:(UITableView*)tableView willSelectRowAtIndexPath:(NSIn } - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { - if (indexPath.row == UIPOPOVERCONTROL_ROW) { + if (indexPath.row == POPOVERCONTROL_ROW) { // Note: presenting a UIViewController with the UIModalPresentationStyle of Popover does not yet present the view controller // as a popover. UIPopoverController has been depricated in ios9.0. // This work will need to be completed as part of UIPopoverPresentationController work. @@ -133,7 +164,22 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*) presentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight; presentationController.sourceView = self.view; presentationController.sourceRect = CGRectMake(100, 100, 100, 100); + } else if (indexPath.row == MODALFORMSHEET_ROW) { + UIViewController* viewController = [[PopoverViewController alloc] initWithImage:[UIImage imageNamed:@"photo1.jpg"]]; + viewController.modalPresentationStyle = UIModalPresentationFormSheet; + + if (self.resizeModal) { + viewController.preferredContentSize = CGSizeMake(200, 200); + } + + [self presentViewController:viewController animated:YES completion:^{ + assert(!([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad && self.view.hidden)); + }]; } } +- (void)toggleResizeModal { + self.resizeModal = !self.resizeModal; +} + @end diff --git a/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m b/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m index d9e27b6ca0..df523d8181 100644 --- a/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m +++ b/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m @@ -37,6 +37,11 @@ - (void)toggleAdjustWindowSize:(UISwitch*)sender { [UIApplication.displayMode updateDisplaySettings]; } +- (void)toggleTabletMode:(UISwitch*)sender { + UIApplication.displayMode.operationMode = sender.on ? WOCOperationModeTablet : WOCOperationModePhone; + [UIApplication.displayMode updateDisplaySettings]; +} + - (void)toggleScreenAwake:(UISwitch*)sender { [[UIApplication sharedApplication] setIdleTimerDisabled:sender.on]; } @@ -262,6 +267,15 @@ - (id)init { cell.textLabel.text = @"Disable idle screen timer"; [self.rows addObject:cell]; + UISwitch* enableTabletMode = [UISwitch new]; + enableTabletMode.on = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad; + [enableTabletMode addTarget:self action:@selector(toggleTabletMode:) forControlEvents:UIControlEventValueChanged]; + + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MenuCell"]; + cell.accessoryView = enableTabletMode; + cell.textLabel.text = @"Tablet Mode"; + [self.rows addObject:cell]; + fixedWidth = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 20)]; fixedWidth.text = [NSString stringWithFormat:@"%.1f", UIApplication.displayMode.fixedWidth]; fixedWidth.borderStyle = UITextBorderStyleBezel; diff --git a/samples/WOCCatalog/WOCCatalog/PopoverViewController.m b/samples/WOCCatalog/WOCCatalog/PopoverViewController.m index dba17e3a81..22c883a43a 100644 --- a/samples/WOCCatalog/WOCCatalog/PopoverViewController.m +++ b/samples/WOCCatalog/WOCCatalog/PopoverViewController.m @@ -72,10 +72,12 @@ - (void)viewDidLoad { scrollView.maximumZoomScale = 1.; scrollView.minimumZoomScale = minimumScale; scrollView.zoomScale = minimumScale; + + imageView.center = CGPointMake(scrollView.contentSize.width * 0.5, scrollView.contentSize.height * 0.5); } - (void)createLayout { - [scrollView setBackgroundColor:[UIColor whiteColor]]; + [scrollView setBackgroundColor:[UIColor lightGrayColor]]; } - (void)scrollViewDidZoom:(UIScrollView*)aScrollView {