Qt 4.8
quikiteventloop.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "quikiteventloop.h"
43 #include "quikitintegration.h"
44 #include "quikitscreen.h"
45 #include "quikitwindow.h"
46 #include "quikitwindowsurface.h"
47 
48 #include <UIKit/UIKit.h>
49 
50 #include <QtGui/QApplication>
51 #include <QtGui/QWidget>
52 #include <QtGui/QGraphicsView>
53 #include <QtGui/QGraphicsScene>
54 #include <QtGui/QGraphicsItem>
55 #include <QtDebug>
56 
57 @interface QUIKitAppDelegate : NSObject <UIApplicationDelegate> {
58  UIInterfaceOrientation mOrientation;
59 }
60 
61 - (void)updateOrientation:(NSNotification *)notification;
62 
63 @end
64 
65 @interface EventLoopHelper : NSObject {
67 }
68 
69 - (id)initWithEventLoopIntegration:(QUIKitEventLoop *)integration;
70 
71 - (void)processEventsAndSchedule;
72 
73 @end
74 
75 @implementation QUIKitAppDelegate
76 
77 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
78 {
79  Q_UNUSED(launchOptions)
80  mOrientation = application.statusBarOrientation;
81  [self updateOrientation:nil];
82  if (QUIKitIntegration::instance()->screens().size() > 0) {
83  QUIKitScreen *screen = static_cast<QUIKitScreen *>(QUIKitIntegration::instance()->screens().at(0));
85  }
86  foreach (QWidget *widget, qApp->topLevelWidgets()) {
87  QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
88  if (platformWindow) platformWindow->ensureNativeWindow();
89  }
90  // orientation support
91  [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
92  [[NSNotificationCenter defaultCenter] addObserver:self
93  selector:@selector(updateOrientation:)
94  name:UIDeviceOrientationDidChangeNotification
95  object:nil];
96  return YES;
97 }
98 
99 - (void)updateOrientation:(NSNotification *)notification
100 {
101  Q_UNUSED(notification)
102  UIInterfaceOrientation newOrientation = mOrientation;
103  NSString *infoValue = @"";
104  switch ([UIDevice currentDevice].orientation) {
105  case UIDeviceOrientationUnknown:
106  break;
107  case UIDeviceOrientationPortrait:
108  newOrientation = UIInterfaceOrientationPortrait;
109  infoValue = @"UIInterfaceOrientationPortrait";
110  break;
111  case UIDeviceOrientationPortraitUpsideDown:
112  newOrientation = UIInterfaceOrientationPortraitUpsideDown;
113  infoValue = @"UIInterfaceOrientationPortraitUpsideDown";
114  break;
115  case UIDeviceOrientationLandscapeLeft:
116  newOrientation = UIInterfaceOrientationLandscapeRight; // as documentated
117  infoValue = @"UIInterfaceOrientationLandscapeRight";
118  break;
119  case UIDeviceOrientationLandscapeRight:
120  newOrientation = UIInterfaceOrientationLandscapeLeft; // as documentated
121  infoValue = @"UIInterfaceOrientationLandscapeLeft";
122  break;
123  case UIDeviceOrientationFaceUp:
124  case UIDeviceOrientationFaceDown:
125  break;
126  }
127 
128  if (newOrientation == mOrientation)
129  return;
130 
131  // check against supported orientations
132  NSBundle *bundle = [NSBundle mainBundle];
133  NSArray *orientations = [bundle objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"];
134  if (![orientations containsObject:infoValue])
135  return;
136 
137  mOrientation = newOrientation;
138  [UIApplication sharedApplication].statusBarOrientation = mOrientation;
139  if (QUIKitIntegration::instance()->screens().size() > 0) {
140  QUIKitScreen *screen = static_cast<QUIKitScreen *>(QUIKitIntegration::instance()->screens().at(0));
141  screen->updateInterfaceOrientation();
142  }
143 }
144 
145 - (void)applicationWillTerminate:(UIApplication *)application
146 {
147  Q_UNUSED(application)
148  qApp->quit();
149 }
150 
151 @end
152 
153 @implementation EventLoopHelper
154 
155 - (id)initWithEventLoopIntegration:(QUIKitEventLoop *)integration
156 {
157  if ((self = [self init])) {
158  mIntegration = integration;
159  }
160  return self;
161 }
162 
164 {
166  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
167  NSDate *nextDate = [[NSDate date] dateByAddingTimeInterval:((double)mIntegration->nextTimerEvent()/1000.)];
168  [mIntegration->mTimer setFireDate:nextDate];
169  [pool release];
170 }
171 
172 @end
173 
175 
177 {
178  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
179  mInputHandler = new QUIKitSoftwareInputHandler;
180  mHelper = [[EventLoopHelper alloc] initWithEventLoopIntegration:this];
181  mTimer = [[NSTimer timerWithTimeInterval:0.030 target:mHelper selector:@selector(processEventsAndSchedule) userInfo:nil repeats:YES] retain];
182  [pool release];
183 }
184 
186 {
187  [mTimer release];
188  [mHelper release];
189  delete mInputHandler;
190 }
191 
193 {
194  qApp->installEventFilter(mInputHandler);
195  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
196  [[NSRunLoop currentRunLoop] addTimer:[mTimer autorelease] forMode:NSDefaultRunLoopMode];
197  UIApplicationMain(qApp->argc(), qApp->argv(), nil, @"QUIKitAppDelegate");
198  [pool release];
199 }
200 
202 {
203 
204 }
205 
207 {
208  [mHelper performSelectorOnMainThread:@selector(processEventsAndSchedule) withObject:nil waitUntilDone:NO];
209 }
210 
211 static UIReturnKeyType keyTypeForObject(QObject *obj)
212 {
213  if (strcmp(obj->metaObject()->className(), "QDeclarativeTextEdit") == 0)
214  return UIReturnKeyDefault;
215  return UIReturnKeyDone;
216 }
217 
219 {
220  if (event->type() == QEvent::RequestSoftwareInputPanel) {
221  UIReturnKeyType returnKeyType = UIReturnKeyDone;
222  if (QGraphicsView *declarativeView = qobject_cast<QGraphicsView *>(obj)) {
223  // register on loosing the focus, so we can auto-remove the input panel again
224  QGraphicsScene *scene = declarativeView->scene();
225  if (scene) {
226  if (mCurrentFocusObject)
227  disconnect(mCurrentFocusObject, 0, this, SLOT(activeFocusChanged(bool)));
228  QObject *focus = dynamic_cast<QObject *>(scene->focusItem());
229  mCurrentFocusObject = focus;
230  if (focus) {
231  connect(mCurrentFocusObject, SIGNAL(activeFocusChanged(bool)), this, SLOT(activeFocusChanged(bool)));
232  returnKeyType = keyTypeForObject(mCurrentFocusObject);
233  }
234  }
235  }
236  QWidget *widget = qobject_cast<QWidget *>(obj);
237  if (widget) {
238  mCurrentFocusWidget = widget;
239  QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->window()->platformWindow());
240  if (platformWindow) {
241  platformWindow->nativeView().returnKeyType = returnKeyType;
242  [platformWindow->nativeView() becomeFirstResponder];
243  }
244  return true;
245  }
246  } else if (event->type() == QEvent::CloseSoftwareInputPanel) {
247  QWidget *widget = qobject_cast<QWidget *>(obj);
248  return closeSoftwareInputPanel(widget);
249  }
250  return false;
251 }
252 
254 {
255  if (widget) {
256  QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->window()->platformWindow());
257  if (platformWindow) {
258  [platformWindow->nativeView() resignFirstResponder];
259  mCurrentFocusWidget = 0;
260  if (mCurrentFocusObject)
261  disconnect(mCurrentFocusObject, 0, this, SLOT(activeFocusChanged(bool)));
262  mCurrentFocusObject = 0;
263  }
264  return true;
265  }
266  return false;
267 }
268 
270 {
271  if (!focus && mCurrentFocusWidget && mCurrentFocusObject) {
272  closeSoftwareInputPanel(mCurrentFocusWidget);
273  }
274 }
275 
T qobject_cast(QObject *object)
Definition: qobject.h:375
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items...
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
EventRef event
QPointer< QWidget > widget
UIWindow * ensureNativeWindow()
#define SLOT(a)
Definition: qobjectdefs.h:226
void activeFocusChanged(bool focus)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
EAGLView * nativeView() const
Definition: quikitwindow.h:116
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
bool closeSoftwareInputPanel(QWidget *widget)
QList< QPlatformScreen * > screens() const
Accessor function to a list of all the screens on the current system.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
static UIReturnKeyType keyTypeForObject(QObject *obj)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QGraphicsItem * focusItem() const
When the scene is active, this functions returns the scene&#39;s current focus item, or 0 if no item curr...
#define qApp
static bool init
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void updateInterfaceOrientation()
Definition: quikitscreen.mm:90
UIInterfaceOrientation mOrientation
QUIKitEventLoop * mIntegration
void qtNeedsToProcessEvents()
UIReturnKeyType returnKeyType
Definition: quikitwindow.h:72
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
static QUIKitIntegration * instance()
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
Definition: qgraphicsview.h:64
EventLoopHelper * mHelper
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
bool eventFilter(QObject *obj, QEvent *event)
Filters events if this object has been installed as an event filter for the watched object...