--- /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);
+ }
+}