28 |
28 |
29 #include <QGraphicsView> |
29 #include <QGraphicsView> |
30 #include <QGraphicsWidget> |
30 #include <QGraphicsWidget> |
31 #include <QGraphicsItem> |
31 #include <QGraphicsItem> |
32 #include <QGraphicsScene> |
32 #include <QGraphicsScene> |
33 |
33 #include <QApplication> |
34 #include "hbaction.h" |
34 #include "hbaction.h" |
35 #include "hbbackgrounditem_p.h" |
35 #include "hbbackgrounditem_p.h" |
|
36 #include "hbscreenshotitem_p.h" |
36 #include "hbdeviceprofile_p.h" |
37 #include "hbdeviceprofile_p.h" |
37 #include "hbindicatorgroup_p.h" |
38 #include "hbindicatorgroup_p.h" |
38 #include "hbinstance.h" |
39 #include "hbinstance.h" |
39 #include "hbinstance_p.h" |
40 #include "hbinstance_p.h" |
40 #include "hbgraphicsscene.h" |
41 #include "hbgraphicsscene.h" |
61 #include "hbmainwindoworientation_p.h" |
62 #include "hbmainwindoworientation_p.h" |
62 #include "hbfeaturemanager_r.h" |
63 #include "hbfeaturemanager_r.h" |
63 #include "hboogmwatcher_p.h" |
64 #include "hboogmwatcher_p.h" |
64 #include "hbwindowobscured_p.h" |
65 #include "hbwindowobscured_p.h" |
65 #include "hbsleepmodelistener_p.h" |
66 #include "hbsleepmodelistener_p.h" |
|
67 #include "hbforegroundwatcher_p.h" |
66 |
68 |
67 #ifdef Q_OS_SYMBIAN |
69 #ifdef Q_OS_SYMBIAN |
68 #include <coecntrl.h> |
70 #include <coecntrl.h> |
69 #include <w32std.h> |
71 #include <w32std.h> |
|
72 #include <e32property.h> |
70 #include "hbnativewindow_sym_p.h" |
73 #include "hbnativewindow_sym_p.h" |
71 #endif |
74 #endif |
72 |
75 |
73 /*! |
76 /*! |
74 @stable |
77 @stable |
261 (so we won't waste time with that). |
264 (so we won't waste time with that). |
262 |
265 |
263 \internal |
266 \internal |
264 */ |
267 */ |
265 |
268 |
|
269 #ifdef Q_OS_SYMBIAN |
|
270 // When defined, the surface for the HbMainWindow is made transparent upon |
|
271 // showing, until the 3rd phase construction is done, to prevent |
|
272 // flickering. However it will also check wsini.ini for a line containing |
|
273 // [tfxrenderstage] and disable the workaround when such a line is present (the |
|
274 // workaround should not be needed when system tfx is enabled). |
|
275 // |
|
276 // When system tfx is known to be enabled permanently, the following define can |
|
277 // be commented out or removed. |
|
278 #define HB_SPLASH_FLICKER_WORKAROUND |
|
279 #endif |
|
280 |
266 class HbRootItem : public HbWidget |
281 class HbRootItem : public HbWidget |
267 { |
282 { |
268 public: |
283 public: |
269 explicit HbRootItem(QGraphicsItem *parent = 0); |
284 explicit HbRootItem(QGraphicsItem *parent = 0); |
270 ~HbRootItem() {} |
285 ~HbRootItem() {} |
285 Q_D(HbMainWindow); |
300 Q_D(HbMainWindow); |
286 d->q_ptr = this; |
301 d->q_ptr = this; |
287 |
302 |
288 // No need for any default (e.g. blank white) background for this window. |
303 // No need for any default (e.g. blank white) background for this window. |
289 setAttribute(Qt::WA_NoSystemBackground); |
304 setAttribute(Qt::WA_NoSystemBackground); |
|
305 viewport()->setAttribute(Qt::WA_NoSystemBackground); |
290 setOptimizationFlag(QGraphicsView::DontSavePainterState); |
306 setOptimizationFlag(QGraphicsView::DontSavePainterState); |
291 |
307 |
292 // Continue with basic initialization. Note: Prefer doing everything that is |
308 // Continue with basic initialization. Note: Prefer doing everything that is |
293 // not absolutely compulsory in _q_delayedConstruction instead. |
309 // not absolutely compulsory in _q_delayedConstruction instead. |
294 |
310 |
324 } else { |
340 } else { |
325 d->mOrientation = d->mDefaultOrientation; |
341 d->mOrientation = d->mDefaultOrientation; |
326 d->mAutomaticOrientationSwitch = false; |
342 d->mAutomaticOrientationSwitch = false; |
327 } |
343 } |
328 |
344 |
329 #if defined(Q_WS_S60) || defined(HB_Q_WS_MAEMO) |
345 #if defined(Q_OS_SYMBIAN) || defined(HB_Q_WS_MAEMO) |
330 setWindowState(Qt::WindowFullScreen); |
346 setWindowState(Qt::WindowFullScreen); |
331 #endif//Q_WS_S60 |
347 #endif |
332 |
348 |
333 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); |
349 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); |
334 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); |
350 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); |
335 setFrameStyle(QFrame::NoFrame); |
351 setFrameStyle(QFrame::NoFrame); |
336 |
352 |
353 d->addBackgroundItem(); |
369 d->addBackgroundItem(); |
354 } |
370 } |
355 |
371 |
356 // add clipping item |
372 // add clipping item |
357 d->mClippingItem = new HbScreen; |
373 d->mClippingItem = new HbScreen; |
|
374 // Makes sure clipingItem layout is activated before any of its child items. |
|
375 QApplication::postEvent(d->mClippingItem, new QEvent(QEvent::LayoutRequest)); |
358 d->mClippingItem->setParentItem(d->mRootItem); |
376 d->mClippingItem->setParentItem(d->mRootItem); |
359 d->mClippingItem->setZValue(HbPrivate::ContentZValue); |
377 d->mClippingItem->setZValue(HbPrivate::ContentZValue); |
360 |
378 |
361 // create content (stacked) widget |
379 // Create content (stacked) widget as a child of the HbScreen. Its size, |
|
380 // position, etc. will be managed by the clipping item (HbScreen). |
362 d->mViewStackWidget = new HbContentWidget(this, d->mClippingItem); |
381 d->mViewStackWidget = new HbContentWidget(this, d->mClippingItem); |
363 d->mEffectItem = d->mViewStackWidget; |
382 d->mEffectItem = d->mViewStackWidget; |
364 d->mClippingItem->setStackWidget(d->mViewStackWidget); |
383 d->mClippingItem->setStackWidget(d->mViewStackWidget); |
365 connect(d->mViewStackWidget, SIGNAL(currentChanged(int)), |
384 connect(d->mViewStackWidget, SIGNAL(currentChanged(int)), |
366 this, SLOT(_q_viewChanged())); |
385 this, SLOT(_q_viewChanged())); |
396 HbOogmWatcher::instance(); |
415 HbOogmWatcher::instance(); |
397 |
416 |
398 // Make sure the sleep mode listener instance is created. |
417 // Make sure the sleep mode listener instance is created. |
399 HbSleepModeListener::instance(); |
418 HbSleepModeListener::instance(); |
400 |
419 |
|
420 // Have also the foregroundwatcher up and running. |
|
421 HbForegroundWatcher::instance(); |
|
422 |
401 HbWindowObscured::installWindowEventFilter(); |
423 HbWindowObscured::installWindowEventFilter(); |
402 |
424 |
403 #ifdef HB_GESTURE_FW |
425 #ifdef HB_GESTURE_FW |
404 // @todo remove after view auto-subscribes to gestures |
426 // @todo remove after view auto-subscribes to gestures |
405 viewport()->grabGesture(Qt::TapGesture); |
427 viewport()->grabGesture(Qt::TapGesture); |
434 // QWidget dtor already initiates some shutdown activities. |
456 // QWidget dtor already initiates some shutdown activities. |
435 HbEffectInternal::safeCancelAll(); |
457 HbEffectInternal::safeCancelAll(); |
436 |
458 |
437 HbInstancePrivate::d_ptr()->removeWindow(this); |
459 HbInstancePrivate::d_ptr()->removeWindow(this); |
438 delete d_ptr; |
460 delete d_ptr; |
439 |
|
440 // to workaround problem when creating/destroying multiple hbmainwindow's in unit tests (win env) |
|
441 #ifdef Q_OS_WIN |
|
442 destroy(); |
|
443 #endif |
|
444 } |
461 } |
445 |
462 |
446 /*! |
463 /*! |
447 Adds a \a widget to the HbMainWindow object. Passing 0 in |
464 Adds a \a widget to the HbMainWindow object. Passing 0 in |
448 \a widget creates an empty HbView. |
465 \a widget creates an empty HbView. |
629 Q_D(HbMainWindow); |
646 Q_D(HbMainWindow); |
630 HbView *oldView = currentView(); |
647 HbView *oldView = currentView(); |
631 // Switching to null view or to the one that is current will do nothing. |
648 // Switching to null view or to the one that is current will do nothing. |
632 if (view && oldView != view) { |
649 if (view && oldView != view) { |
633 emit aboutToChangeView(oldView, view); |
650 emit aboutToChangeView(oldView, view); |
|
651 if (isObscured()) { |
|
652 animate = false; |
|
653 } |
634 if (oldView && animate) { |
654 if (oldView && animate) { |
635 if (flags & Hb::ViewSwitchFullScreen) { |
655 if (flags & Hb::ViewSwitchFullScreen) { |
636 flags |= Hb::ViewSwitchSequential; |
656 flags |= Hb::ViewSwitchSequential; |
637 } |
657 } |
638 if (flags & Hb::ViewSwitchUseBackAnim) { |
658 if (flags & Hb::ViewSwitchUseBackAnim) { |
936 if (currentView()) { |
956 if (currentView()) { |
937 action = currentView()->navigationAction(); |
957 action = currentView()->navigationAction(); |
938 } |
958 } |
939 event->accept(); |
959 event->accept(); |
940 break; |
960 break; |
|
961 |
|
962 #ifdef __WINSCW__ |
|
963 // Support for testing orientation change on the winscw emulator: When enabled, |
|
964 // pressing '9' will toggle (and force) the orientation. |
|
965 case Qt::Key_9: |
|
966 if (QFile::exists("c:/resource/hb_ori_simu")) { |
|
967 if (orientation() == Qt::Horizontal) { |
|
968 setOrientation(Qt::Vertical); |
|
969 } else { |
|
970 setOrientation(Qt::Horizontal); |
|
971 } |
|
972 } |
|
973 QGraphicsView::keyPressEvent(event); |
|
974 break; |
|
975 #endif |
941 |
976 |
942 default: |
977 default: |
943 QGraphicsView::keyPressEvent(event); |
978 QGraphicsView::keyPressEvent(event); |
944 break; |
979 break; |
945 } |
980 } |
980 setSceneRect(0, 0, newSize.width(), newSize.height()); |
1015 setSceneRect(0, 0, newSize.width(), newSize.height()); |
981 d->mClippingItem->resize(newSize); |
1016 d->mClippingItem->resize(newSize); |
982 if (d->mBgItem) { |
1017 if (d->mBgItem) { |
983 d->mBgItem->resize(newSize); |
1018 d->mBgItem->resize(newSize); |
984 } |
1019 } |
985 } |
1020 if (d->mScreenshotItem) { |
986 } |
1021 d->mScreenshotItem->resize(newSize); |
|
1022 } |
|
1023 } |
|
1024 } |
|
1025 |
|
1026 #ifdef HB_SPLASH_FLICKER_WORKAROUND |
|
1027 static bool tfxRenderStagePresent() |
|
1028 { |
|
1029 // Cannot afford to read wsini.ini in every app, let themeserver |
|
1030 // do it once and use the property published by it. |
|
1031 static int wsini_has_tfxrenderstage = -1; |
|
1032 if (wsini_has_tfxrenderstage == -1) { |
|
1033 wsini_has_tfxrenderstage = 0; |
|
1034 TInt v = -1; |
|
1035 if (RProperty::Get(TUid::Uid(0x20022E82), 0x746678, v) == KErrNone) { |
|
1036 wsini_has_tfxrenderstage = v; |
|
1037 } |
|
1038 } |
|
1039 return wsini_has_tfxrenderstage == 1; |
|
1040 } |
|
1041 #endif |
987 |
1042 |
988 /*! |
1043 /*! |
989 Reimplemented from QObject::customEvent(). |
1044 Reimplemented from QObject::customEvent(). |
990 */ |
1045 */ |
991 void HbMainWindow::customEvent(QEvent *event) |
1046 void HbMainWindow::customEvent(QEvent *event) |
998 // create the test utility |
1053 // create the test utility |
999 if (!d->mTheTestUtility) { |
1054 if (!d->mTheTestUtility) { |
1000 d->mTheTestUtility = new HbTheTestUtility(this); |
1055 d->mTheTestUtility = new HbTheTestUtility(this); |
1001 } |
1056 } |
1002 } |
1057 } |
1003 #ifdef Q_OS_SYMBIAN |
1058 #ifdef HB_SPLASH_FLICKER_WORKAROUND |
1004 // Disable surface transparency unless we were really asked to be transparent. |
1059 // Disable surface transparency unless we were really asked to be transparent. |
1005 // Must be done before destroying the splash screen widget. |
1060 // Must be done before destroying the splash screen widget. |
1006 if (!testAttribute(Qt::WA_TranslucentBackground)) { |
1061 if (!tfxRenderStagePresent() && !testAttribute(Qt::WA_TranslucentBackground)) { |
1007 RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow()); |
1062 RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow()); |
1008 window->SetSurfaceTransparency(false); |
1063 window->SetSurfaceTransparency(false); |
1009 } |
1064 } |
1010 #endif |
1065 #endif |
1011 // Get rid of the splash screen widget. (it is not visible to the user anyway at this point) |
1066 // Get rid of the splash screen widget. (it is not visible to the user anyway at this point) |
1074 QGraphicsView::paintEvent(event); |
1129 QGraphicsView::paintEvent(event); |
1075 } |
1130 } |
1076 |
1131 |
1077 void HbMainWindow::showEvent(QShowEvent *event) |
1132 void HbMainWindow::showEvent(QShowEvent *event) |
1078 { |
1133 { |
1079 #ifdef Q_OS_SYMBIAN |
1134 #ifdef HB_SPLASH_FLICKER_WORKAROUND |
1080 // Enable surface transparency if QWidget did not do it already. This is a |
1135 // Enable surface transparency if QWidget did not do it already. This is a |
1081 // workaround for having non-transparent surfaces filled automatically with |
1136 // workaround for having non-transparent surfaces filled automatically with |
1082 // black color. The showEvent is a suitable place because the native control |
1137 // black color. The showEvent is a suitable place because the native control |
1083 // is already created at this point, but it is not too late either. |
1138 // is already created at this point, but it is not too late either. Note |
1084 if (!testAttribute(Qt::WA_TranslucentBackground)) { |
1139 // that while this is meant to be a workaround, the system transition |
|
1140 // effects may actually rely on (and require) this behavior. |
|
1141 if (!tfxRenderStagePresent() && !testAttribute(Qt::WA_TranslucentBackground)) { |
|
1142 // The Qt::WA_TranslucentBackground attribute cannot be used here |
|
1143 // because that can only be enabled, disabling does not seem to be |
|
1144 // supported. |
1085 RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow()); |
1145 RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow()); |
1086 window->SetSurfaceTransparency(true); |
1146 window->SetSurfaceTransparency(true); |
1087 } |
1147 } |
1088 #endif |
1148 #endif |
1089 |
1149 |
1129 |
1189 |
1130 return d->mObscuredState; |
1190 return d->mObscuredState; |
1131 } |
1191 } |
1132 |
1192 |
1133 /* |
1193 /* |
1134 // reimplemented from QWidget |
1194 \reimp |
1135 */ |
1195 */ |
1136 bool HbMainWindow::event(QEvent *event) |
1196 bool HbMainWindow::event(QEvent *event) |
1137 { |
1197 { |
1138 Q_D(HbMainWindow); |
1198 Q_D(HbMainWindow); |
1139 if (event->type() == HbEvent::WindowObscuredChanged) { |
1199 if (event->type() == HbEvent::WindowObscuredChanged) { |
1140 HbWindowObscuredChangedEvent *wosEvent = static_cast<HbWindowObscuredChangedEvent *>(event); |
1200 HbWindowObscuredChangedEvent *wosEvent = static_cast<HbWindowObscuredChangedEvent *>(event); |
1141 d->setObscuredState(wosEvent->obscuredState()); |
1201 d->setObscuredState(wosEvent->obscuredState()); |
1142 } |
1202 } |
1143 return QGraphicsView::event(event); |
1203 return QGraphicsView::event(event); |
|
1204 } |
|
1205 |
|
1206 /* |
|
1207 \reimp |
|
1208 */ |
|
1209 void HbMainWindow::drawBackground(QPainter *painter, const QRectF &rect) |
|
1210 { |
|
1211 QGraphicsView::drawBackground(painter, rect); |
|
1212 // The background item's paint() does not get called automatically so call |
|
1213 // it directly and optimize it by setting a proper clipping rectangle. |
|
1214 Q_D(HbMainWindow); |
|
1215 if (d->mBgItem) { |
|
1216 bool restoreState = false; |
|
1217 if (d->mBgItem->imageMode() != Hb::DoNotDrawBackground && |
|
1218 (!qFuzzyCompare(rect.height(), d->mBgItem->boundingRect().height()) || |
|
1219 !qFuzzyCompare(rect.width(), d->mBgItem->boundingRect().width()))) { |
|
1220 //Need to save the state since some widget in scene could apply a smaller |
|
1221 //clip than this |
|
1222 restoreState = true; |
|
1223 painter->save(); |
|
1224 painter->setClipRect(rect); |
|
1225 } |
|
1226 d->mBgItem->paint(painter, 0, 0); |
|
1227 if (restoreState) { |
|
1228 painter->restore(); |
|
1229 } |
|
1230 } |
1144 } |
1231 } |
1145 |
1232 |
1146 HbRootItem::HbRootItem(QGraphicsItem *parent) |
1233 HbRootItem::HbRootItem(QGraphicsItem *parent) |
1147 : HbWidget(parent) |
1234 : HbWidget(parent) |
1148 { |
1235 { |