browser/ui/src/ARContainer.cpp
changeset 0 c316ab048e9d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/ui/src/ARContainer.cpp	Fri Jun 25 12:50:05 2010 +0200
@@ -0,0 +1,371 @@
+/*
+ * Name        : ARContainer.cpp
+ * Description : 
+ * Project     : This file is part of OpenMAR, an Open Mobile Augmented Reality browser
+ * Website     : http://OpenMAR.org
+ *
+ * Copyright (c) 2010 David Caabeiro
+ *
+ * All rights reserved. This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 which accompanies this 
+ * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+#include "ARContainer.h"
+
+#include <coemain.h>
+#include <eikenv.h>
+
+#include <AknButton.h>
+#include <AknNoteWrappers.h>
+#include <AknView.h>
+
+#include "Application.hrh"
+
+#include <OpenMAR_0x2002E1AB.rsg>
+#include <Button_0x2002E1AB.mbg>
+
+#include "IconLoader.h"
+#include "ResetAndDestroy.h"
+
+#include "Logger.h"
+
+// Constant definitions
+_LIT(KButtonFile, "\\resource\\apps\\Button_0x2002E1AB.mif");
+const TSize KButtonSize(36, 36);
+
+CARContainer* CARContainer::NewL(CAknView& aView, const TRect& aRect)
+{
+    CARContainer* self = new(ELeave) CARContainer(aView);
+    CleanupStack::PushL(self);
+    self->ConstructL(aRect);
+    CleanupStack::Pop(self);
+
+    return self;
+}
+
+CARContainer::CARContainer(CAknView& aView)
+    : iView(aView)
+{}
+
+void CARContainer::ConstructL(const TRect& aRect)
+{
+    CreateWindowL();
+
+    CreateButtonGroupL();
+
+    // This bitmap will contain the camera frame and overlays
+    iBitmap = new(ELeave) CFbsBitmap;
+    iBitmap->Create(aRect.Size(), Window().DisplayMode());
+
+    iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap);
+    User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapContext));
+
+    // Make black background to be shown immediately to the user 
+    iBitmapContext->SetBrushColor(KRgbBlack);
+    iBitmapContext->SetBrushStyle(CFbsBitGc::ESolidBrush);
+    iBitmapContext->Clear();
+
+    SetRect(aRect);
+
+    LOGARG("Control rect size is %d x %d", aRect.Width(), aRect.Height());
+
+    iCoeEnv->AddForegroundObserverL(*this);
+
+#if defined(__MARM__)
+    iCamera = CDigitalCamera::NewL(*this);
+
+    // The rect will be the intersection between the camera frame
+    // and the window rect
+    TRect cameraRect(TPoint(0, 0), iCamera->ViewportSize());
+    cameraRect.Intersection(aRect);
+#else
+    TRect cameraRect(aRect);
+#endif
+
+    LOGARG("Viewport rect is (%d, %d, %d, %d)", 
+            cameraRect.iTl.iX, cameraRect.iTl.iY, cameraRect.iBr.iX, cameraRect.iBr.iY);
+
+    iScreenshot = CScreenshot::NewL(*this, cameraRect.Size(), Window().DisplayMode());
+
+    // Instantiate overlay implementations
+    RImplInfoPtrArray implementations;
+    REComSession::ListImplementationsL(TUid::Uid(KOverlayInterfaceUidValue), implementations);
+    CleanupResetAndDestroyPushL(implementations);
+
+    // Pass container window and rect size to each overlay
+    OpenMAR::CPOIOverlay::SParameter param = { Window(), cameraRect };
+
+    for (TInt i = 0; i < implementations.Count(); ++i)
+    {
+        const CImplementationInformation* info = implementations[i];
+        OpenMAR::CPOIOverlay* plugin = OpenMAR::CPOIOverlay::NewL(info->ImplementationUid(), param);
+        iOverlayList.AppendL(plugin);
+    }
+
+    CleanupStack::PopAndDestroy(&implementations);
+
+    // Start camera in low priority task
+    iSensorTask = CIdle::NewL(CActive::EPriorityIdle);
+
+    TCallBack sensorStart(SensorStart, this);
+    iSensorTask->Start(sensorStart);
+
+    ActivateL();
+}
+
+CARContainer::~CARContainer()
+{
+    DoSensorStop();
+
+    iOverlayList.ResetAndDestroy();
+    iOverlayList.Close();
+
+    delete iCamera;
+    delete iScreenshot;
+
+    iCoeEnv->RemoveForegroundObserver(*this);
+
+    delete iBitmapContext;
+    delete iBitmapDevice;
+    delete iBitmap;
+
+    DeleteButtonGroup();
+}
+
+void CARContainer::CreateButtonGroupL()
+{
+    // Screenshot button
+    CGulIcon* screenshotNormal = CreateIconL(KButtonFile, EMbmButton_0x2002e1abScreenshotbuttonnormal, EMbmButton_0x2002e1abScreenshotbuttonnormal_mask, KButtonSize);
+
+    iScreenshotButton = CAknButton::NewL(screenshotNormal, 0, 0, 0, KNullDesC, KNullDesC, KAknButtonNoFrame, 0);
+    iScreenshotButton->SetContainerWindowL(*this);
+    iScreenshotButton->SetObserver(this);
+}
+
+void CARContainer::DeleteButtonGroup()
+{
+    delete iScreenshotButton;
+}
+
+TInt CARContainer::SensorStart(TAny* aPtr)
+{
+    CARContainer* self = static_cast<CARContainer*>(aPtr);
+    self->DoSensorStart();
+    return KErrNone;
+}
+
+void CARContainer::DoSensorStart()
+{
+    LOGTXT("Starting sensors..");
+
+#if defined(__MARM__)
+    iCamera->Start();
+#endif
+
+    for (TInt i = 0; i < iOverlayList.Count(); ++i)
+        iOverlayList[i]->StartL();
+}
+
+TInt CARContainer::SensorStop(TAny* aPtr)
+{
+    CARContainer* self = static_cast<CARContainer*>(aPtr);
+    self->DoSensorStop();
+    return KErrNone;
+}
+
+void CARContainer::DoSensorStop()
+{
+    LOGTXT("Stopping sensors..");
+
+    for (TInt i = 0; i < iOverlayList.Count(); ++i)
+        iOverlayList[i]->Stop();
+
+#if defined(__MARM__)
+    iCamera->Stop();
+#endif
+}
+
+/*
+ * Before performing the screenshot, disable overlay and sensor activity.
+ * This way the screenshot image is generated fast.
+ */  
+
+void CARContainer::ScreenshotStartL()
+{
+    iScreenshotButton->SetDimmed(ETrue);
+
+    HandleLosingForeground();
+    iScreenshot->RequestL(*iBitmap, iBitmap->SizeInPixels());
+}
+
+/*
+ * Resume overlay and sensor activity.
+ */
+void CARContainer::ScreenshotStop()
+{
+    HandleGainingForeground();
+
+    iScreenshotButton->SetDimmed(EFalse);
+}
+
+void CARContainer::SizeChanged()
+{
+    TRect screenshotButtonRect(TPoint(0, 0), KButtonSize);
+    screenshotButtonRect.Move(TPoint(Rect().Width() - KButtonSize.iWidth, Rect().Height() - KButtonSize.iHeight));
+
+    iScreenshotButton->SetRect(screenshotButtonRect);
+}
+
+void CARContainer::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+{
+//    if (aPointerEvent.iType == TPointerEvent::EButton1Down && iCamera)
+//        iCamera->StartFocus();
+    CCoeControl::HandlePointerEventL(aPointerEvent);
+}
+
+void CARContainer::HandleResourceChange(TInt aType)
+{
+    LOGARG("CARContainer::HandleResourceChange(%d)", aType);
+
+    CCoeControl::HandleResourceChange(aType);
+/*
+    if (aType == KEikDynamicLayoutVariantSwitch)
+    {
+        TRect rect;
+        AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EApplicationWindow, rect);
+        SetRect(rect);
+    }
+*/
+}
+
+void CARContainer::Draw(const TRect& /*aRect*/) const
+{
+    CWindowGc& gc = SystemGc();
+    gc.BitBlt(TPoint(0, 0), iBitmap);
+}
+
+TInt CARContainer::CountComponentControls() const
+{
+    return ETotal;
+}
+
+CCoeControl* CARContainer::ComponentControl(TInt aIndex) const
+{
+    switch (aIndex)
+    {
+        case EScreenshot:
+            return iScreenshotButton;
+
+        default:
+            return 0;
+    }
+}
+
+void CARContainer::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType)
+{
+    if (aEventType == EEventStateChanged)
+    {
+        if (aControl == iScreenshotButton)
+        {
+            LOGTXT("Screenshot requested");
+
+            ScreenshotStartL();
+        }
+    }
+}
+
+void CARContainer::HandleGainingForeground()
+{
+    LOGTXT("Gaining ForegroundL");
+
+    // Clear bitmap to avoid showing screen capture when back
+    iBitmapContext->SetBrushColor(KRgbBlack);
+    iBitmapContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
+    iBitmapContext->Clear();
+
+    iSensorTask->Cancel();
+    TCallBack sensor(SensorStart, this);
+    iSensorTask->Start(sensor);
+}
+
+void CARContainer::HandleLosingForeground()
+{
+    LOGTXT("Losing foreground");
+/*
+    iSensorTask->Cancel();
+    TCallBack sensor(SensorStop, this);
+    iSensorTask->Start(sensor);
+*/
+    DoSensorStop();
+}
+
+void CARContainer::CameraReady(TInt aError)
+{
+    LOGARG("Camera ready (error %d)", aError);
+
+    // Perform some error handling
+}
+
+void CARContainer::CameraFrame(CFbsBitmap& aFrame)
+{
+    // Use camera frame as background
+    iBitmapContext->BitBlt(TPoint(0, 0), &aFrame);
+
+    for (TInt i = 0; i < iOverlayList.Count(); ++i)
+    {
+        // Perform overlay rendering
+        const CFbsBitmap& overlay = iOverlayList[i]->RenderScene();
+        // Blend it with the background image
+        iBitmapContext->BitBlt(TPoint(0, 0), &overlay);
+    }
+
+    const CFont* font = iEikonEnv->LegendFont();
+    iBitmapContext->UseFont(font);
+
+    _LIT(KText, "Focus: %d");
+    TBuf<32> text;
+    text.Format(KText, iOverlayList[0]->GetFocusedPOI());
+
+    const TPoint pos(10, 20);
+
+    iBitmapContext->DrawText(text, pos);
+
+    // TODO: should call this every Nth frame
+    User::ResetInactivityTime();
+
+    DrawNow();
+}
+
+void CARContainer::FocusReady(TInt aError)
+{
+    if (aError == KErrNone)
+        LOGTXT("Focused correctly");
+//    else if (aError == KErrECamNotOptimalFocus)
+//        LOGTXT("Focus not optimal");
+}
+
+void CARContainer::ScreenshotReadyL(TInt aError, const TDesC& aFilename)
+{
+    ScreenshotStop();
+
+    TBuf<128> text;
+
+    if (aError)
+    {
+        CAknErrorNote* note = new(ELeave) CAknErrorNote;
+        HBufC* format = iEikonEnv->AllocReadResourceLC(R_SCREENSHOT_TEXT_ERROR);
+        text.Format(*format, aError);
+        CleanupStack::PopAndDestroy(format);
+        note->ExecuteLD(text);
+    }
+    else
+    {
+        CAknInformationNote* note = new(ELeave) CAknInformationNote;
+        HBufC* format = iEikonEnv->AllocReadResourceLC(R_SCREENSHOT_TEXT_OK);
+        text.Format(*format, &aFilename);
+        CleanupStack::PopAndDestroy(format);
+        note->ExecuteLD(text);
+    }
+}