/* * Copyright (c) 2009 Nokia Corporation. */ // INCLUDE FILES #include #include #include #include #include #include #include "ZXingBarcodeReaderAppView.h" #include "ZXingBarcodeReaderAppUi.h" // ============================ MEMBER FUNCTIONS =============================== CZXingBarcodeReaderAppView* CZXingBarcodeReaderAppView::NewL (const TRect& aRect ) { CZXingBarcodeReaderAppView* self = CZXingBarcodeReaderAppView::NewLC (aRect ); CleanupStack::Pop (self ); return self; } CZXingBarcodeReaderAppView* CZXingBarcodeReaderAppView::NewLC (const TRect& aRect ) { CZXingBarcodeReaderAppView* self = new (ELeave) CZXingBarcodeReaderAppView; CleanupStack::PushL (self ); self->ConstructL (aRect ); return self; } void CZXingBarcodeReaderAppView::ConstructL (const TRect& aRect ) { // Create a window for this application view CreateWindowL (); iTitleFont = AknLayoutUtils::FontFromId(EAknLogicalFontPrimarySmallFont); iAppUi = static_cast(iEikonEnv->EikAppUi()); // Set the windows size SetRect (aRect ); //Start decoder timer. StartTimer(); // Activate the window, which makes it ready to be drawn ActivateL (); } CZXingBarcodeReaderAppView::CZXingBarcodeReaderAppView () : iPeriodic(NULL) { } CZXingBarcodeReaderAppView::~CZXingBarcodeReaderAppView () { if (iCameraWrapper) { iCameraWrapper->ReleaseAndPowerOff(); } delete iCameraWrapper; delete iData; ReleaseBackBuffer(); } TKeyResponse CZXingBarcodeReaderAppView::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) { switch ( aKeyEvent.iCode ) { case EKeyOK: case EStdKeyDevice3: { // Capture picture iCameraShutterFocusing = EFalse; StartFocusing(); return EKeyWasConsumed; } case EKeyUpArrow: { if (iCameraWrapper->State() == CCameraEngine::EEngineViewFinding) { iCameraWrapper->AdjustDigitalZoom(ETrue); } return EKeyWasConsumed; } case EKeyDownArrow: { if (iCameraWrapper->State() == CCameraEngine::EEngineViewFinding) { iCameraWrapper->AdjustDigitalZoom(EFalse); } return EKeyWasConsumed; } default: { break; } }; #ifdef ENABLE_CAMERA_SHUTTER // Camera shutter autofocus switch ( aKeyEvent.iScanCode ) { case KStdKeyCameraFocus: case KStdKeyCameraFocus2: { // Camera shutter autofocus if (aType == EEventKeyDown) { if (!iAppUi->IsBackCBA()) { iCameraShutterFocusing = ETrue; StartFocusing(); } return EKeyWasConsumed; } else if (aType == EEventKeyUp) { // Camera state can be EEngineIdle or EEngineFocusing if (!iAppUi->IsBackCBA() && (iCameraWrapper->State() == CCameraEngine::EEngineFocusing || iCameraWrapper->State() == CCameraEngine::EEngineIdle)) { iCameraWrapper->FocusCancel(); CancelCapturedPicture(); iAppUi->UseOptionsExitCbaL(); } return EKeyWasConsumed; } } default: { break; } }; #endif return EKeyWasNotConsumed; } void CZXingBarcodeReaderAppView::CancelCapturedPicture(TBool aCleanTexts) { if (iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineIdle) { TRAPD(err,iCameraWrapper->StartViewFinderL(iViewFinderSize)); if (aCleanTexts) { if (err) { SetError(_L("Camera viewfinder error %d"), err); } else { SetTitle(_L("Camera viewfinder")); } } } } void CZXingBarcodeReaderAppView::Draw(const TRect& /*aRect*/) const { CWindowGc& gc = SystemGc (); // Draw backbuffer that has camera picture gc.BitBlt(TPoint(0, 0), iBackBuffer); // Draw texts DrawTexts(gc); // Focus rect if (iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineFocusing) { gc.SetPenColor(KRgbWhite); gc.DrawRect(iFocusRect); } } void CZXingBarcodeReaderAppView::DrawTexts(CWindowGc& gc) const { if (iTitle.Length()>0) { TRect rect(Rect()); gc.SetPenColor(KRgbWhite); gc.UseFont(iTitleFont); gc.DrawText(iTitle, rect, rect.Height()/10, CGraphicsContext::ECenter ); gc.DiscardFont(); } } void CZXingBarcodeReaderAppView::SizeChanged() { // Create camera wrapper class here because // whole camera wrapper and all handles have to reset // while orientatio of the application changes. if (iCameraWrapper) { // Power off camera if it is on iCameraWrapper->StopViewFinder(); iCameraWrapper->ReleaseAndPowerOff(); delete iCameraWrapper; iCameraWrapper = NULL; } TInt camErr(KErrNotSupported); if(CCameraEngine::CamerasAvailable() > 0) { TRAP(camErr, iCameraWrapper = CCameraEngine::NewL(0,0,this)); } // iViewFinderSize is picture size for viewfinder. // iCaptureSize is picture size for capturing picture. // We want fill whole screen if (Rect().Size().iWidth > Rect().Size().iHeight) { iViewFinderSize = TSize(Rect().Size().iWidth,Rect().Size().iWidth); iCaptureSize = TSize(1280,960); // Captured picture size } else { iViewFinderSize = TSize(Rect().Size().iHeight,Rect().Size().iHeight); iCaptureSize = TSize(1280,960); // Captured picture size } // Focus rectangle iFocusRect = Rect(); iFocusRect.Shrink(Rect().Size().iWidth/4, Rect().Size().iHeight/4); // Create back buffer where recieved camera pictures are copied ReleaseBackBuffer(); CreateBackBufferL(); // Power on camera, start viewfinder when MceoCameraReady() received if(camErr == KErrNone) { iCameraWrapper->ReserveAndPowerOn(); SetTitle(_L("Camera power on")); } else { SetTitle(_L("no camera found")); } } void CZXingBarcodeReaderAppView::HandlePointerEventL ( const TPointerEvent& aPointerEvent ) { if (aPointerEvent.iType == TPointerEvent::EButton1Down) { // When pointing to screen camera capture picture if (!iAppUi->IsBackCBA() && iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineViewFinding) { iCameraShutterFocusing = EFalse; StartFocusing(); } // After captureing, when pointing again to screen camera // start viewfinder again else if (!iAppUi->IsBackCBA() && iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineIdle) { CancelCapturedPicture(); iAppUi->UseOptionsExitCbaL(); } } } void CZXingBarcodeReaderAppView::SetTitle(const TDesC& aTitle) { iTitle.Copy(aTitle); DrawNow(); } void CZXingBarcodeReaderAppView::SetError( const TDesC& aMsg, TInt aVal ) { iTitle.Format(aMsg, aVal); DrawNow(); } void CZXingBarcodeReaderAppView::SetError( const TDesC& aMsg, TInt aVal1, TInt aVal2 ) { iTitle.Format(aMsg, aVal1, aVal2); DrawNow(); } void CZXingBarcodeReaderAppView::CreateBackBufferL() { // create back buffer bitmap iBackBuffer = new (ELeave) CFbsBitmap; User::LeaveIfError( iBackBuffer->Create(Size(),EColor16M)); // create back buffer graphics context iBackBufferDevice = CFbsBitmapDevice::NewL(iBackBuffer); User::LeaveIfError(iBackBufferDevice->CreateContext(iBackBufferContext)); iBackBufferContext->SetPenStyle(CGraphicsContext::ESolidPen); iBackBufferContext->SetBrushColor(KRgbBlack); iBackBufferContext->Clear(); } void CZXingBarcodeReaderAppView::ReleaseBackBuffer() { if (iBackBufferContext) { delete iBackBufferContext; iBackBufferContext = NULL; } if (iBackBufferDevice) { delete iBackBufferDevice; iBackBufferDevice = NULL; } if (iBackBuffer) { delete iBackBuffer; iBackBuffer = NULL; } } void CZXingBarcodeReaderAppView::MceoCameraReady() { iAppUi->UseOptionsExitCbaL(); if (iCameraWrapper->State() == CCameraEngine::EEngineIdle) { // Prepare camera TRAPD(err,iCameraWrapper->PrepareL(iCaptureSize)); if (err) { SetError(_L("Camera prepare error %d"), err); return; } // Start viewfinder. Viewfinder pictures starts coming into MceoViewFinderFrameReady(); TRAPD(err2,iCameraWrapper->StartViewFinderL(iViewFinderSize)); if (err2) { SetError(_L("Camera start viewfinder error %d"), err2); return; } SetTitle(_L("Camera viewfinder")); } } void CZXingBarcodeReaderAppView::Capture() { // This method is called when picture is focused with camera shutter and pressed whole down // as taking a new picture #ifdef ENABLE_CAMERA_SHUTTER if (iCameraWrapper && !iAppUi->IsBackCBA()) { // No focus supported SetTitle(_L("Capturing picture")); iCameraWrapper->StopViewFinder(); TRAPD(err,iCameraWrapper->CaptureL()); if (err) { SetError(_L("Camera capture error %d"), err); } } #endif } void CZXingBarcodeReaderAppView::StartFocusing() { if (iCameraWrapper && iCameraWrapper->State() == CCameraEngine::EEngineViewFinding) { if (!iCameraWrapper->IsAutoFocusSupported()) { // No focus supported SetTitle(_L("Capturing picture")); iCameraWrapper->StopViewFinder(); TRAPD(err,iCameraWrapper->CaptureL()); if (err) { SetError(_L("Camera capture error %d"), err); } } else { // Focusing supported iCameraWrapper->StartFocusL(); SetTitle(_L("Autofocusing...")); } } } void CZXingBarcodeReaderAppView::MceoFocusComplete() { // CameraEngine state is EEngineIdle SetTitle(_L("Focused")); if (iCameraShutterFocusing) { // Leave as focused. User must press whole camera shutter down for capturing // then CZXingBarcodeReaderAppView::Capture() is called } else { // Capture picture after it has focused iCameraWrapper->StopViewFinder(); TRAPD(err,iCameraWrapper->CaptureL()); if (err) { SetError(_L("Camera capture error %d"), err); } } } void CZXingBarcodeReaderAppView::MceoCapturedDataReady( TDesC8* aData ) { SetTitle(_L("Saving picture...")); delete iData; iData = NULL; iData = aData->Alloc(); if (iCameraWrapper) iCameraWrapper->ReleaseImageBuffer(); TRAP_IGNORE(iAppUi->UseOptionsBackCbaL()); StorePicture(iData); } void CZXingBarcodeReaderAppView::StorePicture( TDesC8* aData ) { // Create path for filename TFileName path = PathInfo::PhoneMemoryRootPath(); path.Append(PathInfo::ImagesPath()); // Ensure that path exists BaflUtils::EnsurePathExistsL(iEikonEnv->FsSession(),path); // Get next free filename for the image TFileName fileToSave; TBool fileExists = ETrue; for (TInt i=1 ; i<100 ; i++) { fileToSave.Copy(path); fileToSave.Append(_L("cw_image_")); fileToSave.AppendNum(i); fileToSave.Append(_L(".jpg")); fileExists = BaflUtils::FileExists(iEikonEnv->FsSession(),fileToSave); if (!fileExists) { break; } } // Save file if (!fileExists) { RFile file; TInt err = file.Create(iEikonEnv->FsSession(),fileToSave,EFileWrite); if (!err) { file.Write(*aData); file.Close(); SetTitle(fileToSave); } else { SetError(_L("File saving error %d"),err); } } else { SetTitle(_L("File not saved, delete old pictures!")); } } void CZXingBarcodeReaderAppView::MceoCapturedBitmapReady( CFbsBitmap* aBitmap ) { if (iBackBufferContext) { TSize bmpSizeInPixels = aBitmap->SizeInPixels(); TInt xDelta = (Rect().Width() - bmpSizeInPixels.iWidth) / 2; TInt yDelta = (Rect().Height() - bmpSizeInPixels.iHeight) / 2; TPoint pos( xDelta, yDelta ); // Copy received viewfinder picture to back buffer iBackBufferContext->BitBlt( pos, aBitmap, TRect( TPoint( 0, 0 ), bmpSizeInPixels )); // Update backbuffer into screen SetTitle(_L("New picture")); } if (iCameraWrapper) iCameraWrapper->ReleaseImageBuffer(); } void CZXingBarcodeReaderAppView::MceoViewFinderFrameReady( CFbsBitmap& aFrame ) { if (iBackBufferContext) { TSize bmpSizeInPixels = aFrame.SizeInPixels(); TInt xDelta = (Rect().Width() - bmpSizeInPixels.iWidth) / 2; TInt yDelta = (Rect().Height() - bmpSizeInPixels.iHeight) / 2; TPoint pos( xDelta, yDelta ); // Copy received viewfinder picture to back buffer iBackBufferContext->BitBlt( pos, &aFrame, TRect( TPoint( 0, 0 ), bmpSizeInPixels )); // Update backbuffer into screen DrawNow(); } if (iCameraWrapper) iCameraWrapper->ReleaseViewFinderBuffer(); } void CZXingBarcodeReaderAppView::MceoHandleError( TCameraEngineError aErrorType, TInt aError ) { // NOTE: CameraEngine state seems to go into CCameraEngine::EEngineIdle state if (aErrorType == EErrReserve) { return; //-18 comes on application startup, but everything works ok } switch (aErrorType) { case EErrReserve: { SetError(_L("Camera reserved error (%d)"), aError); break; } case EErrPowerOn: { SetError(_L("Camera power on error (%d)"), aError); break; } case EErrViewFinderReady: { SetError(_L("Camera viewfinder error (%d)"), aError); break; } case EErrImageReady: { SetError(_L("Camera image ready error (%d)"), aError); break; } case EErrAutoFocusInit: case EErrAutoFocusMode: case EErrAutoFocusArea: case EErrAutoFocusRange: case EErrAutoFocusType: case EErrOptimisedFocusComplete: { //SetTitle(_L("Try focusing again")); break; } default: { SetError(_L("Error %d (%d)"), aErrorType, aError); break; } }; // Try handle error CancelCapturedPicture(EFalse); iAppUi->UseOptionsExitCbaL(); } void CZXingBarcodeReaderAppView::MceoHandleOtherEvent( const TECAMEvent& /*aEvent*/ ) { } void CZXingBarcodeReaderAppView::StopTimer() { if(iPeriodic) iPeriodic->Cancel(); } // End of File