src/hbcore/gui/hbcontentwidget.cpp
changeset 21 4633027730f5
parent 7 923ff622b8b9
child 28 b7da29130b0e
--- a/src/hbcore/gui/hbcontentwidget.cpp	Tue Jul 06 14:36:53 2010 +0300
+++ b/src/hbcore/gui/hbcontentwidget.cpp	Wed Aug 18 10:05:37 2010 +0300
@@ -30,6 +30,7 @@
 #include "hbeffectinternal_p.h"
 #include "hbwidgetfeedback.h"
 #include "hbscreen_p.h"
+#include "hbscreenshotitem_p.h"
 #include <QEvent>
 #include <QGraphicsSceneMouseEvent>
 
@@ -42,6 +43,10 @@
   \internal
 */
 
+// An internal view switch flag, it is used to indicate the type of
+// the effect (show/hide) to getEffectTarget.
+const int Hiding = 0x1000000;
+
 HbContentWidget::HbContentWidget(HbMainWindow *mainWindow, QGraphicsItem *parent /*= 0*/):
     HbStackedWidget(parent),
     mViewSwitchRunning(false),
@@ -129,8 +134,9 @@
     // the effect target.
     QGraphicsWidget *viewWidget = view->widget();
     QGraphicsWidget *effectTarget = viewWidget ? viewWidget : view;
+    HbMainWindowPrivate *mwd = HbMainWindowPrivate::d_ptr(mMainWindow);
     if (flags & Hb::ViewSwitchFullScreen) {
-        effectTarget = HbMainWindowPrivate::d_ptr(mMainWindow)->mClippingItem;
+        effectTarget = mwd->mClippingItem;
         if (!(flags & Hb::ViewSwitchSequential)) {
             // The Parallel+FullScreen combination does not make sense
             // (e.g. cannot animate the one and only titlebar
@@ -138,6 +144,15 @@
             qWarning("HbMainWindow: parallel fullscreen view switch is not supported");
             effectTarget = 0;
         }
+    } else if (flags & Hb::ViewSwitchCachedFullScreen) {
+        // This version supports sequential effects too, but in the
+        // hiding case the effect must run on the special graphics
+        // item that will show a screenshot of the mainwindow.
+        if (flags & Hiding) {
+            effectTarget = mwd->screenshotItem();
+        } else {
+            effectTarget = mwd->mClippingItem;
+        }
     }
     return effectTarget;
 }
@@ -152,6 +167,13 @@
     // of the effect or this notification), the item is hidden properly before
     // resetting the transform etc. and thus there is no flicker.
     mHidingView->setVisible(false);
+    if (mViewSwitchFlags & Hb::ViewSwitchCachedFullScreen) {
+        HbMainWindowPrivate *mwd = HbMainWindowPrivate::d_ptr(mMainWindow);
+        mwd->screenshotItem()->releaseAndHide();
+        if (mViewSwitchFlags & Hb::ViewSwitchSequential) {
+            mwd->mClippingItem->show();
+        }
+    }
     // Start the "show" phase if not yet started.
     if (mViewSwitchFlags & Hb::ViewSwitchSequential) {
         // Do not show targetView yet, leave it to the effect in order to
@@ -190,19 +212,38 @@
     HbEffectInternal::cancelAll(0, true); // ignore looping effects, those are not view switch effects and must not be stopped here
     mViewSwitchRunning = true;
 
-    // Make the new view the current one right away. This must be done asap to prevent
-    // messed up state in mainwindow, the stack widget, etc. due to events coming during
-    // the view switch animation.
-    // 2nd param (hideOld): We still want to see the old view (normally setCurrentWidget would hide it).
-    // 3rd param (showNew): The new view is not yet needed (the effect will take care of making it visible).
-    setCurrentWidget(mTargetView, false, false);
+    bool hideOld = false;
+    if (flags & Hb::ViewSwitchCachedFullScreen) {
+        // Take a screenshot (must be done before touching anything in the view
+        // stack) and show it. The screenshot will effectively replace the
+        // hiding view.
+        HbMainWindowPrivate::d_ptr(mMainWindow)->screenshotItem()->takeAndShowScreenshot();
+        hideOld = true;
+    }
+
+    // Make the new view the current one right away. This must be done asap to
+    // prevent messed up state in mainwindow, the stack widget, etc. due to
+    // events coming during the view switch animation.
+    //
+    // 2nd param (hideOld): We still want to see the old view (normally
+    // setCurrentWidget would hide it), except in the cached case.
+    //
+    // 3rd param (showNew): The new view is not yet needed (the effect will take
+    // care of making it visible).
+    setCurrentWidget(mTargetView, hideOld, false);
 
     mHidingView = viewToHide;
     mViewSwitchFlags = flags;
 
-    QGraphicsWidget *effectTarget = getEffectTarget(viewToHide, flags);
+    QGraphicsWidget *effectTarget = getEffectTarget(viewToHide, (Hb::ViewSwitchFlags) (flags | Hiding));
     if (effectTarget) {
         mMainWindow->setInteractive(false); // disable input while the effects are running
+        if ((flags & Hb::ViewSwitchCachedFullScreen) && (flags & Hb::ViewSwitchSequential)) {
+            // Get rid of decorators for the duration of the hide effect
+            // otherwise they would show up under the screenshot item when
+            // it disappears.
+            HbMainWindowPrivate::d_ptr(mMainWindow)->mClippingItem->hide();
+        }
         QString event = getEffectEvent("hide", flags, viewToHide, mTargetView);
         HbEffectInternal::EffectFlags effectFlags =
             HbEffectInternal::ClearEffectWhenFinished // the effect must not be persistent