browser/ui/src/ARContainer.cpp
changeset 0 c316ab048e9d
equal deleted inserted replaced
-1:000000000000 0:c316ab048e9d
       
     1 /*
       
     2  * Name        : ARContainer.cpp
       
     3  * Description : 
       
     4  * Project     : This file is part of OpenMAR, an Open Mobile Augmented Reality browser
       
     5  * Website     : http://OpenMAR.org
       
     6  *
       
     7  * Copyright (c) 2010 David Caabeiro
       
     8  *
       
     9  * All rights reserved. This program and the accompanying materials are made available 
       
    10  * under the terms of the Eclipse Public License v1.0 which accompanies this 
       
    11  * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
       
    12  *
       
    13  */
       
    14 
       
    15 #include "ARContainer.h"
       
    16 
       
    17 #include <coemain.h>
       
    18 #include <eikenv.h>
       
    19 
       
    20 #include <AknButton.h>
       
    21 #include <AknNoteWrappers.h>
       
    22 #include <AknView.h>
       
    23 
       
    24 #include "Application.hrh"
       
    25 
       
    26 #include <OpenMAR_0x2002E1AB.rsg>
       
    27 #include <Button_0x2002E1AB.mbg>
       
    28 
       
    29 #include "IconLoader.h"
       
    30 #include "ResetAndDestroy.h"
       
    31 
       
    32 #include "Logger.h"
       
    33 
       
    34 // Constant definitions
       
    35 _LIT(KButtonFile, "\\resource\\apps\\Button_0x2002E1AB.mif");
       
    36 const TSize KButtonSize(36, 36);
       
    37 
       
    38 CARContainer* CARContainer::NewL(CAknView& aView, const TRect& aRect)
       
    39 {
       
    40     CARContainer* self = new(ELeave) CARContainer(aView);
       
    41     CleanupStack::PushL(self);
       
    42     self->ConstructL(aRect);
       
    43     CleanupStack::Pop(self);
       
    44 
       
    45     return self;
       
    46 }
       
    47 
       
    48 CARContainer::CARContainer(CAknView& aView)
       
    49     : iView(aView)
       
    50 {}
       
    51 
       
    52 void CARContainer::ConstructL(const TRect& aRect)
       
    53 {
       
    54     CreateWindowL();
       
    55 
       
    56     CreateButtonGroupL();
       
    57 
       
    58     // This bitmap will contain the camera frame and overlays
       
    59     iBitmap = new(ELeave) CFbsBitmap;
       
    60     iBitmap->Create(aRect.Size(), Window().DisplayMode());
       
    61 
       
    62     iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap);
       
    63     User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapContext));
       
    64 
       
    65     // Make black background to be shown immediately to the user 
       
    66     iBitmapContext->SetBrushColor(KRgbBlack);
       
    67     iBitmapContext->SetBrushStyle(CFbsBitGc::ESolidBrush);
       
    68     iBitmapContext->Clear();
       
    69 
       
    70     SetRect(aRect);
       
    71 
       
    72     LOGARG("Control rect size is %d x %d", aRect.Width(), aRect.Height());
       
    73 
       
    74     iCoeEnv->AddForegroundObserverL(*this);
       
    75 
       
    76 #if defined(__MARM__)
       
    77     iCamera = CDigitalCamera::NewL(*this);
       
    78 
       
    79     // The rect will be the intersection between the camera frame
       
    80     // and the window rect
       
    81     TRect cameraRect(TPoint(0, 0), iCamera->ViewportSize());
       
    82     cameraRect.Intersection(aRect);
       
    83 #else
       
    84     TRect cameraRect(aRect);
       
    85 #endif
       
    86 
       
    87     LOGARG("Viewport rect is (%d, %d, %d, %d)", 
       
    88             cameraRect.iTl.iX, cameraRect.iTl.iY, cameraRect.iBr.iX, cameraRect.iBr.iY);
       
    89 
       
    90     iScreenshot = CScreenshot::NewL(*this, cameraRect.Size(), Window().DisplayMode());
       
    91 
       
    92     // Instantiate overlay implementations
       
    93     RImplInfoPtrArray implementations;
       
    94     REComSession::ListImplementationsL(TUid::Uid(KOverlayInterfaceUidValue), implementations);
       
    95     CleanupResetAndDestroyPushL(implementations);
       
    96 
       
    97     // Pass container window and rect size to each overlay
       
    98     OpenMAR::CPOIOverlay::SParameter param = { Window(), cameraRect };
       
    99 
       
   100     for (TInt i = 0; i < implementations.Count(); ++i)
       
   101     {
       
   102         const CImplementationInformation* info = implementations[i];
       
   103         OpenMAR::CPOIOverlay* plugin = OpenMAR::CPOIOverlay::NewL(info->ImplementationUid(), param);
       
   104         iOverlayList.AppendL(plugin);
       
   105     }
       
   106 
       
   107     CleanupStack::PopAndDestroy(&implementations);
       
   108 
       
   109     // Start camera in low priority task
       
   110     iSensorTask = CIdle::NewL(CActive::EPriorityIdle);
       
   111 
       
   112     TCallBack sensorStart(SensorStart, this);
       
   113     iSensorTask->Start(sensorStart);
       
   114 
       
   115     ActivateL();
       
   116 }
       
   117 
       
   118 CARContainer::~CARContainer()
       
   119 {
       
   120     DoSensorStop();
       
   121 
       
   122     iOverlayList.ResetAndDestroy();
       
   123     iOverlayList.Close();
       
   124 
       
   125     delete iCamera;
       
   126     delete iScreenshot;
       
   127 
       
   128     iCoeEnv->RemoveForegroundObserver(*this);
       
   129 
       
   130     delete iBitmapContext;
       
   131     delete iBitmapDevice;
       
   132     delete iBitmap;
       
   133 
       
   134     DeleteButtonGroup();
       
   135 }
       
   136 
       
   137 void CARContainer::CreateButtonGroupL()
       
   138 {
       
   139     // Screenshot button
       
   140     CGulIcon* screenshotNormal = CreateIconL(KButtonFile, EMbmButton_0x2002e1abScreenshotbuttonnormal, EMbmButton_0x2002e1abScreenshotbuttonnormal_mask, KButtonSize);
       
   141 
       
   142     iScreenshotButton = CAknButton::NewL(screenshotNormal, 0, 0, 0, KNullDesC, KNullDesC, KAknButtonNoFrame, 0);
       
   143     iScreenshotButton->SetContainerWindowL(*this);
       
   144     iScreenshotButton->SetObserver(this);
       
   145 }
       
   146 
       
   147 void CARContainer::DeleteButtonGroup()
       
   148 {
       
   149     delete iScreenshotButton;
       
   150 }
       
   151 
       
   152 TInt CARContainer::SensorStart(TAny* aPtr)
       
   153 {
       
   154     CARContainer* self = static_cast<CARContainer*>(aPtr);
       
   155     self->DoSensorStart();
       
   156     return KErrNone;
       
   157 }
       
   158 
       
   159 void CARContainer::DoSensorStart()
       
   160 {
       
   161     LOGTXT("Starting sensors..");
       
   162 
       
   163 #if defined(__MARM__)
       
   164     iCamera->Start();
       
   165 #endif
       
   166 
       
   167     for (TInt i = 0; i < iOverlayList.Count(); ++i)
       
   168         iOverlayList[i]->StartL();
       
   169 }
       
   170 
       
   171 TInt CARContainer::SensorStop(TAny* aPtr)
       
   172 {
       
   173     CARContainer* self = static_cast<CARContainer*>(aPtr);
       
   174     self->DoSensorStop();
       
   175     return KErrNone;
       
   176 }
       
   177 
       
   178 void CARContainer::DoSensorStop()
       
   179 {
       
   180     LOGTXT("Stopping sensors..");
       
   181 
       
   182     for (TInt i = 0; i < iOverlayList.Count(); ++i)
       
   183         iOverlayList[i]->Stop();
       
   184 
       
   185 #if defined(__MARM__)
       
   186     iCamera->Stop();
       
   187 #endif
       
   188 }
       
   189 
       
   190 /*
       
   191  * Before performing the screenshot, disable overlay and sensor activity.
       
   192  * This way the screenshot image is generated fast.
       
   193  */  
       
   194 
       
   195 void CARContainer::ScreenshotStartL()
       
   196 {
       
   197     iScreenshotButton->SetDimmed(ETrue);
       
   198 
       
   199     HandleLosingForeground();
       
   200     iScreenshot->RequestL(*iBitmap, iBitmap->SizeInPixels());
       
   201 }
       
   202 
       
   203 /*
       
   204  * Resume overlay and sensor activity.
       
   205  */
       
   206 void CARContainer::ScreenshotStop()
       
   207 {
       
   208     HandleGainingForeground();
       
   209 
       
   210     iScreenshotButton->SetDimmed(EFalse);
       
   211 }
       
   212 
       
   213 void CARContainer::SizeChanged()
       
   214 {
       
   215     TRect screenshotButtonRect(TPoint(0, 0), KButtonSize);
       
   216     screenshotButtonRect.Move(TPoint(Rect().Width() - KButtonSize.iWidth, Rect().Height() - KButtonSize.iHeight));
       
   217 
       
   218     iScreenshotButton->SetRect(screenshotButtonRect);
       
   219 }
       
   220 
       
   221 void CARContainer::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   222 {
       
   223 //    if (aPointerEvent.iType == TPointerEvent::EButton1Down && iCamera)
       
   224 //        iCamera->StartFocus();
       
   225     CCoeControl::HandlePointerEventL(aPointerEvent);
       
   226 }
       
   227 
       
   228 void CARContainer::HandleResourceChange(TInt aType)
       
   229 {
       
   230     LOGARG("CARContainer::HandleResourceChange(%d)", aType);
       
   231 
       
   232     CCoeControl::HandleResourceChange(aType);
       
   233 /*
       
   234     if (aType == KEikDynamicLayoutVariantSwitch)
       
   235     {
       
   236         TRect rect;
       
   237         AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EApplicationWindow, rect);
       
   238         SetRect(rect);
       
   239     }
       
   240 */
       
   241 }
       
   242 
       
   243 void CARContainer::Draw(const TRect& /*aRect*/) const
       
   244 {
       
   245     CWindowGc& gc = SystemGc();
       
   246     gc.BitBlt(TPoint(0, 0), iBitmap);
       
   247 }
       
   248 
       
   249 TInt CARContainer::CountComponentControls() const
       
   250 {
       
   251     return ETotal;
       
   252 }
       
   253 
       
   254 CCoeControl* CARContainer::ComponentControl(TInt aIndex) const
       
   255 {
       
   256     switch (aIndex)
       
   257     {
       
   258         case EScreenshot:
       
   259             return iScreenshotButton;
       
   260 
       
   261         default:
       
   262             return 0;
       
   263     }
       
   264 }
       
   265 
       
   266 void CARContainer::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType)
       
   267 {
       
   268     if (aEventType == EEventStateChanged)
       
   269     {
       
   270         if (aControl == iScreenshotButton)
       
   271         {
       
   272             LOGTXT("Screenshot requested");
       
   273 
       
   274             ScreenshotStartL();
       
   275         }
       
   276     }
       
   277 }
       
   278 
       
   279 void CARContainer::HandleGainingForeground()
       
   280 {
       
   281     LOGTXT("Gaining ForegroundL");
       
   282 
       
   283     // Clear bitmap to avoid showing screen capture when back
       
   284     iBitmapContext->SetBrushColor(KRgbBlack);
       
   285     iBitmapContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   286     iBitmapContext->Clear();
       
   287 
       
   288     iSensorTask->Cancel();
       
   289     TCallBack sensor(SensorStart, this);
       
   290     iSensorTask->Start(sensor);
       
   291 }
       
   292 
       
   293 void CARContainer::HandleLosingForeground()
       
   294 {
       
   295     LOGTXT("Losing foreground");
       
   296 /*
       
   297     iSensorTask->Cancel();
       
   298     TCallBack sensor(SensorStop, this);
       
   299     iSensorTask->Start(sensor);
       
   300 */
       
   301     DoSensorStop();
       
   302 }
       
   303 
       
   304 void CARContainer::CameraReady(TInt aError)
       
   305 {
       
   306     LOGARG("Camera ready (error %d)", aError);
       
   307 
       
   308     // Perform some error handling
       
   309 }
       
   310 
       
   311 void CARContainer::CameraFrame(CFbsBitmap& aFrame)
       
   312 {
       
   313     // Use camera frame as background
       
   314     iBitmapContext->BitBlt(TPoint(0, 0), &aFrame);
       
   315 
       
   316     for (TInt i = 0; i < iOverlayList.Count(); ++i)
       
   317     {
       
   318         // Perform overlay rendering
       
   319         const CFbsBitmap& overlay = iOverlayList[i]->RenderScene();
       
   320         // Blend it with the background image
       
   321         iBitmapContext->BitBlt(TPoint(0, 0), &overlay);
       
   322     }
       
   323 
       
   324     const CFont* font = iEikonEnv->LegendFont();
       
   325     iBitmapContext->UseFont(font);
       
   326 
       
   327     _LIT(KText, "Focus: %d");
       
   328     TBuf<32> text;
       
   329     text.Format(KText, iOverlayList[0]->GetFocusedPOI());
       
   330 
       
   331     const TPoint pos(10, 20);
       
   332 
       
   333     iBitmapContext->DrawText(text, pos);
       
   334 
       
   335     // TODO: should call this every Nth frame
       
   336     User::ResetInactivityTime();
       
   337 
       
   338     DrawNow();
       
   339 }
       
   340 
       
   341 void CARContainer::FocusReady(TInt aError)
       
   342 {
       
   343     if (aError == KErrNone)
       
   344         LOGTXT("Focused correctly");
       
   345 //    else if (aError == KErrECamNotOptimalFocus)
       
   346 //        LOGTXT("Focus not optimal");
       
   347 }
       
   348 
       
   349 void CARContainer::ScreenshotReadyL(TInt aError, const TDesC& aFilename)
       
   350 {
       
   351     ScreenshotStop();
       
   352 
       
   353     TBuf<128> text;
       
   354 
       
   355     if (aError)
       
   356     {
       
   357         CAknErrorNote* note = new(ELeave) CAknErrorNote;
       
   358         HBufC* format = iEikonEnv->AllocReadResourceLC(R_SCREENSHOT_TEXT_ERROR);
       
   359         text.Format(*format, aError);
       
   360         CleanupStack::PopAndDestroy(format);
       
   361         note->ExecuteLD(text);
       
   362     }
       
   363     else
       
   364     {
       
   365         CAknInformationNote* note = new(ELeave) CAknInformationNote;
       
   366         HBufC* format = iEikonEnv->AllocReadResourceLC(R_SCREENSHOT_TEXT_OK);
       
   367         text.Format(*format, &aFilename);
       
   368         CleanupStack::PopAndDestroy(format);
       
   369         note->ExecuteLD(text);
       
   370     }
       
   371 }