iOS: Let QScreen manage UIWindow and root view-controller

Instead of having the application delegate set up a UIWindow and root
view-controller, we move the responsibility to QScreen, since in a multi
screen scenario we will need one UIWindow per screen, as well as one
root viewcontroller per window.

Change-Id: If5b0d44b8f8a697d830b33b4fe420bff56a7629b
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
This commit is contained in:
Tor Arne Vestbø 2014-07-04 15:03:43 +02:00
parent 3770f4b148
commit 66c47292bd
7 changed files with 64 additions and 54 deletions

View File

@ -45,7 +45,4 @@
#import "qiosviewcontroller.h"
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@ -52,40 +52,6 @@
@implementation QIOSApplicationDelegate
@synthesize window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
Q_UNUSED(application);
Q_UNUSED(launchOptions);
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease];
#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_7_0)
QSysInfo::MacVersion iosVersion = QSysInfo::MacintoshVersion;
// We prefer to keep the root viewcontroller in fullscreen layout, so that
// we don't have to compensate for the viewcontroller position. This also
// gives us the same behavior on iOS 5/6 as on iOS 7, where full screen layout
// is the only way.
if (iosVersion < QSysInfo::MV_IOS_7_0)
self.window.rootViewController.wantsFullScreenLayout = YES;
// Use translucent statusbar by default on iOS6 iPhones (unless the user changed
// the default in the Info.plist), so that windows placed under the stausbar are
// still visible, just like on iOS7.
if (iosVersion >= QSysInfo::MV_IOS_6_0 && iosVersion < QSysInfo::MV_IOS_7_0
&& [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone
&& [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault)
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];
#endif
self.window.hidden = NO;
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
Q_UNUSED(application);
@ -103,11 +69,5 @@
return iosServices->handleUrl(QUrl::fromNSURL(url));
}
- (void)dealloc
{
[window release];
[super dealloc];
}
@end

View File

@ -72,7 +72,7 @@ QIOSIntegration *QIOSIntegration::instance()
QIOSIntegration::QIOSIntegration()
: m_fontDatabase(new QCoreTextFontDatabase)
, m_clipboard(new QIOSClipboard)
, m_inputContext(new QIOSInputContext)
, m_inputContext(0)
, m_platformServices(new QIOSServices)
, m_accessibility(0)
{
@ -91,6 +91,9 @@ QIOSIntegration::QIOSIntegration()
for (UIScreen *screen in [UIScreen screens])
addScreen(new QIOSScreen(screen));
// Depends on a primary screen being present
m_inputContext = new QIOSInputContext;
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition);

View File

@ -80,6 +80,7 @@ public slots:
private:
UIScreen *m_uiScreen;
UIWindow *m_uiWindow;
QRect m_geometry;
QRect m_availableGeometry;
int m_depth;

View File

@ -181,8 +181,28 @@ static QString deviceModelIdentifier()
QIOSScreen::QIOSScreen(UIScreen *screen)
: QPlatformScreen()
, m_uiScreen(screen)
, m_uiWindow(0)
, m_orientationListener(0)
{
for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) {
if (existingWindow.screen == m_uiScreen) {
m_uiWindow = [m_uiWindow retain];
break;
}
}
if (!m_uiWindow) {
// Create a window and associated view-controller that we can use
m_uiWindow = [[UIWindow alloc] initWithFrame:[m_uiScreen bounds]];
m_uiWindow.rootViewController = [[[QIOSViewController alloc] initWithQIOSScreen:this] autorelease];
// FIXME: Only do once windows are added to the screen, and for any screen
if (screen == [UIScreen mainScreen]) {
m_uiWindow.screen = m_uiScreen;
m_uiWindow.hidden = NO;
}
}
if (screen == [UIScreen mainScreen]) {
QString deviceIdentifier = deviceModelIdentifier();
@ -213,17 +233,12 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
QIOSScreen::~QIOSScreen()
{
[m_orientationListener release];
[m_uiWindow release];
}
void QIOSScreen::updateProperties()
{
UIWindow *uiWindow = 0;
for (uiWindow in [[UIApplication sharedApplication] windows]) {
if (uiWindow.screen == m_uiScreen)
break;
}
bool inPortrait = UIInterfaceOrientationIsPortrait(uiWindow.rootViewController.interfaceOrientation);
bool inPortrait = UIInterfaceOrientationIsPortrait(m_uiWindow.rootViewController.interfaceOrientation);
QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds).toRect()
: QRect(m_uiScreen.bounds.origin.x, m_uiScreen.bounds.origin.y,
m_uiScreen.bounds.size.height, m_uiScreen.bounds.size.width);

View File

@ -41,7 +41,13 @@
#import <UIKit/UIKit.h>
@interface QIOSViewController : UIViewController
class QIOSScreen;
@interface QIOSViewController : UIViewController {
QIOSScreen *m_screen;
}
- (id)initWithQIOSScreen:(QIOSScreen *)screen;
- (BOOL)prefersStatusBarHidden;
@end

View File

@ -53,6 +53,35 @@
@implementation QIOSViewController
- (id)initWithQIOSScreen:(QIOSScreen *)screen
{
if (self = [self init]) {
m_screen = screen;
#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_7_0)
QSysInfo::MacVersion iosVersion = QSysInfo::MacintoshVersion;
// We prefer to keep the root viewcontroller in fullscreen layout, so that
// we don't have to compensate for the viewcontroller position. This also
// gives us the same behavior on iOS 5/6 as on iOS 7, where full screen layout
// is the only way.
if (iosVersion < QSysInfo::MV_IOS_7_0)
self.wantsFullScreenLayout = YES;
// Use translucent statusbar by default on iOS6 iPhones (unless the user changed
// the default in the Info.plist), so that windows placed under the stausbar are
// still visible, just like on iOS7.
if (screen->uiScreen() == [UIScreen mainScreen]
&& iosVersion >= QSysInfo::MV_IOS_6_0 && iosVersion < QSysInfo::MV_IOS_7_0
&& [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone
&& [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault)
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];
#endif
}
return self;
}
-(BOOL)shouldAutorotate
{
// Until a proper orientation and rotation API is in place, we always auto rotate.
@ -85,8 +114,7 @@
if (!QCoreApplication::instance())
return; // FIXME: Store orientation for later (?)
QIOSScreen *qiosScreen = static_cast<QIOSScreen *>(QGuiApplication::primaryScreen()->handle());
qiosScreen->updateProperties();
m_screen->updateProperties();
}
#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0)